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
|
@@ -0,0 +1,246 @@
|
|
|
1
|
+
// Created by Cal Stephens on 1/7/22.
|
|
2
|
+
// Copyright © 2022 Airbnb Inc. All rights reserved.
|
|
3
|
+
|
|
4
|
+
import QuartzCore
|
|
5
|
+
|
|
6
|
+
extension CAShapeLayer {
|
|
7
|
+
/// Adds a `path` animation for the given `ShapeItem`
|
|
8
|
+
@nonobjc
|
|
9
|
+
func addAnimations(
|
|
10
|
+
for shape: ShapeItem,
|
|
11
|
+
context: LayerAnimationContext,
|
|
12
|
+
pathMultiplier: PathMultiplier) throws
|
|
13
|
+
{
|
|
14
|
+
switch shape {
|
|
15
|
+
case let customShape as Shape:
|
|
16
|
+
try addAnimations(for: customShape.path, context: context, pathMultiplier: pathMultiplier)
|
|
17
|
+
|
|
18
|
+
case let combinedShape as CombinedShapeItem:
|
|
19
|
+
try addAnimations(for: combinedShape, context: context, pathMultiplier: pathMultiplier)
|
|
20
|
+
|
|
21
|
+
case let ellipse as Ellipse:
|
|
22
|
+
try addAnimations(for: ellipse, context: context, pathMultiplier: pathMultiplier)
|
|
23
|
+
|
|
24
|
+
case let rectangle as Rectangle:
|
|
25
|
+
try addAnimations(for: rectangle, context: context, pathMultiplier: pathMultiplier)
|
|
26
|
+
|
|
27
|
+
case let star as Star:
|
|
28
|
+
try addAnimations(for: star, context: context, pathMultiplier: pathMultiplier)
|
|
29
|
+
|
|
30
|
+
default:
|
|
31
|
+
// None of the other `ShapeItem` subclasses draw a `path`
|
|
32
|
+
try context.logCompatibilityIssue("Unexpected shape type \(type(of: shape))")
|
|
33
|
+
return
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
/// Adds a `fillColor` animation for the given `Fill` object
|
|
38
|
+
@nonobjc
|
|
39
|
+
func addAnimations(for fill: Fill, context: LayerAnimationContext) throws {
|
|
40
|
+
fillRule = fill.fillRule.caFillRule
|
|
41
|
+
|
|
42
|
+
try addAnimation(
|
|
43
|
+
for: .fillColor,
|
|
44
|
+
keyframes: fill.color.keyframes,
|
|
45
|
+
value: \.cgColorValue,
|
|
46
|
+
context: context)
|
|
47
|
+
|
|
48
|
+
try addOpacityAnimation(for: fill, context: context)
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
/// Adds animations for `strokeStart` and `strokeEnd` from the given `Trim` object
|
|
52
|
+
@nonobjc
|
|
53
|
+
func addAnimations(for trim: Trim, context: LayerAnimationContext) throws -> PathMultiplier {
|
|
54
|
+
let (strokeStartKeyframes, strokeEndKeyframes, pathMultiplier) = try trim.caShapeLayerKeyframes(context: context)
|
|
55
|
+
|
|
56
|
+
try addAnimation(
|
|
57
|
+
for: .strokeStart,
|
|
58
|
+
keyframes: strokeStartKeyframes.keyframes,
|
|
59
|
+
value: { strokeStart in
|
|
60
|
+
// Lottie animation files express stoke trims as a numerical percentage value
|
|
61
|
+
// (e.g. 25%, 50%, 100%) so we divide by 100 to get the decimal values
|
|
62
|
+
// expected by Core Animation (e.g. 0.25, 0.5, 1.0).
|
|
63
|
+
CGFloat(strokeStart.cgFloatValue) / CGFloat(pathMultiplier) / 100
|
|
64
|
+
}, context: context)
|
|
65
|
+
|
|
66
|
+
try addAnimation(
|
|
67
|
+
for: .strokeEnd,
|
|
68
|
+
keyframes: strokeEndKeyframes.keyframes,
|
|
69
|
+
value: { strokeEnd in
|
|
70
|
+
// Lottie animation files express stoke trims as a numerical percentage value
|
|
71
|
+
// (e.g. 25%, 50%, 100%) so we divide by 100 to get the decimal values
|
|
72
|
+
// expected by Core Animation (e.g. 0.25, 0.5, 1.0).
|
|
73
|
+
CGFloat(strokeEnd.cgFloatValue) / CGFloat(pathMultiplier) / 100
|
|
74
|
+
}, context: context)
|
|
75
|
+
|
|
76
|
+
return pathMultiplier
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
/// The number of times that a `CGPath` needs to be duplicated in order to support the animation's `Trim` keyframes
|
|
81
|
+
typealias PathMultiplier = Int
|
|
82
|
+
|
|
83
|
+
extension Trim {
|
|
84
|
+
|
|
85
|
+
// MARK: Fileprivate
|
|
86
|
+
|
|
87
|
+
/// The `strokeStart` and `strokeEnd` keyframes to apply to a `CAShapeLayer`,
|
|
88
|
+
/// plus a `pathMultiplier` that should be applied to the layer's `path` so that
|
|
89
|
+
/// trim values larger than 100% can be displayed properly.
|
|
90
|
+
fileprivate func caShapeLayerKeyframes(context: LayerAnimationContext) throws
|
|
91
|
+
-> (strokeStart: KeyframeGroup<Vector1D>, strokeEnd: KeyframeGroup<Vector1D>, pathMultiplier: PathMultiplier)
|
|
92
|
+
{
|
|
93
|
+
let strokeStart: KeyframeGroup<Vector1D>
|
|
94
|
+
let strokeEnd: KeyframeGroup<Vector1D>
|
|
95
|
+
|
|
96
|
+
// CAShapeLayer requires strokeStart to be less than strokeEnd. This
|
|
97
|
+
// isn't required by the Lottie schema, so some animations may have
|
|
98
|
+
// strokeStart and strokeEnd flipped. If we detect this is the case,
|
|
99
|
+
// then swap them.
|
|
100
|
+
if startValueIsAlwaysGreaterThanEndValue() {
|
|
101
|
+
strokeStart = end
|
|
102
|
+
strokeEnd = start
|
|
103
|
+
} else {
|
|
104
|
+
strokeStart = start
|
|
105
|
+
strokeEnd = end
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
// If there are no offsets, then the stroke values can be used as-is
|
|
109
|
+
guard
|
|
110
|
+
!offset.keyframes.isEmpty,
|
|
111
|
+
offset.keyframes.contains(where: { $0.value.cgFloatValue != 0 })
|
|
112
|
+
else {
|
|
113
|
+
return (strokeStart, strokeEnd, 1)
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
// Otherwise, adjust the stroke values to account for the offsets
|
|
117
|
+
// 1. Interpolate the keyframes so they are all on a linear timing function
|
|
118
|
+
// 2. Merge by summing the stroke values with the offset values
|
|
119
|
+
let interpolatedStrokeStart = strokeStart.manuallyInterpolateKeyframes()
|
|
120
|
+
let interpolatedStrokeEnd = strokeEnd.manuallyInterpolateKeyframes()
|
|
121
|
+
let interpolatedStrokeOffset = offset.manuallyInterpolateKeyframes()
|
|
122
|
+
|
|
123
|
+
let adjustedStrokeStart = try adjustKeyframesForTrimOffsets(
|
|
124
|
+
strokeKeyframes: interpolatedStrokeStart,
|
|
125
|
+
offsetKeyframes: interpolatedStrokeOffset,
|
|
126
|
+
context: context)
|
|
127
|
+
|
|
128
|
+
let adjustedStrokeEnd = try adjustKeyframesForTrimOffsets(
|
|
129
|
+
strokeKeyframes: interpolatedStrokeEnd,
|
|
130
|
+
offsetKeyframes: interpolatedStrokeOffset,
|
|
131
|
+
context: context)
|
|
132
|
+
|
|
133
|
+
// If maximum stroke value is larger than 100%, then we have to create copies of the path
|
|
134
|
+
// so the total path length includes the maximum stroke
|
|
135
|
+
let maximumStroke = adjustedStrokeEnd.map { $0.value.cgFloatValue }.max() ?? 100
|
|
136
|
+
let pathMultiplier = Int(ceil(maximumStroke / 100.0))
|
|
137
|
+
|
|
138
|
+
return (
|
|
139
|
+
strokeStart: KeyframeGroup<Vector1D>(keyframes: adjustedStrokeStart),
|
|
140
|
+
strokeEnd: KeyframeGroup<Vector1D>(keyframes: adjustedStrokeEnd),
|
|
141
|
+
pathMultiplier: pathMultiplier)
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
// MARK: Private
|
|
145
|
+
|
|
146
|
+
/// Checks whether or not the value for `trim.start` is greater
|
|
147
|
+
/// than the value for every `trim.end` at every keyframe.
|
|
148
|
+
private func startValueIsAlwaysGreaterThanEndValue() -> Bool {
|
|
149
|
+
let keyframeTimes = Set(start.keyframes.map { $0.time } + end.keyframes.map { $0.time })
|
|
150
|
+
|
|
151
|
+
let startInterpolator = KeyframeInterpolator(keyframes: start.keyframes)
|
|
152
|
+
let endInterpolator = KeyframeInterpolator(keyframes: end.keyframes)
|
|
153
|
+
|
|
154
|
+
for keyframeTime in keyframeTimes {
|
|
155
|
+
guard
|
|
156
|
+
let startAtTime = startInterpolator.value(frame: keyframeTime) as? Vector1D,
|
|
157
|
+
let endAtTime = endInterpolator.value(frame: keyframeTime) as? Vector1D
|
|
158
|
+
else { continue }
|
|
159
|
+
|
|
160
|
+
if startAtTime.cgFloatValue < endAtTime.cgFloatValue {
|
|
161
|
+
return false
|
|
162
|
+
}
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
return true
|
|
166
|
+
}
|
|
167
|
+
|
|
168
|
+
/// Adjusted stroke keyframes to account for offset keyframes by merging them into a single keyframe collection
|
|
169
|
+
///
|
|
170
|
+
/// Since stroke keyframes and offset keyframes can be defined on different animation curves, they must be
|
|
171
|
+
/// manually interpolated prior to invoking this method. Manually interpolating the keyframes will redefine both
|
|
172
|
+
/// keyframe groups such that they can be interpolated linearly.
|
|
173
|
+
///
|
|
174
|
+
/// - Precondition: The keyframes must be interpolated using `KeyframeGroup.manuallyInterpolateKeyframes()`
|
|
175
|
+
private func adjustKeyframesForTrimOffsets(
|
|
176
|
+
strokeKeyframes: ContiguousArray<Keyframe<Vector1D>>,
|
|
177
|
+
offsetKeyframes: ContiguousArray<Keyframe<Vector1D>>,
|
|
178
|
+
context _: LayerAnimationContext) throws -> ContiguousArray<Keyframe<Vector1D>>
|
|
179
|
+
{
|
|
180
|
+
guard
|
|
181
|
+
!strokeKeyframes.isEmpty,
|
|
182
|
+
!offsetKeyframes.isEmpty
|
|
183
|
+
else {
|
|
184
|
+
return strokeKeyframes
|
|
185
|
+
}
|
|
186
|
+
|
|
187
|
+
// Map each time to its corresponding stroke/offset keyframe
|
|
188
|
+
var timeMap = [AnimationFrameTime: [Keyframe<Vector1D>?]]()
|
|
189
|
+
for stroke in strokeKeyframes {
|
|
190
|
+
timeMap[stroke.time] = [stroke, nil]
|
|
191
|
+
}
|
|
192
|
+
for offset in offsetKeyframes {
|
|
193
|
+
if var existing = timeMap[offset.time] {
|
|
194
|
+
existing[1] = offset
|
|
195
|
+
timeMap[offset.time] = existing
|
|
196
|
+
} else {
|
|
197
|
+
timeMap[offset.time] = [nil, offset]
|
|
198
|
+
}
|
|
199
|
+
}
|
|
200
|
+
|
|
201
|
+
// Each time will be mapped to a new, adjusted keyframe
|
|
202
|
+
var output = ContiguousArray<Keyframe<Vector1D>>()
|
|
203
|
+
var lastKeyframe: Keyframe<Vector1D>?
|
|
204
|
+
var lastOffset: Keyframe<Vector1D>?
|
|
205
|
+
|
|
206
|
+
for (time, values) in timeMap.sorted(by: { $0.0 < $1.0 }) {
|
|
207
|
+
// Extract keyframe/offset associated with this timestamp
|
|
208
|
+
let keyframe = values[0]
|
|
209
|
+
let offset = values[1]
|
|
210
|
+
lastKeyframe = keyframe ?? lastKeyframe
|
|
211
|
+
lastOffset = offset ?? lastOffset
|
|
212
|
+
|
|
213
|
+
guard let currentKeyframe = lastKeyframe else {
|
|
214
|
+
// No keyframes are output until the first keyframe occurs
|
|
215
|
+
continue
|
|
216
|
+
}
|
|
217
|
+
|
|
218
|
+
guard let currentOffset = lastOffset else {
|
|
219
|
+
// Scalar isHold keyframes are not output as they offset the offset keyframes
|
|
220
|
+
if !(strokeKeyframes.count == 1 && currentKeyframe.isHold) {
|
|
221
|
+
output.append(currentKeyframe)
|
|
222
|
+
}
|
|
223
|
+
continue
|
|
224
|
+
}
|
|
225
|
+
|
|
226
|
+
// Compute the adjusted value by converting the offset value to a stroke value
|
|
227
|
+
let strokeValue = currentKeyframe.value.value
|
|
228
|
+
let offsetValue = currentOffset.value.value
|
|
229
|
+
let adjustedValue = strokeValue + (offsetValue / 360 * 100)
|
|
230
|
+
|
|
231
|
+
// The tangent values are all `nil` as the keyframes should have been manually interpolated
|
|
232
|
+
let adjustedKeyframe = Keyframe<Vector1D>(
|
|
233
|
+
value: Vector1D(adjustedValue),
|
|
234
|
+
time: time,
|
|
235
|
+
isHold: currentKeyframe.isHold,
|
|
236
|
+
inTangent: nil,
|
|
237
|
+
outTangent: nil,
|
|
238
|
+
spatialInTangent: nil,
|
|
239
|
+
spatialOutTangent: nil)
|
|
240
|
+
|
|
241
|
+
output.append(adjustedKeyframe)
|
|
242
|
+
}
|
|
243
|
+
|
|
244
|
+
return output
|
|
245
|
+
}
|
|
246
|
+
}
|
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
// Created by Cal Stephens on 1/10/22.
|
|
2
|
+
// Copyright © 2022 Airbnb Inc. All rights reserved.
|
|
3
|
+
|
|
4
|
+
import QuartzCore
|
|
5
|
+
|
|
6
|
+
extension CAShapeLayer {
|
|
7
|
+
|
|
8
|
+
// MARK: Internal
|
|
9
|
+
|
|
10
|
+
/// Adds animations for the given `Rectangle` to this `CALayer`
|
|
11
|
+
@nonobjc
|
|
12
|
+
func addAnimations(
|
|
13
|
+
for star: Star,
|
|
14
|
+
context: LayerAnimationContext,
|
|
15
|
+
pathMultiplier: PathMultiplier)
|
|
16
|
+
throws
|
|
17
|
+
{
|
|
18
|
+
switch star.starType {
|
|
19
|
+
case .star:
|
|
20
|
+
try addStarAnimation(for: star, context: context, pathMultiplier: pathMultiplier)
|
|
21
|
+
case .polygon:
|
|
22
|
+
try addPolygonAnimation(for: star, context: context, pathMultiplier: pathMultiplier)
|
|
23
|
+
case .none:
|
|
24
|
+
break
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
// MARK: Private
|
|
29
|
+
|
|
30
|
+
@nonobjc
|
|
31
|
+
private func addStarAnimation(
|
|
32
|
+
for star: Star,
|
|
33
|
+
context: LayerAnimationContext,
|
|
34
|
+
pathMultiplier: PathMultiplier)
|
|
35
|
+
throws
|
|
36
|
+
{
|
|
37
|
+
try addAnimation(
|
|
38
|
+
for: .path,
|
|
39
|
+
keyframes: star.position.keyframes,
|
|
40
|
+
value: { position in
|
|
41
|
+
// We can only use one set of keyframes to animate a given CALayer keypath,
|
|
42
|
+
// so we currently animate `position` and ignore any other keyframes.
|
|
43
|
+
// TODO: Is there a way to support this properly?
|
|
44
|
+
BezierPath.star(
|
|
45
|
+
position: position.pointValue,
|
|
46
|
+
outerRadius: try star.outerRadius
|
|
47
|
+
.exactlyOneKeyframe(context: context, description: "outerRadius").value.cgFloatValue,
|
|
48
|
+
innerRadius: try star.innerRadius?
|
|
49
|
+
.exactlyOneKeyframe(context: context, description: "innerRadius").value.cgFloatValue ?? 0,
|
|
50
|
+
outerRoundedness: try star.outerRoundness
|
|
51
|
+
.exactlyOneKeyframe(context: context, description: "outerRoundness").value.cgFloatValue,
|
|
52
|
+
innerRoundedness: try star.innerRoundness?
|
|
53
|
+
.exactlyOneKeyframe(context: context, description: "innerRoundness").value.cgFloatValue ?? 0,
|
|
54
|
+
numberOfPoints: try star.points
|
|
55
|
+
.exactlyOneKeyframe(context: context, description: "points").value.cgFloatValue,
|
|
56
|
+
rotation: try star.rotation
|
|
57
|
+
.exactlyOneKeyframe(context: context, description: "rotation").value.cgFloatValue,
|
|
58
|
+
direction: star.direction)
|
|
59
|
+
.cgPath()
|
|
60
|
+
.duplicated(times: pathMultiplier)
|
|
61
|
+
},
|
|
62
|
+
context: context)
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
@nonobjc
|
|
66
|
+
private func addPolygonAnimation(
|
|
67
|
+
for star: Star,
|
|
68
|
+
context: LayerAnimationContext,
|
|
69
|
+
pathMultiplier: PathMultiplier)
|
|
70
|
+
throws
|
|
71
|
+
{
|
|
72
|
+
try addAnimation(
|
|
73
|
+
for: .path,
|
|
74
|
+
keyframes: star.position.keyframes,
|
|
75
|
+
value: { position in
|
|
76
|
+
// We can only use one set of keyframes to animate a given CALayer keypath,
|
|
77
|
+
// so we currently animate `position` and ignore any other keyframes.
|
|
78
|
+
// TODO: Is there a way to support this properly?
|
|
79
|
+
BezierPath.polygon(
|
|
80
|
+
position: position.pointValue,
|
|
81
|
+
numberOfPoints: try star.points
|
|
82
|
+
.exactlyOneKeyframe(context: context, description: "numberOfPoints").value.cgFloatValue,
|
|
83
|
+
outerRadius: try star.outerRadius
|
|
84
|
+
.exactlyOneKeyframe(context: context, description: "outerRadius").value.cgFloatValue,
|
|
85
|
+
outerRoundedness: try star.outerRoundness
|
|
86
|
+
.exactlyOneKeyframe(context: context, description: "outerRoundedness").value.cgFloatValue,
|
|
87
|
+
rotation: try star.rotation
|
|
88
|
+
.exactlyOneKeyframe(context: context, description: "rotation").value.cgFloatValue,
|
|
89
|
+
direction: star.direction)
|
|
90
|
+
.cgPath()
|
|
91
|
+
.duplicated(times: pathMultiplier)
|
|
92
|
+
},
|
|
93
|
+
context: context)
|
|
94
|
+
}
|
|
95
|
+
}
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
// Created by Cal Stephens on 2/10/22.
|
|
2
|
+
// Copyright © 2022 Airbnb Inc. All rights reserved.
|
|
3
|
+
|
|
4
|
+
import Foundation
|
|
5
|
+
import QuartzCore
|
|
6
|
+
|
|
7
|
+
// MARK: - StrokeShapeItem
|
|
8
|
+
|
|
9
|
+
/// A `ShapeItem` that represents a stroke
|
|
10
|
+
protocol StrokeShapeItem: OpacityAnimationModel {
|
|
11
|
+
var strokeColor: KeyframeGroup<Color>? { get }
|
|
12
|
+
var width: KeyframeGroup<Vector1D> { get }
|
|
13
|
+
var lineCap: LineCap { get }
|
|
14
|
+
var lineJoin: LineJoin { get }
|
|
15
|
+
var miterLimit: Double { get }
|
|
16
|
+
var dashPattern: [DashElement]? { get }
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
// MARK: - Stroke + StrokeShapeItem
|
|
20
|
+
|
|
21
|
+
extension Stroke: StrokeShapeItem {
|
|
22
|
+
var strokeColor: KeyframeGroup<Color>? { color }
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
// MARK: - GradientStroke + StrokeShapeItem
|
|
26
|
+
|
|
27
|
+
extension GradientStroke: StrokeShapeItem {
|
|
28
|
+
var strokeColor: KeyframeGroup<Color>? { nil }
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
// MARK: - CAShapeLayer + StrokeShapeItem
|
|
32
|
+
|
|
33
|
+
extension CAShapeLayer {
|
|
34
|
+
/// Adds animations for properties related to the given `Stroke` object (`strokeColor`, `lineWidth`, etc)
|
|
35
|
+
@nonobjc
|
|
36
|
+
func addStrokeAnimations(for stroke: StrokeShapeItem, context: LayerAnimationContext) throws {
|
|
37
|
+
lineJoin = stroke.lineJoin.caLineJoin
|
|
38
|
+
lineCap = stroke.lineCap.caLineCap
|
|
39
|
+
miterLimit = CGFloat(stroke.miterLimit)
|
|
40
|
+
|
|
41
|
+
if let strokeColor = stroke.strokeColor {
|
|
42
|
+
try addAnimation(
|
|
43
|
+
for: .strokeColor,
|
|
44
|
+
keyframes: strokeColor.keyframes,
|
|
45
|
+
value: \.cgColorValue,
|
|
46
|
+
context: context)
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
try addAnimation(
|
|
50
|
+
for: .lineWidth,
|
|
51
|
+
keyframes: stroke.width.keyframes,
|
|
52
|
+
value: \.cgFloatValue,
|
|
53
|
+
context: context)
|
|
54
|
+
|
|
55
|
+
try addOpacityAnimation(for: stroke, context: context)
|
|
56
|
+
|
|
57
|
+
if let (dashPattern, dashPhase) = stroke.dashPattern?.shapeLayerConfiguration {
|
|
58
|
+
lineDashPattern = try dashPattern.map {
|
|
59
|
+
try KeyframeGroup(keyframes: $0)
|
|
60
|
+
.exactlyOneKeyframe(context: context, description: "stroke dashPattern").value.cgFloatValue as NSNumber
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
try addAnimation(
|
|
64
|
+
for: .lineDashPhase,
|
|
65
|
+
keyframes: dashPhase,
|
|
66
|
+
value: \.cgFloatValue,
|
|
67
|
+
context: context)
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
}
|
|
@@ -0,0 +1,205 @@
|
|
|
1
|
+
// Created by Cal Stephens on 12/17/21.
|
|
2
|
+
// Copyright © 2021 Airbnb Inc. All rights reserved.
|
|
3
|
+
|
|
4
|
+
import QuartzCore
|
|
5
|
+
|
|
6
|
+
// MARK: - TransformModel
|
|
7
|
+
|
|
8
|
+
/// This protocol mirrors the interface of `Transform`,
|
|
9
|
+
/// but it also implemented by `ShapeTransform` to allow
|
|
10
|
+
/// both transform types to share the same animation implementation.
|
|
11
|
+
protocol TransformModel {
|
|
12
|
+
/// The anchor point of the transform.
|
|
13
|
+
var anchorPoint: KeyframeGroup<Vector3D> { get }
|
|
14
|
+
|
|
15
|
+
/// The position of the transform. This is nil if the position data was split.
|
|
16
|
+
var _position: KeyframeGroup<Vector3D>? { get }
|
|
17
|
+
|
|
18
|
+
/// The positionX of the transform. This is nil if the position property is set.
|
|
19
|
+
var _positionX: KeyframeGroup<Vector1D>? { get }
|
|
20
|
+
|
|
21
|
+
/// The positionY of the transform. This is nil if the position property is set.
|
|
22
|
+
var _positionY: KeyframeGroup<Vector1D>? { get }
|
|
23
|
+
|
|
24
|
+
/// The scale of the transform
|
|
25
|
+
var scale: KeyframeGroup<Vector3D> { get }
|
|
26
|
+
|
|
27
|
+
/// The rotation of the transform. Note: This is single dimensional rotation.
|
|
28
|
+
var rotation: KeyframeGroup<Vector1D> { get }
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
// MARK: - Transform + TransformModel
|
|
32
|
+
|
|
33
|
+
extension Transform: TransformModel {
|
|
34
|
+
var _position: KeyframeGroup<Vector3D>? { position }
|
|
35
|
+
var _positionX: KeyframeGroup<Vector1D>? { positionX }
|
|
36
|
+
var _positionY: KeyframeGroup<Vector1D>? { positionY }
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
// MARK: - ShapeTransform + TransformModel
|
|
40
|
+
|
|
41
|
+
extension ShapeTransform: TransformModel {
|
|
42
|
+
var anchorPoint: KeyframeGroup<Vector3D> { anchor }
|
|
43
|
+
var _position: KeyframeGroup<Vector3D>? { position }
|
|
44
|
+
var _positionX: KeyframeGroup<Vector1D>? { nil }
|
|
45
|
+
var _positionY: KeyframeGroup<Vector1D>? { nil }
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
// MARK: - CALayer + TransformModel
|
|
49
|
+
|
|
50
|
+
extension CALayer {
|
|
51
|
+
|
|
52
|
+
// MARK: Internal
|
|
53
|
+
|
|
54
|
+
/// Adds transform-related animations from the given `TransformModel` to this layer
|
|
55
|
+
/// - This _doesn't_ apply `transform.opacity`, which has to be handled separately
|
|
56
|
+
/// since child layers don't inherit the `opacity` of their parent.
|
|
57
|
+
@nonobjc
|
|
58
|
+
func addTransformAnimations(for transformModel: TransformModel, context: LayerAnimationContext) throws {
|
|
59
|
+
try addPositionAnimations(from: transformModel, context: context)
|
|
60
|
+
try addAnchorPointAnimation(from: transformModel, context: context)
|
|
61
|
+
try addScaleAnimations(from: transformModel, context: context)
|
|
62
|
+
try addRotationAnimation(from: transformModel, context: context)
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
// MARK: Private
|
|
66
|
+
|
|
67
|
+
@nonobjc
|
|
68
|
+
private func addPositionAnimations(
|
|
69
|
+
from transformModel: TransformModel,
|
|
70
|
+
context: LayerAnimationContext)
|
|
71
|
+
throws
|
|
72
|
+
{
|
|
73
|
+
if let positionKeyframes = transformModel._position?.keyframes {
|
|
74
|
+
try addAnimation(
|
|
75
|
+
for: .position,
|
|
76
|
+
keyframes: positionKeyframes,
|
|
77
|
+
value: \.pointValue,
|
|
78
|
+
context: context)
|
|
79
|
+
} else if
|
|
80
|
+
let xKeyframes = transformModel._positionX?.keyframes,
|
|
81
|
+
let yKeyframes = transformModel._positionY?.keyframes
|
|
82
|
+
{
|
|
83
|
+
try addAnimation(
|
|
84
|
+
for: .positionX,
|
|
85
|
+
keyframes: xKeyframes,
|
|
86
|
+
value: \.cgFloatValue,
|
|
87
|
+
context: context)
|
|
88
|
+
|
|
89
|
+
try addAnimation(
|
|
90
|
+
for: .positionY,
|
|
91
|
+
keyframes: yKeyframes,
|
|
92
|
+
value: \.cgFloatValue,
|
|
93
|
+
context: context)
|
|
94
|
+
} else {
|
|
95
|
+
try context.logCompatibilityIssue("""
|
|
96
|
+
`Transform` values must provide either `position` or `positionX` / `positionY` keyframes
|
|
97
|
+
""")
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
@nonobjc
|
|
102
|
+
private func addAnchorPointAnimation(
|
|
103
|
+
from transformModel: TransformModel,
|
|
104
|
+
context: LayerAnimationContext)
|
|
105
|
+
throws
|
|
106
|
+
{
|
|
107
|
+
try addAnimation(
|
|
108
|
+
for: .anchorPoint,
|
|
109
|
+
keyframes: transformModel.anchorPoint.keyframes,
|
|
110
|
+
value: { absoluteAnchorPoint in
|
|
111
|
+
guard bounds.width > 0, bounds.height > 0 else {
|
|
112
|
+
context.logger.assertionFailure("Size must be non-zero before an animation can be played")
|
|
113
|
+
return .zero
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
// Lottie animation files express anchorPoint as an absolute point value,
|
|
117
|
+
// so we have to divide by the width/height of this layer to get the
|
|
118
|
+
// relative decimal values expected by Core Animation.
|
|
119
|
+
return CGPoint(
|
|
120
|
+
x: CGFloat(absoluteAnchorPoint.x) / bounds.width,
|
|
121
|
+
y: CGFloat(absoluteAnchorPoint.y) / bounds.height)
|
|
122
|
+
},
|
|
123
|
+
context: context)
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
@nonobjc
|
|
127
|
+
private func addScaleAnimations(
|
|
128
|
+
from transformModel: TransformModel,
|
|
129
|
+
context: LayerAnimationContext)
|
|
130
|
+
throws
|
|
131
|
+
{
|
|
132
|
+
try addAnimation(
|
|
133
|
+
for: .scaleX,
|
|
134
|
+
keyframes: transformModel.scale.keyframes,
|
|
135
|
+
value: { scale in
|
|
136
|
+
// Lottie animation files express scale as a numerical percentage value
|
|
137
|
+
// (e.g. 50%, 100%, 200%) so we divide by 100 to get the decimal values
|
|
138
|
+
// expected by Core Animation (e.g. 0.5, 1.0, 2.0).
|
|
139
|
+
// - Negative `scale.x` values aren't applied correctly by Core Animation.
|
|
140
|
+
// This appears to be because we animate `transform.scale.x` and `transform.scale.y`
|
|
141
|
+
// as separate `CAKeyframeAnimation`s instead of using a single animation of `transform` itself.
|
|
142
|
+
// https://openradar.appspot.com/FB9862872
|
|
143
|
+
// - To work around this, we set up a `rotationY` animation below
|
|
144
|
+
// to flip the view horizontally, which gives us the desired effect.
|
|
145
|
+
abs(CGFloat(scale.x) / 100)
|
|
146
|
+
},
|
|
147
|
+
context: context)
|
|
148
|
+
|
|
149
|
+
// When `scale.x` is negative, we have to rotate the view
|
|
150
|
+
// half way around the y axis to flip it horizontally.
|
|
151
|
+
// - We don't do this in snapshot tests because it breaks the tests
|
|
152
|
+
// in surprising ways that don't happen at runtime. Definitely not ideal.
|
|
153
|
+
if TestHelpers.snapshotTestsAreRunning {
|
|
154
|
+
if transformModel.scale.keyframes.contains(where: { $0.value.x < 0 }) {
|
|
155
|
+
context.logger.warn("""
|
|
156
|
+
Negative `scale.x` values are not displayed correctly in snapshot tests
|
|
157
|
+
""")
|
|
158
|
+
}
|
|
159
|
+
} else {
|
|
160
|
+
try addAnimation(
|
|
161
|
+
for: .rotationY,
|
|
162
|
+
keyframes: transformModel.scale.keyframes,
|
|
163
|
+
value: { scale in
|
|
164
|
+
if scale.x < 0 {
|
|
165
|
+
return .pi
|
|
166
|
+
} else {
|
|
167
|
+
return 0
|
|
168
|
+
}
|
|
169
|
+
},
|
|
170
|
+
context: context)
|
|
171
|
+
}
|
|
172
|
+
|
|
173
|
+
try addAnimation(
|
|
174
|
+
for: .scaleY,
|
|
175
|
+
keyframes: transformModel.scale.keyframes,
|
|
176
|
+
value: { scale in
|
|
177
|
+
// Lottie animation files express scale as a numerical percentage value
|
|
178
|
+
// (e.g. 50%, 100%, 200%) so we divide by 100 to get the decimal values
|
|
179
|
+
// expected by Core Animation (e.g. 0.5, 1.0, 2.0).
|
|
180
|
+
// - Negative `scaleY` values are correctly applied (they flip the view
|
|
181
|
+
// vertically), so we don't have to apply an additional rotation animation
|
|
182
|
+
// like we do for `scaleX`.
|
|
183
|
+
CGFloat(scale.y) / 100
|
|
184
|
+
},
|
|
185
|
+
context: context)
|
|
186
|
+
}
|
|
187
|
+
|
|
188
|
+
private func addRotationAnimation(
|
|
189
|
+
from transformModel: TransformModel,
|
|
190
|
+
context: LayerAnimationContext)
|
|
191
|
+
throws
|
|
192
|
+
{
|
|
193
|
+
try addAnimation(
|
|
194
|
+
for: .rotation,
|
|
195
|
+
keyframes: transformModel.rotation.keyframes,
|
|
196
|
+
value: { rotationDegrees in
|
|
197
|
+
// Lottie animation files express rotation in degrees
|
|
198
|
+
// (e.g. 90º, 180º, 360º) so we covert to radians to get the
|
|
199
|
+
// values expected by Core Animation (e.g. π/2, π, 2π)
|
|
200
|
+
rotationDegrees.cgFloatValue * .pi / 180
|
|
201
|
+
},
|
|
202
|
+
context: context)
|
|
203
|
+
}
|
|
204
|
+
|
|
205
|
+
}
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
// Created by Cal Stephens on 12/21/21.
|
|
2
|
+
// Copyright © 2021 Airbnb Inc. All rights reserved.
|
|
3
|
+
|
|
4
|
+
import QuartzCore
|
|
5
|
+
|
|
6
|
+
extension CALayer {
|
|
7
|
+
/// Adds an animation for the given `inTime` and `outTime` to this `CALayer`
|
|
8
|
+
@nonobjc
|
|
9
|
+
func addVisibilityAnimation(
|
|
10
|
+
inFrame: AnimationFrameTime,
|
|
11
|
+
outFrame: AnimationFrameTime,
|
|
12
|
+
context: LayerAnimationContext)
|
|
13
|
+
{
|
|
14
|
+
let animation = CAKeyframeAnimation(keyPath: #keyPath(isHidden))
|
|
15
|
+
animation.calculationMode = .discrete
|
|
16
|
+
|
|
17
|
+
animation.values = [
|
|
18
|
+
true, // hidden, before `inFrame`
|
|
19
|
+
false, // visible
|
|
20
|
+
true, // hidden, after `outFrame`
|
|
21
|
+
]
|
|
22
|
+
|
|
23
|
+
// From the documentation of `keyTimes`:
|
|
24
|
+
// - If the calculationMode is set to discrete, the first value in the array
|
|
25
|
+
// must be 0.0 and the last value must be 1.0. The array should have one more
|
|
26
|
+
// entry than appears in the values array. For example, if there are two values,
|
|
27
|
+
// there should be three key times.
|
|
28
|
+
animation.keyTimes = [
|
|
29
|
+
NSNumber(value: 0.0),
|
|
30
|
+
NSNumber(value: max(Double(context.progressTime(for: inFrame)), 0)),
|
|
31
|
+
NSNumber(value: min(Double(context.progressTime(for: outFrame)), 1)),
|
|
32
|
+
NSNumber(value: 1.0),
|
|
33
|
+
]
|
|
34
|
+
|
|
35
|
+
add(animation, timedWith: context)
|
|
36
|
+
}
|
|
37
|
+
}
|