lottie-ios 3.2.3 → 3.4.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.github/actions/setup/action.yml +32 -0
- package/.github/issue_template.md +6 -23
- package/.github/workflows/main.yml +95 -0
- package/.spi.yml +6 -0
- package/.swiftpm/xcode/package.xcworkspace/contents.xcworkspacedata +7 -0
- package/.swiftpm/xcode/package.xcworkspace/xcuserdata/cal.xcuserdatad/UserInterfaceState.xcuserstate +0 -0
- package/.swiftpm/xcode/xcuserdata/{brandonwithrow.xcuserdatad → cal.xcuserdatad}/xcschemes/xcschememanagement.plist +25 -15
- package/.swiftpm/xcode/xcuserdata/calstephens.xcuserdatad/xcschemes/xcschememanagement.plist +14 -0
- package/Gemfile +4 -0
- package/Gemfile.lock +102 -0
- package/Lottie.xcodeproj/project.pbxproj +2005 -1974
- package/Lottie.xcodeproj/project.xcworkspace/contents.xcworkspacedata +1 -1
- package/Lottie.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved +23 -0
- package/Lottie.xcodeproj/project.xcworkspace/xcuserdata/cal.xcuserdatad/UserInterfaceState.xcuserstate +0 -0
- package/Lottie.xcodeproj/xcshareddata/xcschemes/{Lottie_iOS.xcscheme → Lottie (iOS).xcscheme } +15 -18
- package/Lottie.xcodeproj/xcshareddata/xcschemes/{Lottie_macOS.xcscheme → Lottie (macOS).xcscheme } +7 -20
- package/Lottie.xcodeproj/xcshareddata/xcschemes/{Lottie_tvOS.xcscheme → Lottie (tvOS).xcscheme } +5 -18
- package/Lottie.xcodeproj/xcuserdata/cal.xcuserdatad/xcschemes/xcschememanagement.plist +37 -0
- package/Lottie.xcodeproj/xcuserdata/calstephens.xcuserdatad/xcschemes/xcschememanagement.plist +24 -0
- package/Lottie.xcworkspace/contents.xcworkspacedata +10 -0
- package/Lottie.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist +8 -0
- package/Lottie.xcworkspace/xcshareddata/swiftpm/Package.resolved +34 -0
- package/Lottie.xcworkspace/xcuserdata/cal.xcuserdatad/UserInterfaceState.xcuserstate +0 -0
- package/{Lottie.xcodeproj/xcuserdata/brandonwithrow.xcuserdatad → Lottie.xcworkspace/xcuserdata/cal.xcuserdatad}/xcdebugger/Breakpoints_v2.xcbkptlist +2 -2
- package/Lottie.xcworkspace/xcuserdata/cal.xcuserdatad/xcdebugger/Expressions.xcexplist +153 -0
- package/Lottie.xcworkspace/xcuserdata/calstephens.xcuserdatad/UserInterfaceState.xcuserstate +0 -0
- package/Lottie.xcworkspace/xcuserdata/calstephens.xcuserdatad/xcdebugger/Breakpoints_v2.xcbkptlist +39 -0
- package/Lottie.xcworkspace/xcuserdata/calstephens.xcuserdatad/xcdebugger/Expressions.xcexplist +25 -0
- package/Mintfile +3 -0
- package/Package.swift +5 -15
- package/README.md +40 -59
- package/Rakefile +125 -0
- package/Sources/Private/CoreAnimation/Animations/CAAnimation+TimingConfiguration.swift +76 -0
- package/Sources/Private/CoreAnimation/Animations/CALayer+addAnimation.swift +322 -0
- package/Sources/Private/CoreAnimation/Animations/CombinedShapeAnimation.swift +53 -0
- package/Sources/Private/CoreAnimation/Animations/CustomPathAnimation.swift +41 -0
- package/Sources/Private/CoreAnimation/Animations/EllipseAnimation.swift +28 -0
- package/Sources/Private/CoreAnimation/Animations/GradientAnimations.swift +167 -0
- package/Sources/Private/CoreAnimation/Animations/LayerProperty.swift +229 -0
- package/Sources/Private/CoreAnimation/Animations/OpacityAnimation.swift +52 -0
- package/Sources/Private/CoreAnimation/Animations/RectangleAnimation.swift +31 -0
- package/Sources/Private/CoreAnimation/Animations/ShapeAnimation.swift +246 -0
- package/Sources/Private/CoreAnimation/Animations/StarAnimation.swift +95 -0
- package/Sources/Private/CoreAnimation/Animations/StrokeAnimation.swift +70 -0
- package/Sources/Private/CoreAnimation/Animations/TransformAnimations.swift +205 -0
- package/Sources/Private/CoreAnimation/Animations/VisibilityAnimation.swift +37 -0
- package/Sources/Private/CoreAnimation/CompatibilityTracker.swift +130 -0
- package/Sources/Private/CoreAnimation/CoreAnimationLayer.swift +492 -0
- package/Sources/Private/CoreAnimation/Extensions/CALayer+fillBounds.swift +35 -0
- package/Sources/Private/CoreAnimation/Extensions/KeyframeGroup+exactlyOneKeyframe.swift +37 -0
- package/Sources/Private/CoreAnimation/Extensions/Keyframes+combinedIfPossible.swift +61 -0
- package/Sources/Private/CoreAnimation/Layers/AnimationLayer.swift +77 -0
- package/Sources/Private/CoreAnimation/Layers/BaseAnimationLayer.swift +33 -0
- package/Sources/Private/CoreAnimation/Layers/BaseCompositionLayer.swift +87 -0
- package/Sources/Private/CoreAnimation/Layers/CALayer+setupLayerHierarchy.swift +131 -0
- package/Sources/Private/CoreAnimation/Layers/GradientRenderLayer.swift +87 -0
- package/Sources/Private/CoreAnimation/Layers/ImageLayer.swift +79 -0
- package/Sources/Private/CoreAnimation/Layers/LayerModel+makeAnimationLayer.swift +60 -0
- package/Sources/Private/CoreAnimation/Layers/MaskCompositionLayer.swift +138 -0
- package/Sources/Private/CoreAnimation/Layers/PreCompLayer.swift +140 -0
- package/Sources/Private/CoreAnimation/Layers/ShapeItemLayer.swift +259 -0
- package/Sources/Private/CoreAnimation/Layers/ShapeLayer.swift +305 -0
- package/Sources/Private/CoreAnimation/Layers/SolidLayer.swift +47 -0
- package/Sources/Private/CoreAnimation/Layers/TextLayer.swift +91 -0
- package/Sources/Private/CoreAnimation/Layers/TransformLayer.swift +11 -0
- package/Sources/Private/CoreAnimation/ValueProviderStore.swift +139 -0
- package/{lottie-swift/src/Private → Sources/Private/MainThread}/LayerContainers/CompLayers/CompositionLayer.swift +93 -85
- package/{lottie-swift/src/Private → Sources/Private/MainThread}/LayerContainers/CompLayers/ImageCompositionLayer.swift +24 -21
- package/{lottie-swift/src/Private → Sources/Private/MainThread}/LayerContainers/CompLayers/MaskContainerLayer.swift +77 -54
- package/{lottie-swift/src/Private → Sources/Private/MainThread}/LayerContainers/CompLayers/NullCompositionLayer.swift +5 -5
- package/{lottie-swift/src/Private → Sources/Private/MainThread}/LayerContainers/CompLayers/PreCompositionLayer.swift +57 -41
- package/{lottie-swift/src/Private → Sources/Private/MainThread}/LayerContainers/CompLayers/ShapeCompositionLayer.swift +22 -20
- package/{lottie-swift/src/Private → Sources/Private/MainThread}/LayerContainers/CompLayers/SolidCompositionLayer.swift +26 -17
- package/{lottie-swift/src/Private → Sources/Private/MainThread}/LayerContainers/CompLayers/TextCompositionLayer.swift +42 -36
- package/{lottie-swift/src/Private/LayerContainers/AnimationContainer.swift → Sources/Private/MainThread/LayerContainers/MainThreadAnimationLayer.swift} +201 -140
- package/Sources/Private/MainThread/LayerContainers/Utility/CachedImageProvider.swift +47 -0
- package/{lottie-swift/src/Private → Sources/Private/MainThread}/LayerContainers/Utility/CompositionLayersInitializer.swift +33 -24
- package/{lottie-swift/src/Private/LayerContainers/Utility/TextLayer.swift → Sources/Private/MainThread/LayerContainers/Utility/CoreTextRenderLayer.swift} +119 -105
- package/{lottie-swift/src/Private → Sources/Private/MainThread}/LayerContainers/Utility/InvertedMatteLayer.swift +25 -24
- package/Sources/Private/MainThread/LayerContainers/Utility/LayerFontProvider.swift +41 -0
- package/{lottie-swift/src/Private → Sources/Private/MainThread}/LayerContainers/Utility/LayerImageProvider.swift +20 -16
- package/Sources/Private/MainThread/LayerContainers/Utility/LayerTextProvider.swift +40 -0
- package/{lottie-swift/src/Private → Sources/Private/MainThread}/LayerContainers/Utility/LayerTransformNode.swift +83 -67
- package/{lottie-swift/src/Private → Sources/Private/MainThread}/NodeRenderSystem/Extensions/ItemsExtension.swift +6 -4
- package/{lottie-swift/src/Private → Sources/Private/MainThread}/NodeRenderSystem/NodeProperties/NodeProperty.swift +29 -21
- package/{lottie-swift/src/Private → Sources/Private/MainThread}/NodeRenderSystem/NodeProperties/Protocols/AnyNodeProperty.swift +16 -10
- package/{lottie-swift/src/Private → Sources/Private/MainThread}/NodeRenderSystem/NodeProperties/Protocols/AnyValueContainer.swift +6 -6
- package/{lottie-swift/src/Private → Sources/Private/MainThread}/NodeRenderSystem/NodeProperties/Protocols/KeypathSearchable.swift +5 -5
- package/{lottie-swift/src/Private → Sources/Private/MainThread}/NodeRenderSystem/NodeProperties/Protocols/NodePropertyMap.swift +10 -8
- package/{lottie-swift/src/Private → Sources/Private/MainThread}/NodeRenderSystem/NodeProperties/ValueContainer.swift +25 -21
- package/{lottie-swift/src/Private → Sources/Private/MainThread}/NodeRenderSystem/NodeProperties/ValueProviders/GroupInterpolator.swift +23 -17
- package/{lottie-swift/src/Private → Sources/Private/MainThread}/NodeRenderSystem/NodeProperties/ValueProviders/KeyframeInterpolator.swift +128 -108
- package/{lottie-swift/src/Private → Sources/Private/MainThread}/NodeRenderSystem/NodeProperties/ValueProviders/SingleValueProvider.swift +22 -17
- package/{lottie-swift/src/Private → Sources/Private/MainThread}/NodeRenderSystem/Nodes/ModifierNodes/TrimPathNode.swift +113 -79
- package/{lottie-swift/src/Private → Sources/Private/MainThread}/NodeRenderSystem/Nodes/OutputNodes/GroupOutputNode.swift +22 -16
- package/{lottie-swift/src/Private → Sources/Private/MainThread}/NodeRenderSystem/Nodes/OutputNodes/PassThroughOutputNode.swift +19 -15
- package/{lottie-swift/src/Private → Sources/Private/MainThread}/NodeRenderSystem/Nodes/OutputNodes/PathOutputNode.swift +22 -20
- package/{lottie-swift/src/Private → Sources/Private/MainThread}/NodeRenderSystem/Nodes/OutputNodes/Renderables/FillRenderer.swift +22 -23
- package/Sources/Private/MainThread/NodeRenderSystem/Nodes/OutputNodes/Renderables/GradientFillRenderer.swift +242 -0
- package/{lottie-swift/src/Private → Sources/Private/MainThread}/NodeRenderSystem/Nodes/OutputNodes/Renderables/GradientStrokeRenderer.swift +29 -22
- package/{lottie-swift/src/Private/NodeRenderSystem/Nodes/OutputNodes/Renderables/GradientFillRenderer.swift → Sources/Private/MainThread/NodeRenderSystem/Nodes/OutputNodes/Renderables/LegacyGradientFillRenderer.swift} +92 -65
- package/{lottie-swift/src/Private → Sources/Private/MainThread}/NodeRenderSystem/Nodes/OutputNodes/Renderables/StrokeRenderer.swift +22 -18
- package/Sources/Private/MainThread/NodeRenderSystem/Nodes/PathNodes/EllipseNode.swift +139 -0
- package/Sources/Private/MainThread/NodeRenderSystem/Nodes/PathNodes/PolygonNode.swift +170 -0
- package/{lottie-swift/src/Private → Sources/Private/MainThread}/NodeRenderSystem/Nodes/PathNodes/RectNode.swift +94 -57
- package/{lottie-swift/src/Private → Sources/Private/MainThread}/NodeRenderSystem/Nodes/PathNodes/ShapeNode.swift +42 -29
- package/{lottie-swift/src/Private → Sources/Private/MainThread}/NodeRenderSystem/Nodes/PathNodes/StarNode.swift +105 -66
- package/Sources/Private/MainThread/NodeRenderSystem/Nodes/RenderContainers/GroupNode.swift +155 -0
- package/{lottie-swift/src/Private → Sources/Private/MainThread}/NodeRenderSystem/Nodes/RenderNodes/FillNode.swift +51 -37
- package/{lottie-swift/src/Private → Sources/Private/MainThread}/NodeRenderSystem/Nodes/RenderNodes/GradientFillNode.swift +54 -42
- package/{lottie-swift/src/Private → Sources/Private/MainThread}/NodeRenderSystem/Nodes/RenderNodes/GradientStrokeNode.swift +65 -57
- package/{lottie-swift/src/Private → Sources/Private/MainThread}/NodeRenderSystem/Nodes/RenderNodes/StrokeNode.swift +84 -58
- package/{lottie-swift/src/Private → Sources/Private/MainThread}/NodeRenderSystem/Nodes/Text/TextAnimatorNode.swift +138 -119
- package/{lottie-swift/src/Private → Sources/Private/MainThread}/NodeRenderSystem/Protocols/AnimatorNode.swift +80 -79
- package/{lottie-swift/src/Private → Sources/Private/MainThread}/NodeRenderSystem/Protocols/PathNode.swift +5 -3
- package/{lottie-swift/src/Private → Sources/Private/MainThread}/NodeRenderSystem/Protocols/RenderNode.swift +22 -17
- package/{lottie-swift/src/Private → Sources/Private/MainThread}/NodeRenderSystem/RenderLayers/ShapeContainerLayer.swift +26 -23
- package/{lottie-swift/src/Private → Sources/Private/MainThread}/NodeRenderSystem/RenderLayers/ShapeRenderLayer.swift +35 -25
- package/Sources/Private/Model/Animation.swift +160 -0
- package/Sources/Private/Model/Assets/Asset.swift +43 -0
- package/{lottie-swift/src → Sources}/Private/Model/Assets/AssetLibrary.swift +40 -13
- package/Sources/Private/Model/Assets/ImageAsset.swift +112 -0
- package/{lottie-swift/src → Sources}/Private/Model/Assets/PrecompAsset.swift +20 -10
- package/Sources/Private/Model/DictionaryInitializable.swift +67 -0
- package/Sources/Private/Model/Extensions/Bundle.swift +34 -0
- package/{lottie-swift/src → Sources}/Private/Model/Extensions/KeyedDecodingContainerExtensions.swift +8 -4
- package/Sources/Private/Model/Keyframes/KeyframeData.swift +113 -0
- package/Sources/Private/Model/Keyframes/KeyframeGroup.swift +197 -0
- package/{lottie-swift/src → Sources}/Private/Model/Layers/ImageLayerModel.swift +21 -11
- package/Sources/Private/Model/Layers/LayerModel.swift +228 -0
- package/{lottie-swift/src → Sources}/Private/Model/Layers/PreCompLayerModel.swift +39 -22
- package/{lottie-swift/src → Sources}/Private/Model/Layers/ShapeLayerModel.swift +23 -12
- package/{lottie-swift/src → Sources}/Private/Model/Layers/SolidLayerModel.swift +31 -19
- package/{lottie-swift/src → Sources}/Private/Model/Layers/TextLayerModel.swift +33 -19
- package/Sources/Private/Model/Objects/DashPattern.swift +44 -0
- package/Sources/Private/Model/Objects/Marker.swift +33 -0
- package/Sources/Private/Model/Objects/Mask.swift +80 -0
- package/Sources/Private/Model/Objects/Transform.swift +179 -0
- package/Sources/Private/Model/ShapeItems/Ellipse.swift +75 -0
- package/Sources/Private/Model/ShapeItems/Fill.swift +74 -0
- package/Sources/Private/Model/ShapeItems/GradientFill.swift +124 -0
- package/Sources/Private/Model/ShapeItems/GradientStroke.swift +186 -0
- package/{lottie-swift/src → Sources}/Private/Model/ShapeItems/Group.swift +21 -10
- package/{lottie-swift/src → Sources}/Private/Model/ShapeItems/Merge.swift +29 -11
- package/Sources/Private/Model/ShapeItems/Rectangle.swift +73 -0
- package/Sources/Private/Model/ShapeItems/Repeater.swift +136 -0
- package/Sources/Private/Model/ShapeItems/Shape.swift +56 -0
- package/Sources/Private/Model/ShapeItems/ShapeItem.swift +163 -0
- package/Sources/Private/Model/ShapeItems/ShapeTransform.swift +136 -0
- package/Sources/Private/Model/ShapeItems/Star.swift +132 -0
- package/Sources/Private/Model/ShapeItems/Stroke.swift +102 -0
- package/Sources/Private/Model/ShapeItems/Trim.swift +78 -0
- package/Sources/Private/Model/Text/Font.swift +61 -0
- package/{lottie-swift/src → Sources}/Private/Model/Text/Glyph.swift +63 -39
- package/Sources/Private/Model/Text/TextAnimator.swift +165 -0
- package/Sources/Private/Model/Text/TextDocument.swift +123 -0
- package/Sources/Private/RootAnimationLayer.swift +51 -0
- package/{lottie-swift/src → Sources}/Private/Utility/Debugging/AnimatorNodeDebugging.swift +7 -7
- package/{lottie-swift/src → Sources}/Private/Utility/Debugging/LayerDebugging.swift +72 -47
- package/Sources/Private/Utility/Debugging/TestHelpers.swift +10 -0
- package/{lottie-swift/src → Sources}/Private/Utility/Extensions/AnimationKeypathExtension.swift +69 -59
- package/Sources/Private/Utility/Extensions/BlendMode+Filter.swift +31 -0
- package/Sources/Private/Utility/Extensions/CGColor+RGB.swift +22 -0
- package/{lottie-swift/src → Sources}/Private/Utility/Extensions/CGFloatExtensions.swift +70 -67
- package/Sources/Private/Utility/Extensions/DataExtension.swift +27 -0
- package/Sources/Private/Utility/Extensions/MathKit.swift +451 -0
- package/Sources/Private/Utility/Extensions/StringExtensions.swift +39 -0
- package/{lottie-swift/src → Sources}/Private/Utility/Helpers/AnimationContext.swift +42 -16
- package/Sources/Private/Utility/Interpolatable/InterpolatableExtensions.swift +135 -0
- package/{lottie-swift/src → Sources}/Private/Utility/Interpolatable/KeyframeExtensions.swift +13 -10
- package/Sources/Private/Utility/Interpolatable/KeyframeGroup+Extensions.swift +59 -0
- package/{lottie-swift/src → Sources}/Private/Utility/Primitives/BezierPath.swift +229 -142
- package/Sources/Private/Utility/Primitives/CGPointExtension.swift +35 -0
- package/{lottie-swift/src → Sources}/Private/Utility/Primitives/ColorExtension.swift +46 -14
- package/{lottie-swift/src → Sources}/Private/Utility/Primitives/CompoundBezierPath.swift +58 -49
- package/Sources/Private/Utility/Primitives/CurveVertex.swift +186 -0
- package/Sources/Private/Utility/Primitives/PathElement.swift +75 -0
- package/Sources/Private/Utility/Primitives/UnitBezier.swift +115 -0
- package/Sources/Private/Utility/Primitives/VectorsExtensions.swift +341 -0
- package/Sources/Public/Animation/AnimationPublic.swift +269 -0
- package/Sources/Public/Animation/AnimationView.swift +1315 -0
- package/Sources/Public/Animation/AnimationViewInitializers.swift +107 -0
- package/Sources/Public/AnimationCache/AnimationCacheProvider.swift +22 -0
- package/{lottie-swift/src → Sources}/Public/AnimationCache/LRUAnimationCache.swift +22 -18
- package/Sources/Public/DynamicProperties/AnimationKeypath.swift +49 -0
- package/Sources/Public/DynamicProperties/AnyValueProvider.swift +132 -0
- package/{lottie-swift/src → Sources}/Public/DynamicProperties/ValueProviders/ColorValueProvider.swift +54 -36
- package/{lottie-swift/src → Sources}/Public/DynamicProperties/ValueProviders/FloatValueProvider.swift +40 -36
- package/Sources/Public/DynamicProperties/ValueProviders/GradientValueProvider.swift +125 -0
- package/{lottie-swift/src → Sources}/Public/DynamicProperties/ValueProviders/PointValueProvider.swift +40 -35
- package/{lottie-swift/src → Sources}/Public/DynamicProperties/ValueProviders/SizeValueProvider.swift +40 -35
- package/{lottie-swift/src → Sources}/Public/FontProvider/AnimationFontProvider.swift +15 -8
- package/Sources/Public/ImageProvider/AnimationImageProvider.swift +21 -0
- package/Sources/Public/Keyframes/Interpolatable.swift +253 -0
- package/Sources/Public/Keyframes/Keyframe.swift +92 -0
- package/Sources/Public/Logging/LottieLogger.swift +124 -0
- package/Sources/Public/LottieConfiguration.swift +143 -0
- package/{lottie-swift/src → Sources}/Public/Primitives/AnimationTime.swift +1 -1
- package/{lottie-swift/src → Sources}/Public/Primitives/Color.swift +10 -6
- package/{lottie-swift/src → Sources}/Public/Primitives/Vectors.swift +13 -12
- package/Sources/Public/TextProvider/AnimationTextProvider.swift +53 -0
- package/{lottie-swift/src → Sources}/Public/iOS/AnimatedButton.swift +36 -26
- package/{lottie-swift/src → Sources}/Public/iOS/AnimatedControl.swift +102 -91
- package/{lottie-swift/src → Sources}/Public/iOS/AnimatedSwitch.swift +123 -92
- package/{lottie-swift/src → Sources}/Public/iOS/AnimationSubview.swift +3 -3
- package/Sources/Public/iOS/AnimationViewBase.swift +78 -0
- package/{lottie-swift/src → Sources}/Public/iOS/BundleImageProvider.swift +37 -34
- package/{lottie-swift/src → Sources}/Public/iOS/Compatibility/CompatibleAnimationKeypath.swift +4 -0
- package/{lottie-swift/src → Sources}/Public/iOS/Compatibility/CompatibleAnimationView.swift +38 -29
- package/{lottie-swift/src → Sources}/Public/iOS/FilepathImageProvider.swift +24 -20
- package/{lottie-swift/src → Sources}/Public/iOS/UIColorExtension.swift +4 -4
- package/{lottie-swift/src/Public/MacOS/AnimationSubview.swift → Sources/Public/macOS/AnimationSubview.macOS.swift} +4 -5
- package/{lottie-swift/src/Public/MacOS/LottieView.swift → Sources/Public/macOS/AnimationViewBase.macOS.swift} +58 -50
- package/{lottie-swift/src/Public/MacOS/BundleImageProvider.swift → Sources/Public/macOS/BundleImageProvider.macOS.swift} +32 -32
- package/Sources/Public/macOS/FilepathImageProvider.macOS.swift +69 -0
- package/Tests/AnimationKeypathTests.swift +94 -0
- package/Tests/Artifacts/LottieTests.xcresult/Data/data.0~-7Vi1RszY1XYnR2CCkEwIpKG8NwwA9zsZEz_WD7Dv6kKh4RC7N7ob8NIRVHGUJKp7eXxlpeI_gzD87Pcs_2u0g== +0 -0
- package/Tests/Artifacts/LottieTests.xcresult/Data/data.0~-SKV2drO-SFlrlh-wrzECDMkUSr-aF1lV9h-5onOy94zSTsD-oI45s0-KpOK45L-kq3hRY7v9vm-xmh00_eheg== +0 -0
- package/Tests/Artifacts/LottieTests.xcresult/Data/data.0~-_CU_vuaiFfObSeDFfmp7GuB20ThMSAL-P_RUMowiQLbdu-y0bU9upIm3q8g6XmXUG5hP6J1az0Ma5Hi_rhhRg== +0 -0
- package/Tests/Artifacts/LottieTests.xcresult/Data/data.0~03aPYP6VHJjZj5DlphGarj0xdw43qu09Onx5SReZoPvg9zh5uL212E-KWfGct9jf6JG0JFV2tdbBi7X_8bH9aw== +0 -0
- package/Tests/Artifacts/LottieTests.xcresult/Data/data.0~1Z82GPBBPc1VLvn4O7V5glb6lgyXteNlDREUzV_TPymM4ra4UkBMklzV90lEqoYRCDuRVzaQHaDYbmYp3-8CFw== +0 -0
- package/Tests/Artifacts/LottieTests.xcresult/Data/data.0~1mFDCboXpUu9pSHAiVGr1O_QgqEEtvJp_LUhickxLZo0Z5pj3fvadn1l2MzEOd4bFsVBZifUvcyPa7dzlMWF-A== +0 -0
- package/Tests/Artifacts/LottieTests.xcresult/Data/data.0~2_L9PUjv2JDKu1n8bDLb4XLB-yex6ZVjDDMwfuKAr7teDw-SKgLgkW6H-m_gjWChIVdB4vW6yvHP7XJxvXtRNA== +0 -0
- package/Tests/Artifacts/LottieTests.xcresult/Data/data.0~4VqMqsI5lOfxRppnud6-VDWcNsU8J7VgFCJfW2dXPwOcAkvU-I8Um5yp9n0Zv6nr3VmcxYggaVMDFfR0U_vjKw== +1 -0
- package/Tests/Artifacts/LottieTests.xcresult/Data/data.0~4krT4ZMzDOu34msFUq0Xod142kw4pAeSWX4JSxlsjOI0Wanu3343qeespgFi61MTWq1DdH9XXspVKqGlGm_fyw== +0 -0
- package/Tests/Artifacts/LottieTests.xcresult/Data/data.0~5_aJsdP-e3dRTAUnH-y1U2plaCuUi1vyHriaZuNK0xFe8wGl9Qft6uLCX2Qt6CRBKJQluEe9o0uRWw1eb42FHQ== +0 -0
- package/Tests/Artifacts/LottieTests.xcresult/Data/data.0~8b0bSqV7eND54zvHvu1v2Htpm7yn-BOEFw5d3mITJrXWNykJ5BTR9WbrD80JEctNcT-rDqO2xfrQk1tFWeY6Sw== +0 -0
- package/Tests/Artifacts/LottieTests.xcresult/Data/data.0~9u8KAGpgtSm-mQ12Py8RZUbYbDlBhM3w1I2MQO53K2CSn6IePp7g65DBcdXTYMfG1bgoJ-6x30fjnGe-2UYsDQ== +0 -0
- package/Tests/Artifacts/LottieTests.xcresult/Data/data.0~Bw7uMs4wqB9ahfEqGii2FkQ9pvZmG6HGe2hmbAT2wyM5hpn8Xh5dELysMcEz6hEsqmn6HdRdLOLZhC_fNaXzgA== +0 -0
- package/Tests/Artifacts/LottieTests.xcresult/Data/data.0~BwUq2xXQYuE8ya6HT6lfNsdtEjz5AKGf8GvLY6VBxQyIY1vgj_Gov-3NeM69OS66BQRDK0PG9H4Oyg0R48E4vg== +0 -0
- package/Tests/Artifacts/LottieTests.xcresult/Data/data.0~EkDVUR6dcnzxV_lYjkrJ5QGMVTCvb_upAoBF6DBu61sQkGvZN3fSRTsJ1XfJIZO-JUzdNoVA3D_CcvokL0gnQg== +0 -0
- package/Tests/Artifacts/LottieTests.xcresult/Data/data.0~FUkcLSJ8RAuPenM4HFG1R-sN5-cDBGcTxgR2jaVCna7xV0ZTyBHriB1Nn59mariNlJDiCoBtMUQEmauGxWtfBA== +0 -0
- package/Tests/Artifacts/LottieTests.xcresult/Data/data.0~FqsuZe4RVLOOVUYLTL-GTIohZ8TdSfxx7m2KJtLYFPGOdE4XorTX7Oc7kXbhghPRppXT3jW-slI37M34YNEvLQ== +0 -0
- package/Tests/Artifacts/LottieTests.xcresult/Data/data.0~G4F_NtyTj3i46fmKm0NorHAeq8tYWWYf6uv5yC1DwzdpWVoYbOPufmFNvdEbxZt4AMdV0gKx3HI46EAXNOQVFg== +0 -0
- package/Tests/Artifacts/LottieTests.xcresult/Data/data.0~GxetzGUNDgaBBXcTmLK6p9JBDX3I3QPshshbui1IaEWvJbQko-E36tCKwaJYHbleAWz9FqkAM_Tqx3YOmSVkVg== +0 -0
- package/Tests/Artifacts/LottieTests.xcresult/Data/data.0~H1Wjd5kKWDW4t3SDodxiHV72V8WT0xwPubw5cJTNLkPRLgaILFPh-dpy8EOUNgy1KzrDujFsm9EcTsbuqtMPLA== +0 -0
- package/Tests/Artifacts/LottieTests.xcresult/Data/data.0~JpI5MH4zCgebUHFpXVn4zjtsGtMNnO7BQZWfNARAB5UWa9gqz6YXHR3uLCJ_AvJ3lh53BUVkavsx9TY2FMmxbA== +0 -0
- package/Tests/Artifacts/LottieTests.xcresult/Data/data.0~JujNYkJtcux0Ni4QnR64zu4Wz_zYjyKvYaYZm5ypxTLPSzF3_jNE_NO4sdbDamF8wEqWoky1uf4ZE0JT3L607A== +0 -0
- package/Tests/Artifacts/LottieTests.xcresult/Data/data.0~KJSEA6DKnb2_FRPSqKZGh41eo-C8x448J9kEBrH012bUrZfOSDvrgmIrU0Vz7Ri3gaS9aKKmSaVMvXsHSlTJVA== +0 -0
- package/Tests/Artifacts/LottieTests.xcresult/Data/data.0~MStOwu3jBlJtcRnxrseVOuhI4kCj--ggFPG7sqrq5w1hjrI3bVyD-bm1Jwyx0noY3wT1rHDEvaGWnV2qsGjGwg== +0 -0
- package/Tests/Artifacts/LottieTests.xcresult/Data/data.0~McsJ8kFVf3IjhgXIRdw8Xx-EXgbV071bmlj2BBnk52xrWl3sEeiIyxwUsF7mIWvMRWfcFfu4VGHYyqfk2BeHXw== +0 -0
- package/Tests/Artifacts/LottieTests.xcresult/Data/data.0~NHt9fVe4kDdbxnglKcEwXaRK-WsYEOaD23Kbl8SJPRMYHr_Z6SJd_HmG3BROHHR_M6TgSmucONpDJdTj5tjuFw== +0 -0
- package/Tests/Artifacts/LottieTests.xcresult/Data/data.0~Nfo2iwCPcfAcOBIVyoUAK0-PIfr5qYxIKZt-uaSaTBdrTNxAuJ1ItmeDPZ3VdJJmxD_c22No7x482bdd3_yYtw== +0 -0
- package/Tests/Artifacts/LottieTests.xcresult/Data/data.0~S2Qlu11xBhEd5aGSzWsnw1TR8u8PiOF93GO0j5bfNoAFCVzxKOwhRFoIXba2EpQnLQqFdIKyhWN3l70A4GPHmg== +0 -0
- package/Tests/Artifacts/LottieTests.xcresult/Data/data.0~W7a7M37RO9jgck2zeR0471Pm7e8K0Kqj5tXEouDjvqKZXSrWxMaWD28oqkKKYAiU4608R4S9mM11KyphljdMSw== +0 -0
- package/Tests/Artifacts/LottieTests.xcresult/Data/data.0~XUo1oyPCrlL7CA74wG-OzQ06VOWJYWvHGFHU7keZN1SKaIXjHX5qi_kBzjG_rBCi89-S8GVmCy7S3PHSjG8SbQ== +0 -0
- package/Tests/Artifacts/LottieTests.xcresult/Data/data.0~Xh0VmDvFNMELHu08-vrs54pegVyUwwDRxx_nXkwyD0NjnYozyqcGAKAr_QWHmw6F8XyuWg51M9KGpJJIFzzGuw== +0 -0
- package/Tests/Artifacts/LottieTests.xcresult/Data/data.0~Xve-wMBp_lxVUgD9qH5GwieGP9cAWtm0xULZvdGjBRUMvaevmpCB5gnbMBuIXAO6a1c9v6WUq0jNVX7ut5HvOw== +0 -0
- package/Tests/Artifacts/LottieTests.xcresult/Data/data.0~ZU1XkZFgnEE22CXEF-pOlcj5f10x-KM1Vw9d4IOLu-NiTZcz7koYPixhdrB1PJr8J-h9NpJmfqEastfxamA1jQ== +0 -0
- package/Tests/Artifacts/LottieTests.xcresult/Data/data.0~_YkNYEHTsbbtFILJpzH3HenH0t4ShI25dIMdve541CF5bl-jPF3X3F7tq-t5dvP0TEkATsOJdLQdBp1xv4Q-ag== +0 -0
- package/Tests/Artifacts/LottieTests.xcresult/Data/data.0~boy6mpn2jkwm60jjgQ0TG25UqRdN46LzmgTVCrpy6nBOgkLCGkGHcbceiwjU1itS_vj3-iQX0ZnrWOQrPyfHNA== +0 -0
- package/Tests/Artifacts/LottieTests.xcresult/Data/data.0~bwzpVZ9hAqGDHhXs2FRA82dfGfLmc7-m0uQhZDDfHHO7hQ17M_Np341BZX4WDLhYYS4cdUgaDodlNpdfpG3nXw== +0 -0
- package/Tests/Artifacts/LottieTests.xcresult/Data/data.0~cBxe-9PpAGFdAsYkmdN3lJVqEliLcRYlyoAov0aPZfJGwUr_cOm3XpjO7nmf_2eLf8UAx-rycjnJzw07xLrNCA== +1 -0
- package/Tests/Artifacts/LottieTests.xcresult/Data/data.0~dirWk6W4Pav1oyciuflfJlRu0iuxbYOmrpQapOJ0mV9C1SQ-jvDRv_7h753Cy18-SwULARUdWsyUy3yNNvxF7w== +0 -0
- package/Tests/Artifacts/LottieTests.xcresult/Data/data.0~ebwZVjSEHroc9jtIm4jd_h_YAqEBcOkAZ4HPNJT8pLCldjRcTq-obQLakxXOhfuoOBlYBoZLuO-Y0lskeZRYKw== +0 -0
- package/Tests/Artifacts/LottieTests.xcresult/Data/data.0~gfcRcmRIr0h09d0jiZsA7nUeQv2XtapxuYEXZy1Z9um0tTJQvz-O5ef5f7zhLenLvjnDtDtlY_aY4Hvpce6e1Q== +0 -0
- package/Tests/Artifacts/LottieTests.xcresult/Data/data.0~hgOgiVCyv2R0W-f0qKw5xYPeUwj8_ccCM9vKH_7vAQcCO9t8BwR1APGRBv20AONmp-PYMXmtgsBlQkNBRBpdQA== +0 -0
- package/Tests/Artifacts/LottieTests.xcresult/Data/data.0~hrhCl-YRAAr8ByNB_LCgEBsVNHMp92gTIUknetpUHMjcXl4Hpn_uY-h6C45oga0ZALnfGCo6iKTmiPLa4Qvnpg== +0 -0
- package/Tests/Artifacts/LottieTests.xcresult/Data/data.0~n2yoR7JsyL4DSUwmjnpE4Iq9Qi_eeZrmpPU8cdehDFKfESK7nwxXxfrSMQbk0BQ2lgGPadoRcd1-qr1xVz97jA== +0 -0
- package/Tests/Artifacts/LottieTests.xcresult/Data/data.0~nMCcZm8WvPogyO_nuJ926Q3Q2dqVMN2LdjEL1Kq2wJ_RG-rH-e_6v41l1xZbCsQTa3XykQdEiXNc0HtAvT6IRA== +0 -0
- package/Tests/Artifacts/LottieTests.xcresult/Data/data.0~oc3C7xkUt-OWDL6rrsxs-seS4Fu1bqBWAAXCHalgShaGg9MUrOiRbHT2DcAnhyQFKx6x5FRbvjmYoQWrQiXJZA== +0 -0
- package/Tests/Artifacts/LottieTests.xcresult/Data/data.0~p-ihj7SEgkDXpMu9hvKE_wiX9cvtwyXrdIn964BfedXHKGpC6o7mMPxEyC0kRPVi_EZs_MRV5bAPEpl5h5we0g== +0 -0
- package/Tests/Artifacts/LottieTests.xcresult/Data/data.0~qlhO_D9oE8uSKH-mZqyRF9pp4Zv1Tv0dIYcqrH4hb1VWlIxcdxmg2j0M8496cQeFXC5bn_JMXdBlD-d6cnFF8w== +0 -0
- package/Tests/Artifacts/LottieTests.xcresult/Data/data.0~tjpiyIxJR_boTdUNrtFDuKIZoY84fI4lA1oMJbq9e2ZmYKIK5FeRN2O8cV_yMOYJGr4lbv03kTmT70mCjUc2_Q== +0 -0
- package/Tests/Artifacts/LottieTests.xcresult/Data/data.0~wULeoj18eEKJWAKx1uFQVwS48cUGFcYPRJQj1Ro5XNJsWCwppGSCdIPhwifD6Z2f_j3zfI2SmC2Gg81sBXXW7g== +0 -0
- package/Tests/Artifacts/LottieTests.xcresult/Data/data.0~zrEihMys4NVV5rx6FmuzEGO2TjloI3OiC7yzIhvqYoRo43ibb2F-Km6Jf4NX-ac62pOLBYZRcjQTvYMpn75_oA== +0 -0
- package/Tests/Artifacts/LottieTests.xcresult/Data/refs.0~-7Vi1RszY1XYnR2CCkEwIpKG8NwwA9zsZEz_WD7Dv6kKh4RC7N7ob8NIRVHGUJKp7eXxlpeI_gzD87Pcs_2u0g== +0 -0
- package/Tests/Artifacts/LottieTests.xcresult/Data/refs.0~-SKV2drO-SFlrlh-wrzECDMkUSr-aF1lV9h-5onOy94zSTsD-oI45s0-KpOK45L-kq3hRY7v9vm-xmh00_eheg== +0 -0
- package/Tests/Artifacts/LottieTests.xcresult/Data/refs.0~-_CU_vuaiFfObSeDFfmp7GuB20ThMSAL-P_RUMowiQLbdu-y0bU9upIm3q8g6XmXUG5hP6J1az0Ma5Hi_rhhRg== +0 -0
- package/Tests/Artifacts/LottieTests.xcresult/Data/refs.0~03aPYP6VHJjZj5DlphGarj0xdw43qu09Onx5SReZoPvg9zh5uL212E-KWfGct9jf6JG0JFV2tdbBi7X_8bH9aw== +0 -0
- package/Tests/Artifacts/LottieTests.xcresult/Data/refs.0~1Z82GPBBPc1VLvn4O7V5glb6lgyXteNlDREUzV_TPymM4ra4UkBMklzV90lEqoYRCDuRVzaQHaDYbmYp3-8CFw== +0 -0
- package/Tests/Artifacts/LottieTests.xcresult/Data/refs.0~1mFDCboXpUu9pSHAiVGr1O_QgqEEtvJp_LUhickxLZo0Z5pj3fvadn1l2MzEOd4bFsVBZifUvcyPa7dzlMWF-A== +0 -0
- package/Tests/Artifacts/LottieTests.xcresult/Data/refs.0~2_L9PUjv2JDKu1n8bDLb4XLB-yex6ZVjDDMwfuKAr7teDw-SKgLgkW6H-m_gjWChIVdB4vW6yvHP7XJxvXtRNA== +0 -0
- package/Tests/Artifacts/LottieTests.xcresult/Data/refs.0~4VqMqsI5lOfxRppnud6-VDWcNsU8J7VgFCJfW2dXPwOcAkvU-I8Um5yp9n0Zv6nr3VmcxYggaVMDFfR0U_vjKw== +0 -0
- package/Tests/Artifacts/LottieTests.xcresult/Data/refs.0~4krT4ZMzDOu34msFUq0Xod142kw4pAeSWX4JSxlsjOI0Wanu3343qeespgFi61MTWq1DdH9XXspVKqGlGm_fyw== +0 -0
- package/Tests/Artifacts/LottieTests.xcresult/Data/refs.0~5_aJsdP-e3dRTAUnH-y1U2plaCuUi1vyHriaZuNK0xFe8wGl9Qft6uLCX2Qt6CRBKJQluEe9o0uRWw1eb42FHQ== +0 -0
- package/Tests/Artifacts/LottieTests.xcresult/Data/refs.0~8b0bSqV7eND54zvHvu1v2Htpm7yn-BOEFw5d3mITJrXWNykJ5BTR9WbrD80JEctNcT-rDqO2xfrQk1tFWeY6Sw== +0 -0
- package/Tests/Artifacts/LottieTests.xcresult/Data/refs.0~9u8KAGpgtSm-mQ12Py8RZUbYbDlBhM3w1I2MQO53K2CSn6IePp7g65DBcdXTYMfG1bgoJ-6x30fjnGe-2UYsDQ== +0 -0
- package/Tests/Artifacts/LottieTests.xcresult/Data/refs.0~Bw7uMs4wqB9ahfEqGii2FkQ9pvZmG6HGe2hmbAT2wyM5hpn8Xh5dELysMcEz6hEsqmn6HdRdLOLZhC_fNaXzgA== +0 -0
- package/Tests/Artifacts/LottieTests.xcresult/Data/refs.0~BwUq2xXQYuE8ya6HT6lfNsdtEjz5AKGf8GvLY6VBxQyIY1vgj_Gov-3NeM69OS66BQRDK0PG9H4Oyg0R48E4vg== +0 -0
- package/Tests/Artifacts/LottieTests.xcresult/Data/refs.0~EkDVUR6dcnzxV_lYjkrJ5QGMVTCvb_upAoBF6DBu61sQkGvZN3fSRTsJ1XfJIZO-JUzdNoVA3D_CcvokL0gnQg== +0 -0
- package/Tests/Artifacts/LottieTests.xcresult/Data/refs.0~FUkcLSJ8RAuPenM4HFG1R-sN5-cDBGcTxgR2jaVCna7xV0ZTyBHriB1Nn59mariNlJDiCoBtMUQEmauGxWtfBA== +0 -0
- package/Tests/Artifacts/LottieTests.xcresult/Data/refs.0~FqsuZe4RVLOOVUYLTL-GTIohZ8TdSfxx7m2KJtLYFPGOdE4XorTX7Oc7kXbhghPRppXT3jW-slI37M34YNEvLQ== +0 -0
- package/Tests/Artifacts/LottieTests.xcresult/Data/refs.0~G4F_NtyTj3i46fmKm0NorHAeq8tYWWYf6uv5yC1DwzdpWVoYbOPufmFNvdEbxZt4AMdV0gKx3HI46EAXNOQVFg== +0 -0
- package/Tests/Artifacts/LottieTests.xcresult/Data/refs.0~GxetzGUNDgaBBXcTmLK6p9JBDX3I3QPshshbui1IaEWvJbQko-E36tCKwaJYHbleAWz9FqkAM_Tqx3YOmSVkVg== +0 -0
- package/Tests/Artifacts/LottieTests.xcresult/Data/refs.0~H1Wjd5kKWDW4t3SDodxiHV72V8WT0xwPubw5cJTNLkPRLgaILFPh-dpy8EOUNgy1KzrDujFsm9EcTsbuqtMPLA== +0 -0
- package/Tests/Artifacts/LottieTests.xcresult/Data/refs.0~JpI5MH4zCgebUHFpXVn4zjtsGtMNnO7BQZWfNARAB5UWa9gqz6YXHR3uLCJ_AvJ3lh53BUVkavsx9TY2FMmxbA== +0 -0
- package/Tests/Artifacts/LottieTests.xcresult/Data/refs.0~JujNYkJtcux0Ni4QnR64zu4Wz_zYjyKvYaYZm5ypxTLPSzF3_jNE_NO4sdbDamF8wEqWoky1uf4ZE0JT3L607A== +0 -0
- package/Tests/Artifacts/LottieTests.xcresult/Data/refs.0~KJSEA6DKnb2_FRPSqKZGh41eo-C8x448J9kEBrH012bUrZfOSDvrgmIrU0Vz7Ri3gaS9aKKmSaVMvXsHSlTJVA== +0 -0
- package/Tests/Artifacts/LottieTests.xcresult/Data/refs.0~MStOwu3jBlJtcRnxrseVOuhI4kCj--ggFPG7sqrq5w1hjrI3bVyD-bm1Jwyx0noY3wT1rHDEvaGWnV2qsGjGwg== +0 -0
- package/Tests/Artifacts/LottieTests.xcresult/Data/refs.0~McsJ8kFVf3IjhgXIRdw8Xx-EXgbV071bmlj2BBnk52xrWl3sEeiIyxwUsF7mIWvMRWfcFfu4VGHYyqfk2BeHXw== +0 -0
- package/Tests/Artifacts/LottieTests.xcresult/Data/refs.0~NHt9fVe4kDdbxnglKcEwXaRK-WsYEOaD23Kbl8SJPRMYHr_Z6SJd_HmG3BROHHR_M6TgSmucONpDJdTj5tjuFw== +0 -0
- package/Tests/Artifacts/LottieTests.xcresult/Data/refs.0~Nfo2iwCPcfAcOBIVyoUAK0-PIfr5qYxIKZt-uaSaTBdrTNxAuJ1ItmeDPZ3VdJJmxD_c22No7x482bdd3_yYtw== +0 -0
- package/Tests/Artifacts/LottieTests.xcresult/Data/refs.0~S2Qlu11xBhEd5aGSzWsnw1TR8u8PiOF93GO0j5bfNoAFCVzxKOwhRFoIXba2EpQnLQqFdIKyhWN3l70A4GPHmg== +0 -0
- package/Tests/Artifacts/LottieTests.xcresult/Data/refs.0~W7a7M37RO9jgck2zeR0471Pm7e8K0Kqj5tXEouDjvqKZXSrWxMaWD28oqkKKYAiU4608R4S9mM11KyphljdMSw== +0 -0
- package/Tests/Artifacts/LottieTests.xcresult/Data/refs.0~XUo1oyPCrlL7CA74wG-OzQ06VOWJYWvHGFHU7keZN1SKaIXjHX5qi_kBzjG_rBCi89-S8GVmCy7S3PHSjG8SbQ== +0 -0
- package/Tests/Artifacts/LottieTests.xcresult/Data/refs.0~Xh0VmDvFNMELHu08-vrs54pegVyUwwDRxx_nXkwyD0NjnYozyqcGAKAr_QWHmw6F8XyuWg51M9KGpJJIFzzGuw== +0 -0
- package/Tests/Artifacts/LottieTests.xcresult/Data/refs.0~Xve-wMBp_lxVUgD9qH5GwieGP9cAWtm0xULZvdGjBRUMvaevmpCB5gnbMBuIXAO6a1c9v6WUq0jNVX7ut5HvOw== +0 -0
- package/Tests/Artifacts/LottieTests.xcresult/Data/refs.0~ZU1XkZFgnEE22CXEF-pOlcj5f10x-KM1Vw9d4IOLu-NiTZcz7koYPixhdrB1PJr8J-h9NpJmfqEastfxamA1jQ== +0 -0
- package/Tests/Artifacts/LottieTests.xcresult/Data/refs.0~_YkNYEHTsbbtFILJpzH3HenH0t4ShI25dIMdve541CF5bl-jPF3X3F7tq-t5dvP0TEkATsOJdLQdBp1xv4Q-ag== +0 -0
- package/Tests/Artifacts/LottieTests.xcresult/Data/refs.0~boy6mpn2jkwm60jjgQ0TG25UqRdN46LzmgTVCrpy6nBOgkLCGkGHcbceiwjU1itS_vj3-iQX0ZnrWOQrPyfHNA== +0 -0
- package/Tests/Artifacts/LottieTests.xcresult/Data/refs.0~bwzpVZ9hAqGDHhXs2FRA82dfGfLmc7-m0uQhZDDfHHO7hQ17M_Np341BZX4WDLhYYS4cdUgaDodlNpdfpG3nXw== +0 -0
- package/Tests/Artifacts/LottieTests.xcresult/Data/refs.0~cBxe-9PpAGFdAsYkmdN3lJVqEliLcRYlyoAov0aPZfJGwUr_cOm3XpjO7nmf_2eLf8UAx-rycjnJzw07xLrNCA== +0 -0
- package/Tests/Artifacts/LottieTests.xcresult/Data/refs.0~dirWk6W4Pav1oyciuflfJlRu0iuxbYOmrpQapOJ0mV9C1SQ-jvDRv_7h753Cy18-SwULARUdWsyUy3yNNvxF7w== +0 -0
- package/Tests/Artifacts/LottieTests.xcresult/Data/refs.0~ebwZVjSEHroc9jtIm4jd_h_YAqEBcOkAZ4HPNJT8pLCldjRcTq-obQLakxXOhfuoOBlYBoZLuO-Y0lskeZRYKw== +0 -0
- package/Tests/Artifacts/LottieTests.xcresult/Data/refs.0~gfcRcmRIr0h09d0jiZsA7nUeQv2XtapxuYEXZy1Z9um0tTJQvz-O5ef5f7zhLenLvjnDtDtlY_aY4Hvpce6e1Q== +0 -0
- package/Tests/Artifacts/LottieTests.xcresult/Data/refs.0~hgOgiVCyv2R0W-f0qKw5xYPeUwj8_ccCM9vKH_7vAQcCO9t8BwR1APGRBv20AONmp-PYMXmtgsBlQkNBRBpdQA== +0 -0
- package/Tests/Artifacts/LottieTests.xcresult/Data/refs.0~hrhCl-YRAAr8ByNB_LCgEBsVNHMp92gTIUknetpUHMjcXl4Hpn_uY-h6C45oga0ZALnfGCo6iKTmiPLa4Qvnpg== +0 -0
- package/Tests/Artifacts/LottieTests.xcresult/Data/refs.0~n2yoR7JsyL4DSUwmjnpE4Iq9Qi_eeZrmpPU8cdehDFKfESK7nwxXxfrSMQbk0BQ2lgGPadoRcd1-qr1xVz97jA== +0 -0
- package/Tests/Artifacts/LottieTests.xcresult/Data/refs.0~nMCcZm8WvPogyO_nuJ926Q3Q2dqVMN2LdjEL1Kq2wJ_RG-rH-e_6v41l1xZbCsQTa3XykQdEiXNc0HtAvT6IRA== +0 -0
- package/Tests/Artifacts/LottieTests.xcresult/Data/refs.0~oc3C7xkUt-OWDL6rrsxs-seS4Fu1bqBWAAXCHalgShaGg9MUrOiRbHT2DcAnhyQFKx6x5FRbvjmYoQWrQiXJZA== +0 -0
- package/Tests/Artifacts/LottieTests.xcresult/Data/refs.0~p-ihj7SEgkDXpMu9hvKE_wiX9cvtwyXrdIn964BfedXHKGpC6o7mMPxEyC0kRPVi_EZs_MRV5bAPEpl5h5we0g== +0 -0
- package/Tests/Artifacts/LottieTests.xcresult/Data/refs.0~qlhO_D9oE8uSKH-mZqyRF9pp4Zv1Tv0dIYcqrH4hb1VWlIxcdxmg2j0M8496cQeFXC5bn_JMXdBlD-d6cnFF8w== +0 -0
- package/Tests/Artifacts/LottieTests.xcresult/Data/refs.0~tjpiyIxJR_boTdUNrtFDuKIZoY84fI4lA1oMJbq9e2ZmYKIK5FeRN2O8cV_yMOYJGr4lbv03kTmT70mCjUc2_Q== +0 -0
- package/Tests/Artifacts/LottieTests.xcresult/Data/refs.0~wULeoj18eEKJWAKx1uFQVwS48cUGFcYPRJQj1Ro5XNJsWCwppGSCdIPhwifD6Z2f_j3zfI2SmC2Gg81sBXXW7g== +0 -0
- package/Tests/Artifacts/LottieTests.xcresult/Data/refs.0~zrEihMys4NVV5rx6FmuzEGO2TjloI3OiC7yzIhvqYoRo43ibb2F-Km6Jf4NX-ac62pOLBYZRcjQTvYMpn75_oA== +0 -0
- package/Tests/Artifacts/LottieTests.xcresult/Info.plist +29 -0
- package/Tests/AutomaticEngineTests.swift +57 -0
- package/Tests/BundleTests.swift +25 -0
- package/Tests/DataURLTests.swift +64 -0
- package/Tests/ParsingTests.swift +42 -0
- package/Tests/PerformanceTests.swift +215 -0
- package/Tests/Samples/9squares_AlBoardman.json +1 -0
- package/Tests/Samples/Boat_Loader.json +1 -0
- package/Tests/Samples/HamburgerArrow.json +1 -0
- package/Tests/Samples/IconTransitions.json +1 -0
- package/Tests/Samples/Images/dog.png +0 -0
- package/Tests/Samples/Issues/issue_1403.json +1 -0
- package/Tests/Samples/Issues/issue_1407.json +1 -0
- package/Tests/Samples/Issues/issue_1488.json +1 -0
- package/Tests/Samples/Issues/issue_1505.json +1 -0
- package/Tests/Samples/Issues/issue_1628.json +1 -0
- package/Tests/Samples/Issues/pr_1536.json +1 -0
- package/Tests/Samples/Issues/pr_1563.json +8439 -0
- package/Tests/Samples/Issues/pr_1592.json +5527 -0
- package/Tests/Samples/Issues/pr_1599.json +738 -0
- package/Tests/Samples/Issues/pr_1604_1.json +1 -0
- package/Tests/Samples/Issues/pr_1604_2.json +1 -0
- package/Tests/Samples/LottieFiles/LICENSE.md +14 -0
- package/Tests/Samples/LottieFiles/bounce_strokes.json +1 -0
- package/Tests/Samples/LottieFiles/cactus.json +1 -0
- package/Tests/Samples/LottieFiles/dog_car_ride.json +1 -0
- package/Tests/Samples/LottieFiles/draft_icon.json +1 -0
- package/Tests/Samples/LottieFiles/gradient_1.json +1 -0
- package/Tests/Samples/LottieFiles/gradient_2.json +1 -0
- package/Tests/Samples/LottieFiles/gradient_pill.json +1 -0
- package/Tests/Samples/LottieFiles/gradient_shapes.json +1 -0
- package/Tests/Samples/LottieFiles/gradient_square.json +1 -0
- package/Tests/Samples/LottieFiles/growth.json +1 -0
- package/Tests/Samples/LottieFiles/infinity_loader.json +1 -0
- package/Tests/Samples/LottieFiles/loading_dots_1.json +1 -0
- package/Tests/Samples/LottieFiles/loading_dots_2.json +1 -0
- package/Tests/Samples/LottieFiles/loading_dots_3.json +1 -0
- package/Tests/Samples/LottieFiles/loading_gradient_strokes.json +1 -0
- package/Tests/Samples/LottieFiles/settings_slider.json +1 -0
- package/Tests/Samples/LottieFiles/shop.json +1 -0
- package/Tests/Samples/LottieFiles/step_loader.json +1 -0
- package/Tests/Samples/LottieLogo1.json +1 -0
- package/Tests/Samples/LottieLogo1_masked.json +1 -0
- package/Tests/Samples/LottieLogo2.json +1 -0
- package/Tests/Samples/MotionCorpse_Jrcanest.json +1 -0
- package/Tests/Samples/Nonanimating/BasicLayers.json +1 -0
- package/Tests/Samples/Nonanimating/DisableNodesTest.json +1 -0
- package/Tests/Samples/Nonanimating/FirstText.json +1 -0
- package/Tests/Samples/Nonanimating/GeometryTransformTest.json +1 -0
- package/Tests/Samples/Nonanimating/Text_AnimatedProperties.json +1 -0
- package/Tests/Samples/Nonanimating/Text_Glyph.json +1 -0
- package/Tests/Samples/Nonanimating/Text_NoAnimation.json +1 -0
- package/Tests/Samples/Nonanimating/Text_NoGlyph.json +1 -0
- package/Tests/Samples/Nonanimating/Zoom.json +1 -0
- package/Tests/Samples/Nonanimating/_dog.json +1 -0
- package/Tests/Samples/Nonanimating/base64Test.json +1 -0
- package/Tests/Samples/Nonanimating/blend_mode_test.json +1 -0
- package/Tests/Samples/Nonanimating/keypathTest.json +1 -0
- package/Tests/Samples/Nonanimating/verifyLineHeight.json +1 -0
- package/Tests/Samples/PinJump.json +1 -0
- package/Tests/Samples/Private/BrokenLottieFiles/growth_man.json +874 -0
- package/Tests/Samples/Private/BrokenLottieFiles/rocket.json +1 -0
- package/Tests/Samples/Private/China_EmptyState_Itinerary.json +1 -0
- package/Tests/Samples/Private/LoaderHourglass.json +12070 -0
- package/Tests/Samples/Private/README.md +7 -0
- package/Tests/Samples/Private/Urgency/alarm_animated.json +1 -0
- package/Tests/Samples/Private/Urgency/diamond_animated.json +1 -0
- package/Tests/Samples/Private/Urgency/eye_animated.json +1 -0
- package/Tests/Samples/Private/Urgency/light_bulb_animated.json +1 -0
- package/Tests/Samples/Private/Urgency/light_bulb_static.json +1 -0
- package/Tests/Samples/Private/Urgency/piggy_bank_static.json +1 -0
- package/Tests/Samples/Private/Urgency/price_tag_legacy.json +1 -0
- package/Tests/Samples/Private/Urgency/rausch_alarm.json +1 -0
- package/Tests/Samples/Private/Urgency/rausch_alert.json +1 -0
- package/Tests/Samples/Private/Urgency/rausch_clock.json +1 -0
- package/Tests/Samples/Private/Urgency/rausch_diamond.json +1 -0
- package/Tests/Samples/Private/Urgency/rausch_money.json +1 -0
- package/Tests/Samples/Private/Urgency/rausch_piggy_bank.json +1 -0
- package/Tests/Samples/Private/Urgency/rausch_tag.json +1 -0
- package/Tests/Samples/Private/Urgency/red_envelope_animated.json +1 -0
- package/Tests/Samples/Private/Urgency/tag_animated.json +1 -0
- package/Tests/Samples/Private/Urgency/trophy_animated.json +1 -0
- package/Tests/Samples/Private/Urgency/wings_key_animated.json +1 -0
- package/Tests/Samples/Private/_flexible.json +1 -0
- package/Tests/Samples/Private/aircover.json +1 -0
- package/Tests/Samples/Private/belo_spin_rausch.json +1 -0
- package/Tests/Samples/Private/celebration.json +2821 -0
- package/Tests/Samples/Private/checkbox.json +1 -0
- package/Tests/Samples/Private/checkbox_small.json +1 -0
- package/Tests/Samples/Private/getting_your_trip_ready.json +3540 -0
- package/Tests/Samples/Private/gradient_afternoon.json +1 -0
- package/Tests/Samples/Private/gradient_brand.json +1 -0
- package/Tests/Samples/Private/gradient_evening.json +1 -0
- package/Tests/Samples/Private/gradient_morning.json +1 -0
- package/Tests/Samples/Private/issue_1467.json +1 -0
- package/Tests/Samples/Private/loading_dots.json +1 -0
- package/Tests/Samples/Private/loading_dots_small.json +1 -0
- package/Tests/Samples/Private/payment_loader.json +1 -0
- package/Tests/Samples/Private/radio_button.json +1 -0
- package/Tests/Samples/Private/selfie_intro.json +1 -0
- package/Tests/Samples/Private/stepper_add.json +1 -0
- package/Tests/Samples/Private/stepper_subtract.json +1 -0
- package/Tests/Samples/Private/switch.json +1 -0
- package/Tests/Samples/Private/thumb.json +1 -0
- package/Tests/Samples/Private/toggle_no.json +1 -0
- package/Tests/Samples/Private/toggle_yes.json +1 -0
- package/Tests/Samples/Private/user_error_black_and_white.json +1 -0
- package/Tests/Samples/Private/user_error_cut_off.json +1 -0
- package/Tests/Samples/Switch.json +1 -0
- package/Tests/Samples/Switch_States.json +1 -0
- package/Tests/Samples/TwitterHeart.json +1 -0
- package/Tests/Samples/TwitterHeartButton.json +1 -0
- package/Tests/Samples/TypeFace/A.json +1 -0
- package/Tests/Samples/TypeFace/Apostrophe.json +1 -0
- package/Tests/Samples/TypeFace/B.json +1 -0
- package/Tests/Samples/TypeFace/BlinkingCursor.json +1 -0
- package/Tests/Samples/TypeFace/C.json +1 -0
- package/Tests/Samples/TypeFace/Colon.json +1 -0
- package/Tests/Samples/TypeFace/Comma.json +1 -0
- package/Tests/Samples/TypeFace/D.json +1 -0
- package/Tests/Samples/TypeFace/E.json +1 -0
- package/Tests/Samples/TypeFace/F.json +1 -0
- package/Tests/Samples/TypeFace/G.json +1 -0
- package/Tests/Samples/TypeFace/H.json +1 -0
- package/Tests/Samples/TypeFace/I.json +1 -0
- package/Tests/Samples/TypeFace/J.json +1 -0
- package/Tests/Samples/TypeFace/K.json +1 -0
- package/Tests/Samples/TypeFace/L.json +1 -0
- package/Tests/Samples/TypeFace/M.json +1 -0
- package/Tests/Samples/TypeFace/N.json +1 -0
- package/Tests/Samples/TypeFace/O.json +1 -0
- package/Tests/Samples/TypeFace/P.json +1 -0
- package/Tests/Samples/TypeFace/Q.json +1 -0
- package/Tests/Samples/TypeFace/R.json +1 -0
- package/Tests/Samples/TypeFace/S.json +1 -0
- package/Tests/Samples/TypeFace/T.json +1 -0
- package/Tests/Samples/TypeFace/U.json +1 -0
- package/Tests/Samples/TypeFace/V.json +1 -0
- package/Tests/Samples/TypeFace/W.json +1 -0
- package/Tests/Samples/TypeFace/X.json +1 -0
- package/Tests/Samples/TypeFace/Y.json +1 -0
- package/Tests/Samples/TypeFace/Z.json +1 -0
- package/Tests/Samples/Watermelon.json +1 -0
- package/Tests/Samples/setValueTest.json +1 -0
- package/Tests/Samples/timeremap.json +1 -0
- package/Tests/Samples/vcTransition1.json +1 -0
- package/Tests/Samples/vcTransition2.json +1 -0
- package/Tests/SnapshotConfiguration.swift +153 -0
- package/Tests/SnapshotTests.swift +265 -0
- package/Tests/Utils/Bundle+Module.swift +30 -0
- package/Tests/Utils/HardcodedFontProvider.swift +19 -0
- package/Tests/Utils/HardcodedImageProvider.swift +23 -0
- package/Tests/Utils/Snapshotting+presentationLayer.swift +47 -0
- package/Tests/ValueProvidersTests.swift +27 -0
- package/lottie-ios.podspec +12 -12
- package/package.json +1 -1
- package/script/lint/airbnb.swiftformat +68 -0
- package/script/lint/swiftlint.yml +38 -0
- package/script/test-carthage/Cartfile +1 -0
- package/script/test-carthage/Cartfile.resolved +1 -0
- package/script/test-carthage/Carthage/Build/.lottie-ios.version +19 -0
- package/script/test-carthage/Carthage/Build/Lottie.xcframework/Info.plist +46 -0
- package/script/test-carthage/Carthage/Build/Lottie.xcframework/ios-arm64/BCSymbolMaps/BF971162-BE99-3507-B5B3-11947DC6B176.bcsymbolmap +14778 -0
- package/script/test-carthage/Carthage/Build/Lottie.xcframework/ios-arm64/Lottie.framework/Headers/Lottie-Swift.h +673 -0
- package/script/test-carthage/Carthage/Build/Lottie.xcframework/ios-arm64/Lottie.framework/Info.plist +0 -0
- package/script/test-carthage/Carthage/Build/Lottie.xcframework/ios-arm64/Lottie.framework/Lottie +0 -0
- package/script/test-carthage/Carthage/Build/Lottie.xcframework/ios-arm64/Lottie.framework/Modules/Lottie.swiftmodule/arm64-apple-ios.swiftdoc +0 -0
- package/script/test-carthage/Carthage/Build/Lottie.xcframework/ios-arm64/Lottie.framework/Modules/Lottie.swiftmodule/arm64-apple-ios.swiftmodule +0 -0
- package/script/test-carthage/Carthage/Build/Lottie.xcframework/ios-arm64/Lottie.framework/Modules/Lottie.swiftmodule/arm64.swiftdoc +0 -0
- package/script/test-carthage/Carthage/Build/Lottie.xcframework/ios-arm64/Lottie.framework/Modules/Lottie.swiftmodule/arm64.swiftmodule +0 -0
- package/script/test-carthage/Carthage/Build/Lottie.xcframework/ios-arm64/Lottie.framework/Modules/module.modulemap +4 -0
- package/script/test-carthage/Carthage/Build/Lottie.xcframework/ios-arm64/dSYMs/Lottie.framework.dSYM/Contents/Info.plist +20 -0
- package/script/test-carthage/Carthage/Build/Lottie.xcframework/ios-arm64/dSYMs/Lottie.framework.dSYM/Contents/Resources/DWARF/Lottie +0 -0
- package/script/test-carthage/Carthage/Build/Lottie.xcframework/ios-arm64_x86_64-simulator/Lottie.framework/Headers/Lottie-Swift.h +1352 -0
- package/script/test-carthage/Carthage/Build/Lottie.xcframework/ios-arm64_x86_64-simulator/Lottie.framework/Info.plist +0 -0
- package/script/test-carthage/Carthage/Build/Lottie.xcframework/ios-arm64_x86_64-simulator/Lottie.framework/Lottie +0 -0
- package/script/test-carthage/Carthage/Build/Lottie.xcframework/ios-arm64_x86_64-simulator/Lottie.framework/Modules/Lottie.swiftmodule/Project/arm64-apple-ios-simulator.swiftsourceinfo +0 -0
- package/script/test-carthage/Carthage/Build/Lottie.xcframework/ios-arm64_x86_64-simulator/Lottie.framework/Modules/Lottie.swiftmodule/Project/arm64.swiftsourceinfo +0 -0
- package/script/test-carthage/Carthage/Build/Lottie.xcframework/ios-arm64_x86_64-simulator/Lottie.framework/Modules/Lottie.swiftmodule/Project/x86_64-apple-ios-simulator.swiftsourceinfo +0 -0
- package/script/test-carthage/Carthage/Build/Lottie.xcframework/ios-arm64_x86_64-simulator/Lottie.framework/Modules/Lottie.swiftmodule/Project/x86_64.swiftsourceinfo +0 -0
- package/script/test-carthage/Carthage/Build/Lottie.xcframework/ios-arm64_x86_64-simulator/Lottie.framework/Modules/Lottie.swiftmodule/arm64-apple-ios-simulator.swiftdoc +0 -0
- package/script/test-carthage/Carthage/Build/Lottie.xcframework/ios-arm64_x86_64-simulator/Lottie.framework/Modules/Lottie.swiftmodule/arm64-apple-ios-simulator.swiftmodule +0 -0
- package/script/test-carthage/Carthage/Build/Lottie.xcframework/ios-arm64_x86_64-simulator/Lottie.framework/Modules/Lottie.swiftmodule/arm64.swiftdoc +0 -0
- package/script/test-carthage/Carthage/Build/Lottie.xcframework/ios-arm64_x86_64-simulator/Lottie.framework/Modules/Lottie.swiftmodule/arm64.swiftmodule +0 -0
- package/script/test-carthage/Carthage/Build/Lottie.xcframework/ios-arm64_x86_64-simulator/Lottie.framework/Modules/Lottie.swiftmodule/x86_64-apple-ios-simulator.swiftdoc +0 -0
- package/script/test-carthage/Carthage/Build/Lottie.xcframework/ios-arm64_x86_64-simulator/Lottie.framework/Modules/Lottie.swiftmodule/x86_64-apple-ios-simulator.swiftmodule +0 -0
- package/script/test-carthage/Carthage/Build/Lottie.xcframework/ios-arm64_x86_64-simulator/Lottie.framework/Modules/Lottie.swiftmodule/x86_64.swiftdoc +0 -0
- package/script/test-carthage/Carthage/Build/Lottie.xcframework/ios-arm64_x86_64-simulator/Lottie.framework/Modules/Lottie.swiftmodule/x86_64.swiftmodule +0 -0
- package/script/test-carthage/Carthage/Build/Lottie.xcframework/ios-arm64_x86_64-simulator/Lottie.framework/Modules/module.modulemap +4 -0
- package/script/test-carthage/Carthage/Build/Lottie.xcframework/ios-arm64_x86_64-simulator/Lottie.framework/_CodeSignature/CodeResources +256 -0
- package/script/test-carthage/Carthage/Build/Lottie.xcframework/ios-arm64_x86_64-simulator/dSYMs/Lottie.framework.dSYM/Contents/Info.plist +20 -0
- package/script/test-carthage/Carthage/Build/Lottie.xcframework/ios-arm64_x86_64-simulator/dSYMs/Lottie.framework.dSYM/Contents/Resources/DWARF/Lottie +0 -0
- package/script/test-carthage/Carthage/Checkouts/lottie-ios/Lottie.xcodeproj/project.xcworkspace/xcuserdata/cal.xcuserdatad/UserInterfaceState.xcuserstate +0 -0
- package/script/test-carthage/Carthage/Checkouts/lottie-ios/Lottie.xcodeproj/xcuserdata/cal.xcuserdatad/xcschemes/xcschememanagement.plist +37 -0
- package/script/test-carthage/Carthage/Checkouts/lottie-ios/Lottie.xcworkspace/xcuserdata/cal.xcuserdatad/UserInterfaceState.xcuserstate +0 -0
- package/script/test-carthage/CarthageTest/AppDelegate.swift +27 -0
- package/script/test-carthage/CarthageTest/Assets.xcassets/AccentColor.colorset/Contents.json +11 -0
- package/script/test-carthage/CarthageTest/Assets.xcassets/AppIcon.appiconset/Contents.json +98 -0
- package/script/test-carthage/CarthageTest/Assets.xcassets/Contents.json +6 -0
- package/script/test-carthage/CarthageTest/Base.lproj/LaunchScreen.storyboard +25 -0
- package/script/test-carthage/CarthageTest/Base.lproj/Main.storyboard +24 -0
- package/script/test-carthage/CarthageTest/Info.plist +66 -0
- package/script/test-carthage/CarthageTest/SceneDelegate.swift +10 -0
- package/script/test-carthage/CarthageTest/ViewController.swift +15 -0
- package/script/test-carthage/CarthageTest.xcodeproj/project.pbxproj +378 -0
- package/script/test-carthage/CarthageTest.xcodeproj/project.xcworkspace/contents.xcworkspacedata +7 -0
- package/script/test-carthage/CarthageTest.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist +8 -0
- package/script/test-carthage/CarthageTest.xcodeproj/project.xcworkspace/xcuserdata/cal.xcuserdatad/UserInterfaceState.xcuserstate +0 -0
- package/script/test-carthage/CarthageTest.xcodeproj/xcuserdata/cal.xcuserdatad/xcschemes/xcschememanagement.plist +14 -0
- package/script/test-carthage/Mintfile +1 -0
- package/script/test-spm/LottieSPM.xcworkspace/contents.xcworkspacedata +7 -0
- package/script/test-spm/LottieSPM.xcworkspace/xcuserdata/cal.xcuserdatad/UserInterfaceState.xcuserstate +0 -0
- package/script/test-spm/Mintfile +1 -0
- package/.swiftpm/xcode/package.xcworkspace/xcuserdata/brandonwithrow.xcuserdatad/UserInterfaceState.xcuserstate +0 -0
- package/Lottie/Info.plist +0 -22
- package/Lottie.xcodeproj/project.xcworkspace/xcuserdata/brandonwithrow.xcuserdatad/UserInterfaceState.xcuserstate +0 -0
- package/Lottie.xcodeproj/xcuserdata/brandonwithrow.xcuserdatad/xcschemes/LottieLibraryMacOS.xcscheme +0 -80
- package/Lottie.xcodeproj/xcuserdata/brandonwithrow.xcuserdatad/xcschemes/xcschememanagement.plist +0 -57
- package/lottie-swift/Assets/.gitkeep +0 -0
- package/lottie-swift/src/Private/LayerContainers/Utility/LayerFontProvider.swift +0 -37
- package/lottie-swift/src/Private/LayerContainers/Utility/LayerTextProvider.swift +0 -36
- package/lottie-swift/src/Private/Model/Animation.swift +0 -107
- package/lottie-swift/src/Private/Model/Assets/Asset.swift +0 -27
- package/lottie-swift/src/Private/Model/Assets/ImageAsset.swift +0 -48
- package/lottie-swift/src/Private/Model/Keyframes/Keyframe.swift +0 -128
- package/lottie-swift/src/Private/Model/Keyframes/KeyframeGroup.swift +0 -108
- package/lottie-swift/src/Private/Model/Layers/LayerModel.swift +0 -150
- package/lottie-swift/src/Private/Model/Objects/DashPattern.swift +0 -24
- package/lottie-swift/src/Private/Model/Objects/Marker.swift +0 -23
- package/lottie-swift/src/Private/Model/Objects/Mask.swift +0 -48
- package/lottie-swift/src/Private/Model/Objects/Transform.swift +0 -105
- package/lottie-swift/src/Private/Model/ShapeItems/Ellipse.swift +0 -50
- package/lottie-swift/src/Private/Model/ShapeItems/FillI.swift +0 -49
- package/lottie-swift/src/Private/Model/ShapeItems/GradientFill.swift +0 -86
- package/lottie-swift/src/Private/Model/ShapeItems/GradientStroke.swift +0 -125
- package/lottie-swift/src/Private/Model/ShapeItems/Rectangle.swift +0 -50
- package/lottie-swift/src/Private/Model/ShapeItems/Repeater.swift +0 -80
- package/lottie-swift/src/Private/Model/ShapeItems/Shape.swift +0 -37
- package/lottie-swift/src/Private/Model/ShapeItems/ShapeItem.swift +0 -95
- package/lottie-swift/src/Private/Model/ShapeItems/ShapeTransform.swift +0 -68
- package/lottie-swift/src/Private/Model/ShapeItems/Star.swift +0 -86
- package/lottie-swift/src/Private/Model/ShapeItems/Stroke.swift +0 -67
- package/lottie-swift/src/Private/Model/ShapeItems/Trim.swift +0 -53
- package/lottie-swift/src/Private/Model/Text/Font.swift +0 -35
- package/lottie-swift/src/Private/Model/Text/TextAnimator.swift +0 -99
- package/lottie-swift/src/Private/Model/Text/TextDocument.swift +0 -70
- package/lottie-swift/src/Private/NodeRenderSystem/Nodes/PathNodes/EllipseNode.swift +0 -109
- package/lottie-swift/src/Private/NodeRenderSystem/Nodes/PathNodes/PolygonNode.swift +0 -132
- package/lottie-swift/src/Private/NodeRenderSystem/Nodes/RenderContainers/GroupNode.swift +0 -141
- package/lottie-swift/src/Private/Utility/Extensions/MathKit.swift +0 -539
- package/lottie-swift/src/Private/Utility/Extensions/StringExtensions.swift +0 -32
- package/lottie-swift/src/Private/Utility/Interpolatable/Interpolatable.swift +0 -18
- package/lottie-swift/src/Private/Utility/Interpolatable/InterpolatableExtensions.swift +0 -170
- package/lottie-swift/src/Private/Utility/Primitives/CurveVertex.swift +0 -177
- package/lottie-swift/src/Private/Utility/Primitives/PathElement.swift +0 -68
- package/lottie-swift/src/Private/Utility/Primitives/VectorsExtensions.swift +0 -218
- package/lottie-swift/src/Public/Animation/AnimationPublic.swift +0 -196
- package/lottie-swift/src/Public/Animation/AnimationView.swift +0 -1006
- package/lottie-swift/src/Public/Animation/AnimationViewInitializers.swift +0 -83
- package/lottie-swift/src/Public/AnimationCache/AnimationCacheProvider.swift +0 -24
- package/lottie-swift/src/Public/DynamicProperties/AnimationKeypath.swift +0 -46
- package/lottie-swift/src/Public/DynamicProperties/AnyValueProvider.swift +0 -29
- package/lottie-swift/src/Public/DynamicProperties/ValueProviders/GradientValueProvider.swift +0 -114
- package/lottie-swift/src/Public/ImageProvider/AnimationImageProvider.swift +0 -23
- package/lottie-swift/src/Public/MacOS/FilepathImageProvider.swift +0 -67
- package/lottie-swift/src/Public/TextProvider/AnimationTextProvider.swift +0 -39
- package/lottie-swift/src/Public/iOS/LottieView.swift +0 -62
- package/lottie-swift-testing.podspec +0 -32
package/README.md
CHANGED
|
@@ -1,18 +1,17 @@
|
|
|
1
|
-
# Lottie for iOS
|
|
2
|
-
[](https://cocoapods.org/pods/lottie-ios)[](https://cocoapods.org/pods/lottie-ios)[](https://cocoapods.org/pods/lottie-ios) [](https://cocoapods.org/pods/lottie-ios) [](https://swiftpackageindex.com/airbnb/lottie-ios) [](https://swiftpackageindex.com/airbnb/lottie-ios)
|
|
3
3
|
|
|
4
|
-
|
|
4
|
+
**View documentation, FAQ, help, examples, and more at [airbnb.io/lottie](http://airbnb.io/lottie/)**
|
|
5
5
|
|
|
6
|
-
Lottie is a
|
|
6
|
+
Lottie is a cross-platform library for iOS, macOS, tvOS, [Android](https://github.com/airbnb/lottie), and [Web](https://github.com/airbnb/lottie-web) that natively renders vector based animations and art in realtime with minimal code.
|
|
7
7
|
|
|
8
|
-
Lottie loads and renders animations and vectors exported in the bodymovin JSON format. Bodymovin JSON can be created and exported from After Effects with [bodymovin](https://github.com/bodymovin/bodymovin), Sketch with [Lottie Sketch Export](https://github.com/buba447/Lottie-Sketch-Export), and from [Haiku](https://www.haiku.ai).
|
|
8
|
+
Lottie loads and renders animations and vectors exported in the bodymovin JSON format. Bodymovin JSON can be created and exported from After Effects with [bodymovin](https://github.com/bodymovin/bodymovin), Sketch with [Lottie Sketch Export](https://github.com/buba447/Lottie-Sketch-Export), and from [Haiku](https://www.haiku.ai).
|
|
9
9
|
|
|
10
|
-
|
|
10
|
+
Designers can create **and ship** beautiful animations without an engineer painstakingly recreating it by hand.
|
|
11
11
|
Since the animation is backed by JSON they are extremely small in size but can be large in complexity!
|
|
12
12
|
Animations can be played, resized, looped, sped up, slowed down, reversed, and even interactively scrubbed.
|
|
13
13
|
Lottie can play or loop just a portion of the animation as well, the possibilities are endless!
|
|
14
14
|
Animations can even be ***changed at runtime*** in various ways! Change the color, position or any keyframable value!
|
|
15
|
-
Lottie also supports native UIViewController Transitions out of the box!
|
|
16
15
|
|
|
17
16
|
Here is just a small sampling of the power of Lottie
|
|
18
17
|
|
|
@@ -26,10 +25,18 @@ Here is just a small sampling of the power of Lottie
|
|
|
26
25
|

|
|
27
26
|
|
|
28
27
|
## Installing Lottie
|
|
29
|
-
Lottie supports [CocoaPods](https://cocoapods.org/) and [Carthage](https://github.com/Carthage/Carthage) (Both dynamic and static).
|
|
28
|
+
Lottie supports [Swift Package Manager](https://www.swift.org/package-manager/), [CocoaPods](https://cocoapods.org/) and [Carthage](https://github.com/Carthage/Carthage) (Both dynamic and static).
|
|
29
|
+
|
|
30
30
|
### Github Repo
|
|
31
31
|
|
|
32
|
-
You can pull the [Lottie Github Repo](https://github.com/airbnb/lottie-ios/) and include the Lottie.xcodeproj to build a dynamic or static library.
|
|
32
|
+
You can pull the [Lottie Github Repo](https://github.com/airbnb/lottie-ios/) and include the `Lottie.xcodeproj` to build a dynamic or static library.
|
|
33
|
+
|
|
34
|
+
### Swift Package Manager
|
|
35
|
+
|
|
36
|
+
To install Lottie using [Swift Package Manager](https://github.com/apple/swift-package-manager) you can follow the [tutorial published by Apple](https://developer.apple.com/documentation/xcode/adding_package_dependencies_to_your_app) using the URL for the Lottie repo with the current version:
|
|
37
|
+
|
|
38
|
+
1. In Xcode, select “File” → “Swift Packages” → “Add Package Dependency”
|
|
39
|
+
1. Enter https://github.com/airbnb/lottie-ios.git
|
|
33
40
|
|
|
34
41
|
### CocoaPods
|
|
35
42
|
Add the pod to your Podfile:
|
|
@@ -41,7 +48,7 @@ And then run:
|
|
|
41
48
|
```ruby
|
|
42
49
|
pod install
|
|
43
50
|
```
|
|
44
|
-
After installing the cocoapod into your project import Lottie with
|
|
51
|
+
After installing the cocoapod into your project import Lottie with
|
|
45
52
|
```swift
|
|
46
53
|
import Lottie
|
|
47
54
|
```
|
|
@@ -57,60 +64,34 @@ carthage update
|
|
|
57
64
|
```
|
|
58
65
|
In your application targets “General” tab under the “Linked Frameworks and Libraries” section, drag and drop lottie-ios.framework from the Carthage/Build/iOS directory that `carthage update` produced.
|
|
59
66
|
|
|
60
|
-
###
|
|
61
|
-
``` swift
|
|
62
|
-
// swift-tools-version:5.1
|
|
63
|
-
|
|
64
|
-
import PackageDescription
|
|
65
|
-
|
|
66
|
-
let package = Package(
|
|
67
|
-
name: "YourTestProject",
|
|
68
|
-
platforms: [
|
|
69
|
-
.iOS(.v12),
|
|
70
|
-
],
|
|
71
|
-
dependencies: [
|
|
72
|
-
.package(url: "https://github.com/airbnb/lottie-ios.git", from: "3.1.2")
|
|
73
|
-
],
|
|
74
|
-
targets: [
|
|
75
|
-
.target(name: "YourTestProject", dependencies: ["Lottie"])
|
|
76
|
-
]
|
|
77
|
-
)
|
|
78
|
-
```
|
|
79
|
-
And then import wherever needed: ```import Lottie```
|
|
80
|
-
|
|
81
|
-
#### Adding it to an existent iOS Project via Swift Package Manager
|
|
82
|
-
|
|
83
|
-
1. Using Xcode 11 go to File > Swift Packages > Add Package Dependency
|
|
84
|
-
2. Paste the project URL: https://github.com/airbnb/lottie-ios
|
|
85
|
-
3. Click on next and select the project target
|
|
86
|
-
4. Don't forget to set `DEAD_CODE_STRIPPING = NO` in your `Build Settings` (https://bugs.swift.org/plugins/servlet/mobile#issue/SR-11564)
|
|
87
|
-
**NOTE: For MacOS you must set the `Branch` field to `lottie/macos-spm`
|
|
88
|
-

|
|
89
|
-
|
|
90
|
-
If you have doubts, please, check the following links:
|
|
91
|
-
|
|
92
|
-
[How to use](https://developer.apple.com/videos/play/wwdc2019/408/)
|
|
93
|
-
|
|
94
|
-
[Creating Swift Packages](https://developer.apple.com/videos/play/wwdc2019/410/)
|
|
95
|
-
|
|
96
|
-
After successfully retrieved the package and added it to your project, just import `Lottie` and you can get the full benefits of it.
|
|
97
|
-
|
|
98
|
-
-----
|
|
99
|
-
|
|
100
|
-
### Objective-C Support
|
|
67
|
+
### Data collection
|
|
101
68
|
|
|
102
|
-
|
|
69
|
+
The Lottie SDK does not collect any data. We provide this notice to help you fill out [App Privacy Details](https://developer.apple.com/app-store/app-privacy-details/).
|
|
103
70
|
|
|
104
|
-
|
|
71
|
+
## Contributing
|
|
105
72
|
|
|
106
|
-
|
|
73
|
+
We always appreciate contributions from the community. To make changes to the project, you can clone the repo and open `Lottie.xcworkspace`. This workspace includes:
|
|
74
|
+
- the Lottie framework (for iOS, macOS, and tvOS)
|
|
75
|
+
- unit tests and snapshot tests (for iOS, must be run on an iPhone 8 simulator)
|
|
76
|
+
- an Example iOS app that lets you browse and test over 100 sample animations included in the repo
|
|
107
77
|
|
|
108
|
-
|
|
78
|
+
All pull requests with new features or bug fixes that affect how animations render should include snapshot test cases that validate the included changes.
|
|
79
|
+
- To add a new sample animation to the snapshot testing suite, you can add the `.json` file to `Tests/Samples`. Re-run the snapshot tests to generate the new snapshot image files.
|
|
80
|
+
- To update existing snapshots after making changes, you can set `isRecording = true` in `SnapshotTests.swift` and then re-run the snapshot tests.
|
|
109
81
|
|
|
110
|
-
|
|
82
|
+
The project also include several helpful commands defined in our [Rakefile](https://github.com/airbnb/lottie-ios/blob/master/Rakefile). To use these, you need to install [Bundler](https://bundler.io/) and [Mint](https://github.com/yonaskolb/Mint):
|
|
111
83
|
|
|
112
|
-
|
|
84
|
+
```bash
|
|
85
|
+
$ sudo gem install bundle
|
|
86
|
+
$ bundle install
|
|
87
|
+
$ brew install mint
|
|
88
|
+
```
|
|
113
89
|
|
|
114
|
-
|
|
90
|
+
For example, all Swift code should be formatted according to the [Airbnb Swift Style Guide](https://github.com/airbnb/swift). After making changes, you can reformat the code automatically using [SwiftFormat](https://github.com/nicklockwood/SwiftFormat) and [SwiftLint](https://github.com/realm/SwiftLint) by running `bundle exec rake format:swift`. Other helpful commands include:
|
|
115
91
|
|
|
116
|
-
|
|
92
|
+
```bash
|
|
93
|
+
$ bundle exec rake build:all # builds all targets for all platforms
|
|
94
|
+
$ bundle exec rake build:package:iOS # builds the Lottie package for iOS
|
|
95
|
+
$ bundle exec rake test:package # tests the Lottie package
|
|
96
|
+
$ bundle exec rake format:swift # reformat Swift code based on the Airbnb Swift Style Guide
|
|
97
|
+
```
|
package/Rakefile
ADDED
|
@@ -0,0 +1,125 @@
|
|
|
1
|
+
namespace :build do
|
|
2
|
+
desc 'Builds all packages and executables'
|
|
3
|
+
task all: ['package:all', 'example:all']
|
|
4
|
+
|
|
5
|
+
desc 'Builds the Lottie package for supported platforms'
|
|
6
|
+
namespace :package do
|
|
7
|
+
desc 'Builds the Lottie package for all supported platforms'
|
|
8
|
+
task all: ['iOS', 'macOS', 'tvOS']
|
|
9
|
+
|
|
10
|
+
desc 'Builds the Lottie package for iOS'
|
|
11
|
+
task :iOS do
|
|
12
|
+
xcodebuild('build -scheme "Lottie (iOS)" -destination generic/platform=iOS -workspace Lottie.xcworkspace')
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
desc 'Builds the Lottie package for macOS'
|
|
16
|
+
task :macOS do
|
|
17
|
+
xcodebuild('build -scheme "Lottie (macOS)" -destination generic/platform=macOS -workspace Lottie.xcworkspace')
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
desc 'Builds the Lottie package for tvOS'
|
|
21
|
+
task :tvOS do
|
|
22
|
+
xcodebuild('build -scheme "Lottie (tvOS)" -destination generic/platform=tvOS -workspace Lottie.xcworkspace')
|
|
23
|
+
end
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
desc 'Builds the Lottie example app for supported platforms'
|
|
27
|
+
namespace :example do
|
|
28
|
+
desc 'Builds the Lottie example apps for all supported platforms'
|
|
29
|
+
task all: ['iOS', 'macOS', 'tvOS']
|
|
30
|
+
|
|
31
|
+
desc 'Builds the iOS Lottie Example app'
|
|
32
|
+
task :iOS do
|
|
33
|
+
xcodebuild('build -scheme "Example (iOS)" -destination "platform=iOS Simulator,name=iPhone 8" -workspace Lottie.xcworkspace')
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
desc 'Builds the macOS Lottie Example app'
|
|
37
|
+
task :macOS do
|
|
38
|
+
xcodebuild('build -scheme "Example (macOS)" -workspace Lottie.xcworkspace')
|
|
39
|
+
end
|
|
40
|
+
|
|
41
|
+
desc 'Builds the tvOS Lottie Example app'
|
|
42
|
+
task :tvOS do
|
|
43
|
+
xcodebuild('build -scheme "Example (tvOS)" -destination "platform=tvOS Simulator,name=Apple TV" -workspace Lottie.xcworkspace')
|
|
44
|
+
end
|
|
45
|
+
end
|
|
46
|
+
end
|
|
47
|
+
|
|
48
|
+
namespace :test do
|
|
49
|
+
desc 'Tests the Lottie package for iOS'
|
|
50
|
+
task :package do
|
|
51
|
+
sh 'rm -rf Tests/Artifacts'
|
|
52
|
+
xcodebuild('test -scheme "Lottie (iOS)" -destination "platform=iOS Simulator,name=iPhone 8" -resultBundlePath Tests/Artifacts/LottieTests.xcresult')
|
|
53
|
+
end
|
|
54
|
+
|
|
55
|
+
desc 'Processes .xcresult artifacts from the most recent test:package execution'
|
|
56
|
+
task :process do
|
|
57
|
+
sh 'mint run ChargePoint/xcparse@2.2.1 xcparse attachments Tests/Artifacts/LottieTests.xcresult Tests/Artifacts/TestAttachments'
|
|
58
|
+
end
|
|
59
|
+
|
|
60
|
+
desc 'Tests Carthage support'
|
|
61
|
+
task :carthage do
|
|
62
|
+
# Copy the repo to `Carthage/Checkouts/Lottie-ios`
|
|
63
|
+
sh 'rm -rf script/test-carthage/Carthage'
|
|
64
|
+
sh 'mkdir script/test-carthage/Carthage script/test-carthage/Carthage/Checkouts script/test-carthage/Carthage/Checkouts/lottie-ios'
|
|
65
|
+
sh 'cp -R [^script]* script/test-carthage/Carthage/Checkouts/lottie-ios'
|
|
66
|
+
|
|
67
|
+
Dir.chdir('script/test-carthage') do
|
|
68
|
+
# Build the LottieCarthage framework scheme
|
|
69
|
+
sh 'carthage build --use-xcframeworks'
|
|
70
|
+
|
|
71
|
+
# Delete Carthage's derived data to verify that the built .xcframework doesn't depend on any
|
|
72
|
+
# side effects from building on this specific machine.
|
|
73
|
+
# https://github.com/airbnb/lottie-ios/issues/1492
|
|
74
|
+
sh 'rm -rf ~/Library/Caches/org.carthage.CarthageKit/DerivedData'
|
|
75
|
+
|
|
76
|
+
# Build a test app that imports and uses the LottieCarthage framework
|
|
77
|
+
xcodebuild('build -scheme CarthageTest -destination "platform=iOS Simulator,name=iPhone 8"')
|
|
78
|
+
end
|
|
79
|
+
end
|
|
80
|
+
|
|
81
|
+
desc 'Tests Swift Package Manager support'
|
|
82
|
+
task :spm do
|
|
83
|
+
Dir.chdir('script/test-spm') do
|
|
84
|
+
# Build for iOS, macOS, and tvOS using the targets defined in Package.swift
|
|
85
|
+
xcodebuild('build -scheme "Lottie" -destination generic/platform=iOS')
|
|
86
|
+
xcodebuild('build -scheme "Lottie" -destination generic/platform=macOS')
|
|
87
|
+
xcodebuild('build -scheme "Lottie" -destination generic/platform=tvOS')
|
|
88
|
+
end
|
|
89
|
+
end
|
|
90
|
+
end
|
|
91
|
+
|
|
92
|
+
namespace :lint do
|
|
93
|
+
desc 'Lints swift files'
|
|
94
|
+
task swift: ['swift:swiftlint', 'swift:swiftformat']
|
|
95
|
+
|
|
96
|
+
desc 'Lints swift files'
|
|
97
|
+
namespace :swift do
|
|
98
|
+
desc 'Lints swift files using SwiftLint'
|
|
99
|
+
task :swiftlint do
|
|
100
|
+
sh 'mint run SwiftLint lint Sources Tests Example Package.swift --config script/lint/swiftlint.yml --strict'
|
|
101
|
+
end
|
|
102
|
+
|
|
103
|
+
desc 'Lints swift files using SwiftLint'
|
|
104
|
+
task :swiftformat do
|
|
105
|
+
sh 'mint run SwiftFormat Sources Tests Example Package.swift --config script/lint/airbnb.swiftformat --lint'
|
|
106
|
+
end
|
|
107
|
+
end
|
|
108
|
+
|
|
109
|
+
desc 'Lints the CocoaPods podspec'
|
|
110
|
+
task :podspec do
|
|
111
|
+
sh 'pod lib lint lottie-ios.podspec'
|
|
112
|
+
end
|
|
113
|
+
end
|
|
114
|
+
|
|
115
|
+
namespace :format do
|
|
116
|
+
desc 'Runs SwiftFormat'
|
|
117
|
+
task :swift do
|
|
118
|
+
sh 'mint run SwiftLint autocorrect Sources Tests Example Package.swift --config script/lint/swiftlint.yml'
|
|
119
|
+
sh 'mint run SwiftFormat Sources Tests Example Package.swift --config script/lint/airbnb.swiftformat'
|
|
120
|
+
end
|
|
121
|
+
end
|
|
122
|
+
|
|
123
|
+
def xcodebuild(command)
|
|
124
|
+
sh "set -o pipefail && xcodebuild #{command} | mint run xcbeautify"
|
|
125
|
+
end
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
// Created by Cal Stephens on 1/6/22.
|
|
2
|
+
// Copyright © 2022 Airbnb Inc. All rights reserved.
|
|
3
|
+
|
|
4
|
+
import QuartzCore
|
|
5
|
+
|
|
6
|
+
extension CAAnimation {
|
|
7
|
+
/// Creates a `CAAnimation` that wraps this animation,
|
|
8
|
+
/// applying timing-related configuration from the given `LayerAnimationContext`
|
|
9
|
+
@nonobjc
|
|
10
|
+
func timed(with context: LayerAnimationContext, for layer: CALayer) -> CAAnimation {
|
|
11
|
+
|
|
12
|
+
// The base animation always has the duration of the full animation,
|
|
13
|
+
// since that's the time space where keyframing and interpolating happens.
|
|
14
|
+
// So we start with a simple animation timeline from 0% to 100%:
|
|
15
|
+
//
|
|
16
|
+
// ┌──────────────────────────────────┐
|
|
17
|
+
// │ baseAnimation │
|
|
18
|
+
// └──────────────────────────────────┘
|
|
19
|
+
// 0% 100%
|
|
20
|
+
//
|
|
21
|
+
let baseAnimation = self
|
|
22
|
+
baseAnimation.duration = context.animation.duration
|
|
23
|
+
baseAnimation.speed = (context.endFrame < context.startFrame) ? -1 : 1
|
|
24
|
+
|
|
25
|
+
// To select the subrange of the `baseAnimation` that should be played,
|
|
26
|
+
// we create a parent animation with the duration of that subrange
|
|
27
|
+
// to clip the `baseAnimation`. This parent animation can then loop
|
|
28
|
+
// and/or autoreverse over the clipped subrange.
|
|
29
|
+
//
|
|
30
|
+
// ┌────────────────────┬───────►
|
|
31
|
+
// │ clippingParent │ ...
|
|
32
|
+
// └────────────────────┴───────►
|
|
33
|
+
// 25% 75%
|
|
34
|
+
// ┌──────────────────────────────────┐
|
|
35
|
+
// │ baseAnimation │
|
|
36
|
+
// └──────────────────────────────────┘
|
|
37
|
+
// 0% 100%
|
|
38
|
+
//
|
|
39
|
+
let clippingParent = CAAnimationGroup()
|
|
40
|
+
clippingParent.animations = [baseAnimation]
|
|
41
|
+
|
|
42
|
+
clippingParent.duration = Double(abs(context.endFrame - context.startFrame)) / context.animation.framerate
|
|
43
|
+
baseAnimation.timeOffset = context.animation.time(forFrame: context.startFrame)
|
|
44
|
+
|
|
45
|
+
clippingParent.autoreverses = context.timingConfiguration.autoreverses
|
|
46
|
+
clippingParent.repeatCount = context.timingConfiguration.repeatCount
|
|
47
|
+
clippingParent.timeOffset = context.timingConfiguration.timeOffset
|
|
48
|
+
|
|
49
|
+
// Once the animation ends, it should pause on the final frame
|
|
50
|
+
clippingParent.fillMode = .both
|
|
51
|
+
clippingParent.isRemovedOnCompletion = false
|
|
52
|
+
|
|
53
|
+
// We can pause the animation on a specific frame by setting the root layer's
|
|
54
|
+
// `speed` to 0, and then setting the `timeOffset` for the given frame.
|
|
55
|
+
// - For that setup to work properly, we have to set the `beginTime`
|
|
56
|
+
// of this animation to a time slightly before the current time.
|
|
57
|
+
// - It's not really clear why this is necessary, but `timeOffset`
|
|
58
|
+
// is not applied correctly without this configuration.
|
|
59
|
+
// - We can't do this when playing the animation in real time,
|
|
60
|
+
// because it can cause keyframe timings to be incorrect.
|
|
61
|
+
if context.timingConfiguration.speed == 0 {
|
|
62
|
+
let currentTime = layer.convertTime(CACurrentMediaTime(), from: nil)
|
|
63
|
+
clippingParent.beginTime = currentTime - .leastNonzeroMagnitude
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
return clippingParent
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
extension CALayer {
|
|
71
|
+
/// Adds the given animation to this layer, timed with the given timing configuration
|
|
72
|
+
@nonobjc
|
|
73
|
+
func add(_ animation: CAPropertyAnimation, timedWith context: LayerAnimationContext) {
|
|
74
|
+
add(animation.timed(with: context, for: self), forKey: animation.keyPath)
|
|
75
|
+
}
|
|
76
|
+
}
|
|
@@ -0,0 +1,322 @@
|
|
|
1
|
+
// Created by Cal Stephens on 12/14/21.
|
|
2
|
+
// Copyright © 2021 Airbnb Inc. All rights reserved.
|
|
3
|
+
|
|
4
|
+
import QuartzCore
|
|
5
|
+
|
|
6
|
+
extension CALayer {
|
|
7
|
+
|
|
8
|
+
// MARK: Internal
|
|
9
|
+
|
|
10
|
+
/// Constructs a `CAKeyframeAnimation` that reflects the given keyframes,
|
|
11
|
+
/// and adds it to this `CALayer`.
|
|
12
|
+
@nonobjc
|
|
13
|
+
func addAnimation<KeyframeValue, ValueRepresentation: Equatable>(
|
|
14
|
+
for property: LayerProperty<ValueRepresentation>,
|
|
15
|
+
keyframes: ContiguousArray<Keyframe<KeyframeValue>>,
|
|
16
|
+
value keyframeValueMapping: (KeyframeValue) throws -> ValueRepresentation,
|
|
17
|
+
context: LayerAnimationContext)
|
|
18
|
+
throws
|
|
19
|
+
{
|
|
20
|
+
if let customAnimation = try customizedAnimation(for: property, context: context) {
|
|
21
|
+
add(customAnimation, timedWith: context)
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
else if
|
|
25
|
+
let defaultAnimation = try defaultAnimation(
|
|
26
|
+
for: property,
|
|
27
|
+
keyframes: keyframes,
|
|
28
|
+
value: keyframeValueMapping,
|
|
29
|
+
context: context)
|
|
30
|
+
{
|
|
31
|
+
add(defaultAnimation, timedWith: context)
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
// MARK: Private
|
|
36
|
+
|
|
37
|
+
/// Constructs a `CAAnimation` that reflects the given keyframes
|
|
38
|
+
/// - If the value can be applied directly to the CALayer using KVC,
|
|
39
|
+
/// then no `CAAnimation` will be created and the value will be applied directly.
|
|
40
|
+
@nonobjc
|
|
41
|
+
private func defaultAnimation<KeyframeValue, ValueRepresentation>(
|
|
42
|
+
for property: LayerProperty<ValueRepresentation>,
|
|
43
|
+
keyframes: ContiguousArray<Keyframe<KeyframeValue>>,
|
|
44
|
+
value keyframeValueMapping: (KeyframeValue) throws -> ValueRepresentation,
|
|
45
|
+
context: LayerAnimationContext)
|
|
46
|
+
throws
|
|
47
|
+
-> CAPropertyAnimation?
|
|
48
|
+
{
|
|
49
|
+
guard !keyframes.isEmpty else { return nil }
|
|
50
|
+
|
|
51
|
+
// If there is exactly one keyframe value, we can improve performance
|
|
52
|
+
// by applying that value directly to the layer instead of creating
|
|
53
|
+
// a relatively expensive `CAKeyframeAnimation`.
|
|
54
|
+
if keyframes.count == 1 {
|
|
55
|
+
let keyframeValue = try keyframeValueMapping(keyframes[0].value)
|
|
56
|
+
|
|
57
|
+
// If the keyframe value is the same as the layer's default value for this property,
|
|
58
|
+
// then we can just ignore this set of keyframes.
|
|
59
|
+
if keyframeValue == property.defaultValue {
|
|
60
|
+
return nil
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
// If the property on the CALayer being animated hasn't been modified from the default yet,
|
|
64
|
+
// then we can apply the keyframe value directly to the layer using KVC instead
|
|
65
|
+
// of creating a `CAAnimation`.
|
|
66
|
+
if
|
|
67
|
+
let defaultValue = property.defaultValue,
|
|
68
|
+
defaultValue == value(forKey: property.caLayerKeypath) as? ValueRepresentation
|
|
69
|
+
{
|
|
70
|
+
setValue(keyframeValue, forKeyPath: property.caLayerKeypath)
|
|
71
|
+
return nil
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
// Otherwise, we still need to create a `CAAnimation`, but we can
|
|
75
|
+
// create a simple `CABasicAnimation` that is still less expensive
|
|
76
|
+
// than computing a `CAKeyframeAnimation`.
|
|
77
|
+
let animation = CABasicAnimation(keyPath: property.caLayerKeypath)
|
|
78
|
+
animation.fromValue = keyframeValue
|
|
79
|
+
animation.toValue = keyframeValue
|
|
80
|
+
return animation
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
return try keyframeAnimation(
|
|
84
|
+
for: property,
|
|
85
|
+
keyframes: keyframes,
|
|
86
|
+
value: keyframeValueMapping,
|
|
87
|
+
context: context)
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
/// A `CAAnimation` that applies the custom value from the `AnyValueProvider`
|
|
91
|
+
/// registered for this specific property's `AnimationKeypath`,
|
|
92
|
+
/// if one has been registered using `AnimationView.setValueProvider(_:keypath:)`.
|
|
93
|
+
@nonobjc
|
|
94
|
+
private func customizedAnimation<ValueRepresentation>(
|
|
95
|
+
for property: LayerProperty<ValueRepresentation>,
|
|
96
|
+
context: LayerAnimationContext)
|
|
97
|
+
throws
|
|
98
|
+
-> CAPropertyAnimation?
|
|
99
|
+
{
|
|
100
|
+
guard
|
|
101
|
+
let customizableProperty = property.customizableProperty,
|
|
102
|
+
let customKeyframes = try context.valueProviderStore.customKeyframes(
|
|
103
|
+
of: customizableProperty,
|
|
104
|
+
for: AnimationKeypath(keys: context.currentKeypath.keys + customizableProperty.name.map { $0.rawValue }),
|
|
105
|
+
context: context)
|
|
106
|
+
else { return nil }
|
|
107
|
+
|
|
108
|
+
// Since custom animations are overriding an existing animation,
|
|
109
|
+
// we always have to create a CAKeyframeAnimation for these instead of
|
|
110
|
+
// letting `defaultAnimation(...)` try to apply the value using KVC.
|
|
111
|
+
return try keyframeAnimation(
|
|
112
|
+
for: property,
|
|
113
|
+
keyframes: customKeyframes.keyframes,
|
|
114
|
+
value: { $0 },
|
|
115
|
+
context: context)
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
/// Creates a `CAKeyframeAnimation` for the given keyframes
|
|
119
|
+
private func keyframeAnimation<KeyframeValue, ValueRepresentation>(
|
|
120
|
+
for property: LayerProperty<ValueRepresentation>,
|
|
121
|
+
keyframes: ContiguousArray<Keyframe<KeyframeValue>>,
|
|
122
|
+
value keyframeValueMapping: (KeyframeValue) throws -> ValueRepresentation,
|
|
123
|
+
context: LayerAnimationContext)
|
|
124
|
+
throws
|
|
125
|
+
-> CAKeyframeAnimation
|
|
126
|
+
{
|
|
127
|
+
// Convert the list of `Keyframe<T>` into
|
|
128
|
+
// the representation used by `CAKeyframeAnimation`
|
|
129
|
+
var keyTimes = keyframes.map { keyframeModel -> NSNumber in
|
|
130
|
+
NSNumber(value: Float(context.progressTime(for: keyframeModel.time)))
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
var timingFunctions = self.timingFunctions(for: keyframes)
|
|
134
|
+
let calculationMode = try self.calculationMode(for: keyframes, context: context)
|
|
135
|
+
|
|
136
|
+
let animation = CAKeyframeAnimation(keyPath: property.caLayerKeypath)
|
|
137
|
+
|
|
138
|
+
// Position animations define a `CGPath` curve that should be followed,
|
|
139
|
+
// instead of animating directly between keyframe point values.
|
|
140
|
+
if property.caLayerKeypath == LayerProperty<CGPoint>.position.caLayerKeypath {
|
|
141
|
+
animation.path = try path(keyframes: keyframes, value: { value in
|
|
142
|
+
guard let point = try keyframeValueMapping(value) as? CGPoint else {
|
|
143
|
+
context.logger.assertionFailure("Cannot create point from keyframe with value \(value)")
|
|
144
|
+
return .zero
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
return point
|
|
148
|
+
})
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
// All other types of keyframes provide individual values that are interpolated by Core Animation
|
|
152
|
+
else {
|
|
153
|
+
var values = try keyframes.map { keyframeModel in
|
|
154
|
+
try keyframeValueMapping(keyframeModel.value)
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
validate(
|
|
158
|
+
values: &values,
|
|
159
|
+
keyTimes: &keyTimes,
|
|
160
|
+
timingFunctions: &timingFunctions,
|
|
161
|
+
for: calculationMode,
|
|
162
|
+
context: context)
|
|
163
|
+
|
|
164
|
+
animation.values = values
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
animation.calculationMode = calculationMode
|
|
168
|
+
animation.keyTimes = keyTimes
|
|
169
|
+
animation.timingFunctions = timingFunctions
|
|
170
|
+
return animation
|
|
171
|
+
}
|
|
172
|
+
|
|
173
|
+
/// The `CAAnimationCalculationMode` that should be used for a `CAKeyframeAnimation`
|
|
174
|
+
/// animating the given keyframes
|
|
175
|
+
private func calculationMode<KeyframeValue>(
|
|
176
|
+
for keyframes: ContiguousArray<Keyframe<KeyframeValue>>,
|
|
177
|
+
context: LayerAnimationContext)
|
|
178
|
+
throws
|
|
179
|
+
-> CAAnimationCalculationMode
|
|
180
|
+
{
|
|
181
|
+
// Animations using `isHold` should use `CAAnimationCalculationMode.discrete`
|
|
182
|
+
//
|
|
183
|
+
// - Since we currently only create a single `CAKeyframeAnimation`,
|
|
184
|
+
// we can currently only correctly support animations where
|
|
185
|
+
// `isHold` is either always `true` or always `false`
|
|
186
|
+
// (this requirement doesn't apply to the first/last keyframes).
|
|
187
|
+
//
|
|
188
|
+
// - We should be able to support this in the future by creating multiple
|
|
189
|
+
// `CAKeyframeAnimation`s with different `calculationMode`s and
|
|
190
|
+
// playing them sequentially.
|
|
191
|
+
//
|
|
192
|
+
let intermediateKeyframes = keyframes.dropFirst().dropLast()
|
|
193
|
+
if intermediateKeyframes.contains(where: \.isHold) {
|
|
194
|
+
if intermediateKeyframes.allSatisfy(\.isHold) {
|
|
195
|
+
return .discrete
|
|
196
|
+
} else {
|
|
197
|
+
try context.logCompatibilityIssue("Mixed `isHold` / `!isHold` keyframes are currently unsupported")
|
|
198
|
+
}
|
|
199
|
+
}
|
|
200
|
+
|
|
201
|
+
return .linear
|
|
202
|
+
}
|
|
203
|
+
|
|
204
|
+
/// `timingFunctions` to apply to a `CAKeyframeAnimation` animating the given keyframes
|
|
205
|
+
private func timingFunctions<KeyframeValue>(
|
|
206
|
+
for keyframes: ContiguousArray<Keyframe<KeyframeValue>>)
|
|
207
|
+
-> [CAMediaTimingFunction]
|
|
208
|
+
{
|
|
209
|
+
// Compute the timing function between each keyframe and the subsequent keyframe
|
|
210
|
+
var timingFunctions: [CAMediaTimingFunction] = []
|
|
211
|
+
|
|
212
|
+
for (index, keyframe) in keyframes.enumerated()
|
|
213
|
+
where index != keyframes.indices.last
|
|
214
|
+
{
|
|
215
|
+
let nextKeyframe = keyframes[index + 1]
|
|
216
|
+
|
|
217
|
+
let controlPoint1 = keyframe.outTangent?.pointValue ?? .zero
|
|
218
|
+
let controlPoint2 = nextKeyframe.inTangent?.pointValue ?? CGPoint(x: 1, y: 1)
|
|
219
|
+
|
|
220
|
+
timingFunctions.append(CAMediaTimingFunction(
|
|
221
|
+
controlPoints:
|
|
222
|
+
Float(controlPoint1.x),
|
|
223
|
+
Float(controlPoint1.y),
|
|
224
|
+
Float(controlPoint2.x),
|
|
225
|
+
Float(controlPoint2.y)))
|
|
226
|
+
}
|
|
227
|
+
|
|
228
|
+
return timingFunctions
|
|
229
|
+
}
|
|
230
|
+
|
|
231
|
+
/// Creates a `CGPath` for the given `position` keyframes,
|
|
232
|
+
/// which accounts for `spatialInTangent`s and `spatialOutTangents`
|
|
233
|
+
private func path<KeyframeValue>(
|
|
234
|
+
keyframes positionKeyframes: ContiguousArray<Keyframe<KeyframeValue>>,
|
|
235
|
+
value keyframeValueMapping: (KeyframeValue) throws -> CGPoint) rethrows
|
|
236
|
+
-> CGPath {
|
|
237
|
+
let path = CGMutablePath()
|
|
238
|
+
|
|
239
|
+
for (index, keyframe) in positionKeyframes.enumerated() {
|
|
240
|
+
if index == positionKeyframes.indices.first {
|
|
241
|
+
path.move(to: try keyframeValueMapping(keyframe.value))
|
|
242
|
+
}
|
|
243
|
+
|
|
244
|
+
if index != positionKeyframes.indices.last {
|
|
245
|
+
let nextKeyframe = positionKeyframes[index + 1]
|
|
246
|
+
|
|
247
|
+
if
|
|
248
|
+
let controlPoint1 = keyframe.spatialOutTangent?.pointValue,
|
|
249
|
+
let controlPoint2 = nextKeyframe.spatialInTangent?.pointValue,
|
|
250
|
+
controlPoint1 != .zero,
|
|
251
|
+
controlPoint2 != .zero
|
|
252
|
+
{
|
|
253
|
+
path.addCurve(
|
|
254
|
+
to: try keyframeValueMapping(nextKeyframe.value),
|
|
255
|
+
control1: try keyframeValueMapping(keyframe.value) + controlPoint1,
|
|
256
|
+
control2: try keyframeValueMapping(nextKeyframe.value) + controlPoint2)
|
|
257
|
+
}
|
|
258
|
+
|
|
259
|
+
else {
|
|
260
|
+
path.addLine(to: try keyframeValueMapping(nextKeyframe.value))
|
|
261
|
+
}
|
|
262
|
+
}
|
|
263
|
+
}
|
|
264
|
+
|
|
265
|
+
path.closeSubpath()
|
|
266
|
+
return path
|
|
267
|
+
}
|
|
268
|
+
|
|
269
|
+
/// Validates that the requirements of the `CAKeyframeAnimation` API are met correctly
|
|
270
|
+
private func validate<ValueRepresentation>(
|
|
271
|
+
values: inout [ValueRepresentation],
|
|
272
|
+
keyTimes: inout [NSNumber],
|
|
273
|
+
timingFunctions: inout [CAMediaTimingFunction],
|
|
274
|
+
for calculationMode: CAAnimationCalculationMode,
|
|
275
|
+
context: LayerAnimationContext)
|
|
276
|
+
{
|
|
277
|
+
// Validate that we have correct start (0.0) and end (1.0) keyframes.
|
|
278
|
+
// From the documentation of `CAKeyframeAnimation.keyTimes`:
|
|
279
|
+
// - The first value in the `keyTimes` array must be 0.0 and the last value must be 1.0.
|
|
280
|
+
if keyTimes.first != 0.0 {
|
|
281
|
+
keyTimes.insert(0.0, at: 0)
|
|
282
|
+
values.insert(values[0], at: 0)
|
|
283
|
+
timingFunctions.insert(CAMediaTimingFunction(name: .linear), at: 0)
|
|
284
|
+
}
|
|
285
|
+
|
|
286
|
+
if keyTimes.last != 1.0 {
|
|
287
|
+
keyTimes.append(1.0)
|
|
288
|
+
values.append(values.last!)
|
|
289
|
+
timingFunctions.append(CAMediaTimingFunction(name: .linear))
|
|
290
|
+
}
|
|
291
|
+
|
|
292
|
+
switch calculationMode {
|
|
293
|
+
case .linear, .cubic:
|
|
294
|
+
// From the documentation of `CAKeyframeAnimation.keyTimes`:
|
|
295
|
+
// - The number of elements in the keyTimes array
|
|
296
|
+
// should match the number of elements in the values property
|
|
297
|
+
context.logger.assert(
|
|
298
|
+
values.count == keyTimes.count,
|
|
299
|
+
"`values.count` must exactly equal `keyTimes.count`")
|
|
300
|
+
|
|
301
|
+
context.logger.assert(
|
|
302
|
+
timingFunctions.count == (values.count - 1),
|
|
303
|
+
"`timingFunctions.count` must exactly equal `values.count - 1`")
|
|
304
|
+
|
|
305
|
+
case .discrete:
|
|
306
|
+
// From the documentation of `CAKeyframeAnimation.keyTimes`:
|
|
307
|
+
// - If the calculationMode is set to discrete... the keyTimes array
|
|
308
|
+
// should have one more entry than appears in the values array.
|
|
309
|
+
values.removeLast()
|
|
310
|
+
|
|
311
|
+
context.logger.assert(
|
|
312
|
+
keyTimes.count == values.count + 1,
|
|
313
|
+
"`keyTimes.count` must exactly equal `values.count + 1`")
|
|
314
|
+
|
|
315
|
+
default:
|
|
316
|
+
context.logger.assertionFailure("""
|
|
317
|
+
Unexpected keyframe calculation mode \(calculationMode)
|
|
318
|
+
""")
|
|
319
|
+
}
|
|
320
|
+
}
|
|
321
|
+
|
|
322
|
+
}
|