lottie-ios 3.2.0 → 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/FUNDING.yml +1 -1
- 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 +94 -86
- 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 +59 -42
- 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 +46 -35
- package/{lottie-swift/src/Private/LayerContainers/AnimationContainer.swift → Sources/Private/MainThread/LayerContainers/MainThreadAnimationLayer.swift} +203 -135
- 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} +122 -106
- 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 +7 -7
- 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 +81 -80
- 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 -24
- package/{lottie-swift/src/Private → Sources/Private/MainThread}/NodeRenderSystem/RenderLayers/ShapeRenderLayer.swift +32 -27
- 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 +37 -27
- package/{lottie-swift/src → Sources}/Public/iOS/AnimatedControl.swift +103 -92
- package/{lottie-swift/src → Sources}/Public/iOS/AnimatedSwitch.swift +124 -93
- package/{lottie-swift/src → Sources}/Public/iOS/AnimationSubview.swift +4 -4
- package/Sources/Public/iOS/AnimationViewBase.swift +78 -0
- package/{lottie-swift/src → Sources}/Public/iOS/BundleImageProvider.swift +38 -35
- package/{lottie-swift/src → Sources}/Public/iOS/Compatibility/CompatibleAnimationKeypath.swift +5 -1
- package/{lottie-swift/src → Sources}/Public/iOS/Compatibility/CompatibleAnimationView.swift +39 -30
- package/{lottie-swift/src → Sources}/Public/iOS/FilepathImageProvider.swift +25 -21
- package/{lottie-swift/src → Sources}/Public/iOS/UIColorExtension.swift +5 -5
- 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 -1007
- 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,305 @@
|
|
|
1
|
+
// Created by Cal Stephens on 12/14/21.
|
|
2
|
+
// Copyright © 2021 Airbnb Inc. All rights reserved.
|
|
3
|
+
|
|
4
|
+
import QuartzCore
|
|
5
|
+
|
|
6
|
+
// MARK: - ShapeLayer
|
|
7
|
+
|
|
8
|
+
/// The CALayer type responsible for rendering `ShapeLayerModel`s
|
|
9
|
+
final class ShapeLayer: BaseCompositionLayer {
|
|
10
|
+
|
|
11
|
+
// MARK: Lifecycle
|
|
12
|
+
|
|
13
|
+
init(shapeLayer: ShapeLayerModel, context: LayerContext) throws {
|
|
14
|
+
self.shapeLayer = shapeLayer
|
|
15
|
+
super.init(layerModel: shapeLayer)
|
|
16
|
+
try setupGroups(from: shapeLayer.items, parentGroup: nil, context: context)
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
required init?(coder _: NSCoder) {
|
|
20
|
+
fatalError("init(coder:) has not been implemented")
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
/// Called by CoreAnimation to create a shadow copy of this layer
|
|
24
|
+
/// More details: https://developer.apple.com/documentation/quartzcore/calayer/1410842-init
|
|
25
|
+
override init(layer: Any) {
|
|
26
|
+
guard let typedLayer = layer as? Self else {
|
|
27
|
+
fatalError("\(Self.self).init(layer:) incorrectly called with \(type(of: layer))")
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
shapeLayer = typedLayer.shapeLayer
|
|
31
|
+
super.init(layer: typedLayer)
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
// MARK: Private
|
|
35
|
+
|
|
36
|
+
private let shapeLayer: ShapeLayerModel
|
|
37
|
+
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
// MARK: - GroupLayer
|
|
41
|
+
|
|
42
|
+
/// The CALayer type responsible for rendering `Group`s
|
|
43
|
+
final class GroupLayer: BaseAnimationLayer {
|
|
44
|
+
|
|
45
|
+
// MARK: Lifecycle
|
|
46
|
+
|
|
47
|
+
init(group: Group, inheritedItems: [ShapeItemLayer.Item], context: LayerContext) throws {
|
|
48
|
+
self.group = group
|
|
49
|
+
self.inheritedItems = inheritedItems
|
|
50
|
+
super.init()
|
|
51
|
+
try setupLayerHierarchy(context: context)
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
required init?(coder _: NSCoder) {
|
|
55
|
+
fatalError("init(coder:) has not been implemented")
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
/// Called by CoreAnimation to create a shadow copy of this layer
|
|
59
|
+
/// More details: https://developer.apple.com/documentation/quartzcore/calayer/1410842-init
|
|
60
|
+
override init(layer: Any) {
|
|
61
|
+
guard let typedLayer = layer as? Self else {
|
|
62
|
+
fatalError("\(Self.self).init(layer:) incorrectly called with \(type(of: layer))")
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
group = typedLayer.group
|
|
66
|
+
inheritedItems = typedLayer.inheritedItems
|
|
67
|
+
super.init(layer: typedLayer)
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
// MARK: Internal
|
|
71
|
+
|
|
72
|
+
override func setupAnimations(context: LayerAnimationContext) throws {
|
|
73
|
+
try super.setupAnimations(context: context)
|
|
74
|
+
|
|
75
|
+
if let (shapeTransform, context) = nonGroupItems.first(ShapeTransform.self, context: context) {
|
|
76
|
+
try addTransformAnimations(for: shapeTransform, context: context)
|
|
77
|
+
try addOpacityAnimation(for: shapeTransform, context: context)
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
// MARK: Private
|
|
82
|
+
|
|
83
|
+
private let group: Group
|
|
84
|
+
|
|
85
|
+
/// `ShapeItem`s that were listed in the parent's `items: [ShapeItem]` array
|
|
86
|
+
/// - This layer's parent is either the root `ShapeLayerModel` or some other `Group`
|
|
87
|
+
private let inheritedItems: [ShapeItemLayer.Item]
|
|
88
|
+
|
|
89
|
+
/// `ShapeItem`s (other than nested `Group`s) that are included in this group
|
|
90
|
+
private lazy var nonGroupItems = group.items
|
|
91
|
+
.filter { !($0 is Group) }
|
|
92
|
+
.map { ShapeItemLayer.Item(item: $0, parentGroup: group) }
|
|
93
|
+
+ inheritedItems
|
|
94
|
+
|
|
95
|
+
private func setupLayerHierarchy(context: LayerContext) throws {
|
|
96
|
+
// Groups can contain other groups, so we may have to continue
|
|
97
|
+
// recursively creating more `GroupLayer`s
|
|
98
|
+
try setupGroups(from: group.items, parentGroup: group, context: context)
|
|
99
|
+
|
|
100
|
+
// Create `ShapeItemLayer`s for each subgroup of shapes that should be rendered as a single unit
|
|
101
|
+
// - These groups are listed from front-to-back, so we have to add the sublayers in reverse order
|
|
102
|
+
for shapeRenderGroup in nonGroupItems.shapeRenderGroups.reversed() {
|
|
103
|
+
// If all of the path-drawing `ShapeItem`s have keyframes with the same timing information,
|
|
104
|
+
// we can combine the `[KeyframeGroup<BezierPath>]` (which have to animate in separate layers)
|
|
105
|
+
// into a single `KeyframeGroup<[BezierPath]>`, which can be combined into a single CGPath animation.
|
|
106
|
+
//
|
|
107
|
+
// This is how Groups with multiple path-drawing items are supposed to be rendered,
|
|
108
|
+
// because combining multiple paths into a single `CGPath` (instead of rendering them in separate layers)
|
|
109
|
+
// allows `CAShapeLayerFillRule.evenOdd` to be applied if the paths overlap. We just can't do this
|
|
110
|
+
// in all cases, due to limitations of Core Animation.
|
|
111
|
+
if
|
|
112
|
+
shapeRenderGroup.pathItems.count > 1,
|
|
113
|
+
let combinedShapeKeyframes = Keyframes.combinedIfPossible(
|
|
114
|
+
shapeRenderGroup.pathItems.map { ($0.item as? Shape)?.path }),
|
|
115
|
+
// `Trim`s are currently only applied correctly using individual `ShapeItemLayer`s,
|
|
116
|
+
// because each path has to be trimmed separately.
|
|
117
|
+
!shapeRenderGroup.otherItems.contains(where: { $0.item is Trim })
|
|
118
|
+
{
|
|
119
|
+
let combinedShape = CombinedShapeItem(
|
|
120
|
+
shapes: combinedShapeKeyframes,
|
|
121
|
+
name: group.name)
|
|
122
|
+
|
|
123
|
+
let sublayer = try ShapeItemLayer(
|
|
124
|
+
shape: ShapeItemLayer.Item(item: combinedShape, parentGroup: group),
|
|
125
|
+
otherItems: shapeRenderGroup.otherItems,
|
|
126
|
+
context: context)
|
|
127
|
+
|
|
128
|
+
addSublayer(sublayer)
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
// Otherwise, if each `ShapeItem` that draws a `GGPath` animates independently,
|
|
132
|
+
// we have to create a separate `ShapeItemLayer` for each one.
|
|
133
|
+
else {
|
|
134
|
+
for pathDrawingItem in shapeRenderGroup.pathItems {
|
|
135
|
+
let sublayer = try ShapeItemLayer(
|
|
136
|
+
shape: pathDrawingItem,
|
|
137
|
+
otherItems: shapeRenderGroup.otherItems,
|
|
138
|
+
context: context)
|
|
139
|
+
|
|
140
|
+
addSublayer(sublayer)
|
|
141
|
+
}
|
|
142
|
+
}
|
|
143
|
+
}
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
extension CALayer {
|
|
149
|
+
/// Sets up `GroupLayer`s for each `Group` in the given list of `ShapeItem`s
|
|
150
|
+
/// - Each `Group` item becomes its own `GroupLayer` sublayer.
|
|
151
|
+
/// - Other `ShapeItem` are applied to all sublayers
|
|
152
|
+
fileprivate func setupGroups(from items: [ShapeItem], parentGroup: Group?, context: LayerContext) throws {
|
|
153
|
+
let (groupItems, otherItems) = items.grouped(by: { $0 is Group })
|
|
154
|
+
|
|
155
|
+
// Groups are listed from front to back,
|
|
156
|
+
// but `CALayer.sublayers` are listed from back to front.
|
|
157
|
+
let groupsInZAxisOrder = groupItems.reversed()
|
|
158
|
+
|
|
159
|
+
for group in groupsInZAxisOrder {
|
|
160
|
+
guard let group = group as? Group else { continue }
|
|
161
|
+
|
|
162
|
+
// `ShapeItem`s either draw a path, or modify how a path is rendered.
|
|
163
|
+
// - If this group doesn't have any items that draw a path, then its
|
|
164
|
+
// items are applied to all of this groups children.
|
|
165
|
+
let inheritedItems: [ShapeItemLayer.Item]
|
|
166
|
+
if !otherItems.contains(where: { $0.drawsCGPath }) {
|
|
167
|
+
inheritedItems = otherItems.map {
|
|
168
|
+
ShapeItemLayer.Item(item: $0, parentGroup: parentGroup)
|
|
169
|
+
}
|
|
170
|
+
} else {
|
|
171
|
+
inheritedItems = []
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
let groupLayer = try GroupLayer(
|
|
175
|
+
group: group,
|
|
176
|
+
inheritedItems: inheritedItems,
|
|
177
|
+
context: context)
|
|
178
|
+
|
|
179
|
+
addSublayer(groupLayer)
|
|
180
|
+
}
|
|
181
|
+
}
|
|
182
|
+
}
|
|
183
|
+
|
|
184
|
+
extension ShapeItem {
|
|
185
|
+
/// Whether or not this `ShapeItem` is responsible for rendering a `CGPath`
|
|
186
|
+
var drawsCGPath: Bool {
|
|
187
|
+
switch type {
|
|
188
|
+
case .ellipse, .rectangle, .shape, .star:
|
|
189
|
+
return true
|
|
190
|
+
|
|
191
|
+
case .fill, .gradientFill, .group, .gradientStroke, .merge,
|
|
192
|
+
.repeater, .round, .stroke, .trim, .transform, .unknown:
|
|
193
|
+
return false
|
|
194
|
+
}
|
|
195
|
+
}
|
|
196
|
+
|
|
197
|
+
/// Whether or not this `ShapeItem` provides a fill for a set of shapes
|
|
198
|
+
var isFill: Bool {
|
|
199
|
+
switch type {
|
|
200
|
+
case .fill, .gradientFill:
|
|
201
|
+
return true
|
|
202
|
+
|
|
203
|
+
case .ellipse, .rectangle, .shape, .star, .group, .gradientStroke,
|
|
204
|
+
.merge, .repeater, .round, .stroke, .trim, .transform, .unknown:
|
|
205
|
+
return false
|
|
206
|
+
}
|
|
207
|
+
}
|
|
208
|
+
|
|
209
|
+
/// Whether or not this `ShapeItem` provides a stroke for a set of shapes
|
|
210
|
+
var isStroke: Bool {
|
|
211
|
+
switch type {
|
|
212
|
+
case .stroke, .gradientStroke:
|
|
213
|
+
return true
|
|
214
|
+
|
|
215
|
+
case .ellipse, .rectangle, .shape, .star, .group, .gradientFill,
|
|
216
|
+
.merge, .repeater, .round, .fill, .trim, .transform, .unknown:
|
|
217
|
+
return false
|
|
218
|
+
}
|
|
219
|
+
}
|
|
220
|
+
}
|
|
221
|
+
|
|
222
|
+
extension Collection {
|
|
223
|
+
/// Splits this collection into two groups, based on the given predicate
|
|
224
|
+
func grouped(by predicate: (Element) -> Bool) -> (trueElements: [Element], falseElements: [Element]) {
|
|
225
|
+
var trueElements = [Element]()
|
|
226
|
+
var falseElements = [Element]()
|
|
227
|
+
|
|
228
|
+
for element in self {
|
|
229
|
+
if predicate(element) {
|
|
230
|
+
trueElements.append(element)
|
|
231
|
+
} else {
|
|
232
|
+
falseElements.append(element)
|
|
233
|
+
}
|
|
234
|
+
}
|
|
235
|
+
|
|
236
|
+
return (trueElements, falseElements)
|
|
237
|
+
}
|
|
238
|
+
}
|
|
239
|
+
|
|
240
|
+
// MARK: - ShapeRenderGroup
|
|
241
|
+
|
|
242
|
+
/// A group of `ShapeItem`s that should be rendered together as a single unit
|
|
243
|
+
struct ShapeRenderGroup {
|
|
244
|
+
/// The items in this group that render `CGPath`s
|
|
245
|
+
var pathItems: [ShapeItemLayer.Item] = []
|
|
246
|
+
/// Shape items that modify the appearance of the shapes rendered by this group
|
|
247
|
+
var otherItems: [ShapeItemLayer.Item] = []
|
|
248
|
+
}
|
|
249
|
+
|
|
250
|
+
extension Array where Element == ShapeItemLayer.Item {
|
|
251
|
+
/// Splits this list of `ShapeItem`s into groups that should be rendered together as individual units
|
|
252
|
+
var shapeRenderGroups: [ShapeRenderGroup] {
|
|
253
|
+
var renderGroups = [ShapeRenderGroup()]
|
|
254
|
+
|
|
255
|
+
for item in self {
|
|
256
|
+
// `renderGroups` is non-empty, so is guaranteed to have a valid end index
|
|
257
|
+
let lastIndex = renderGroups.indices.last!
|
|
258
|
+
|
|
259
|
+
if item.item.drawsCGPath {
|
|
260
|
+
renderGroups[lastIndex].pathItems.append(item)
|
|
261
|
+
}
|
|
262
|
+
|
|
263
|
+
// `Fill` items are unique, because they specifically only apply to _previous_ shapes in a `Group`
|
|
264
|
+
// - For example, with [Rectangle, Fill(Red), Circle, Fill(Blue)], the Rectangle should be Red
|
|
265
|
+
// but the Circle should be Blue.
|
|
266
|
+
// - To handle this, we create a new `ShapeRenderGroup` when we encounter a `Fill` item
|
|
267
|
+
else if item.item.isFill {
|
|
268
|
+
renderGroups[lastIndex].otherItems.append(item)
|
|
269
|
+
renderGroups.append(ShapeRenderGroup())
|
|
270
|
+
}
|
|
271
|
+
|
|
272
|
+
// Other items in the list are applied to all subgroups
|
|
273
|
+
else {
|
|
274
|
+
for index in renderGroups.indices {
|
|
275
|
+
renderGroups[index].otherItems.append(item)
|
|
276
|
+
}
|
|
277
|
+
}
|
|
278
|
+
}
|
|
279
|
+
|
|
280
|
+
// `Fill` and `Stroke` items have an `alpha` property that can be animated separately,
|
|
281
|
+
// but each layer only has a single `opacity` property, so we have to create
|
|
282
|
+
// separate layers / render groups for each of these if necessary.
|
|
283
|
+
return renderGroups.flatMap { group -> [ShapeRenderGroup] in
|
|
284
|
+
let (strokesAndFills, otherItems) = group.otherItems.grouped(by: { $0.item.isFill || $0.item.isStroke })
|
|
285
|
+
|
|
286
|
+
// However, if all of the strokes / fills have the exact same opacity animation configuration,
|
|
287
|
+
// then we can continue using a single layer / render group.
|
|
288
|
+
let allAlphaAnimationsAreIdentical = strokesAndFills.allSatisfy { item in
|
|
289
|
+
(item.item as? OpacityAnimationModel)?.opacity
|
|
290
|
+
== (strokesAndFills.first?.item as? OpacityAnimationModel)?.opacity
|
|
291
|
+
}
|
|
292
|
+
|
|
293
|
+
if allAlphaAnimationsAreIdentical {
|
|
294
|
+
return [group]
|
|
295
|
+
}
|
|
296
|
+
|
|
297
|
+
// Create a new group for each stroke / fill
|
|
298
|
+
return strokesAndFills.map { strokeOrFill in
|
|
299
|
+
ShapeRenderGroup(
|
|
300
|
+
pathItems: group.pathItems,
|
|
301
|
+
otherItems: [strokeOrFill] + otherItems)
|
|
302
|
+
}
|
|
303
|
+
}
|
|
304
|
+
}
|
|
305
|
+
}
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
// Created by Cal Stephens on 12/13/21.
|
|
2
|
+
// Copyright © 2021 Airbnb Inc. All rights reserved.
|
|
3
|
+
|
|
4
|
+
import QuartzCore
|
|
5
|
+
|
|
6
|
+
// MARK: - SolidLayer
|
|
7
|
+
|
|
8
|
+
final class SolidLayer: BaseCompositionLayer {
|
|
9
|
+
|
|
10
|
+
// MARK: Lifecycle
|
|
11
|
+
|
|
12
|
+
init(_ solidLayer: SolidLayerModel) {
|
|
13
|
+
self.solidLayer = solidLayer
|
|
14
|
+
super.init(layerModel: solidLayer)
|
|
15
|
+
setupContentLayer()
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
required init?(coder _: NSCoder) {
|
|
19
|
+
fatalError("init(coder:) has not been implemented")
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
/// Called by CoreAnimation to create a shadow copy of this layer
|
|
23
|
+
/// More details: https://developer.apple.com/documentation/quartzcore/calayer/1410842-init
|
|
24
|
+
override init(layer: Any) {
|
|
25
|
+
guard let typedLayer = layer as? Self else {
|
|
26
|
+
fatalError("\(Self.self).init(layer:) incorrectly called with \(type(of: layer))")
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
solidLayer = typedLayer.solidLayer
|
|
30
|
+
super.init(layer: typedLayer)
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
// MARK: Private
|
|
34
|
+
|
|
35
|
+
private let solidLayer: SolidLayerModel
|
|
36
|
+
|
|
37
|
+
private func setupContentLayer() {
|
|
38
|
+
// Render the fill color in a child `CAShapeLayer`
|
|
39
|
+
// - Using a `CAShapeLayer` specifically, instead of a `CALayer` with a `backgroundColor`,
|
|
40
|
+
// allows the size of the fill shape to be different from `contentsLayer.size`.
|
|
41
|
+
let shapeLayer = CAShapeLayer()
|
|
42
|
+
shapeLayer.fillColor = solidLayer.colorHex.cgColor
|
|
43
|
+
shapeLayer.path = CGPath(rect: .init(x: 0, y: 0, width: solidLayer.width, height: solidLayer.height), transform: nil)
|
|
44
|
+
addSublayer(shapeLayer)
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
}
|
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
// Created by Cal Stephens on 2/9/22.
|
|
2
|
+
// Copyright © 2022 Airbnb Inc. All rights reserved.
|
|
3
|
+
|
|
4
|
+
import QuartzCore
|
|
5
|
+
|
|
6
|
+
/// The `CALayer` type responsible for rendering `TextLayer`s
|
|
7
|
+
final class TextLayer: BaseCompositionLayer {
|
|
8
|
+
|
|
9
|
+
// MARK: Lifecycle
|
|
10
|
+
|
|
11
|
+
init(
|
|
12
|
+
textLayerModel: TextLayerModel,
|
|
13
|
+
context: LayerContext)
|
|
14
|
+
throws
|
|
15
|
+
{
|
|
16
|
+
self.textLayerModel = textLayerModel
|
|
17
|
+
super.init(layerModel: textLayerModel)
|
|
18
|
+
setupSublayers()
|
|
19
|
+
try configureRenderLayer(with: context)
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
required init?(coder _: NSCoder) {
|
|
23
|
+
fatalError("init(coder:) has not been implemented")
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
/// Called by CoreAnimation to create a shadow copy of this layer
|
|
27
|
+
/// More details: https://developer.apple.com/documentation/quartzcore/calayer/1410842-init
|
|
28
|
+
override init(layer: Any) {
|
|
29
|
+
guard let typedLayer = layer as? Self else {
|
|
30
|
+
fatalError("\(Self.self).init(layer:) incorrectly called with \(type(of: layer))")
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
textLayerModel = typedLayer.textLayerModel
|
|
34
|
+
super.init(layer: typedLayer)
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
// MARK: Internal
|
|
38
|
+
|
|
39
|
+
func configureRenderLayer(with context: LayerContext) throws {
|
|
40
|
+
// We can't use `CATextLayer`, because it doesn't support enough features we use.
|
|
41
|
+
// Instead, we use the same `CoreTextRenderLayer` (with a custom `draw` implementation)
|
|
42
|
+
// used by the Main Thread rendering engine. This means the Core Animation engine can't
|
|
43
|
+
// _animate_ text properties, but it can display static text without any issues.
|
|
44
|
+
let text = try textLayerModel.text.exactlyOneKeyframe(context: context, description: "text layer text").value
|
|
45
|
+
|
|
46
|
+
// The Core Animation engine doesn't currently support `TextAnimator`s.
|
|
47
|
+
// - We could add support for animating the transform-related properties without much trouble.
|
|
48
|
+
// - We may be able to support animating `fillColor` by getting clever with layer blend modes
|
|
49
|
+
// or masks (e.g. use `CoreTextRenderLayer` to draw black glyphs, and then fill them in
|
|
50
|
+
// using a `CAShapeLayer`).
|
|
51
|
+
if !textLayerModel.animators.isEmpty {
|
|
52
|
+
try context.logCompatibilityIssue("""
|
|
53
|
+
The Core Animation rendering engine currently doesn't support text animators.
|
|
54
|
+
""")
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
renderLayer.text = text.text
|
|
58
|
+
renderLayer.font = context.fontProvider.fontFor(family: text.fontFamily, size: CGFloat(text.fontSize))
|
|
59
|
+
|
|
60
|
+
renderLayer.alignment = text.justification.textAlignment
|
|
61
|
+
renderLayer.lineHeight = CGFloat(text.lineHeight)
|
|
62
|
+
renderLayer.tracking = (CGFloat(text.fontSize) * CGFloat(text.tracking)) / 1000
|
|
63
|
+
|
|
64
|
+
renderLayer.fillColor = text.fillColorData?.cgColorValue
|
|
65
|
+
renderLayer.strokeColor = text.strokeColorData?.cgColorValue
|
|
66
|
+
renderLayer.strokeWidth = CGFloat(text.strokeWidth ?? 0)
|
|
67
|
+
renderLayer.strokeOnTop = text.strokeOverFill ?? false
|
|
68
|
+
|
|
69
|
+
renderLayer.preferredSize = text.textFrameSize?.sizeValue
|
|
70
|
+
renderLayer.sizeToFit()
|
|
71
|
+
|
|
72
|
+
renderLayer.transform = CATransform3DIdentity
|
|
73
|
+
renderLayer.position = text.textFramePosition?.pointValue ?? .zero
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
// MARK: Private
|
|
77
|
+
|
|
78
|
+
private let textLayerModel: TextLayerModel
|
|
79
|
+
private let renderLayer = CoreTextRenderLayer()
|
|
80
|
+
|
|
81
|
+
private func setupSublayers() {
|
|
82
|
+
// Place the text render layer in an additional container
|
|
83
|
+
// - Direct sublayers of a `BaseCompositionLayer` always fill the bounds
|
|
84
|
+
// of their superlayer -- so this container will be the bounds of self,
|
|
85
|
+
// and the text render layer can be positioned anywhere.
|
|
86
|
+
let textContainerLayer = CALayer()
|
|
87
|
+
textContainerLayer.addSublayer(renderLayer)
|
|
88
|
+
addSublayer(textContainerLayer)
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
// Created by Cal Stephens on 12/21/21.
|
|
2
|
+
// Copyright © 2021 Airbnb Inc. All rights reserved.
|
|
3
|
+
|
|
4
|
+
/// The CALayer type responsible for only rendering the `transform` of a `LayerModel`
|
|
5
|
+
final class TransformLayer: BaseCompositionLayer {
|
|
6
|
+
|
|
7
|
+
/// `TransformLayer`s don't render any visible content,
|
|
8
|
+
/// they just `transform` their sublayers
|
|
9
|
+
override var renderLayerContents: Bool { false }
|
|
10
|
+
|
|
11
|
+
}
|
|
@@ -0,0 +1,139 @@
|
|
|
1
|
+
// Created by Cal Stephens on 1/13/22.
|
|
2
|
+
// Copyright © 2022 Airbnb Inc. All rights reserved.
|
|
3
|
+
|
|
4
|
+
import QuartzCore
|
|
5
|
+
|
|
6
|
+
// MARK: - ValueProviderStore
|
|
7
|
+
|
|
8
|
+
/// Registration and storage for `AnyValueProvider`s that can dynamically
|
|
9
|
+
/// provide custom values for `AnimationKeypath`s within an `Animation`.
|
|
10
|
+
final class ValueProviderStore {
|
|
11
|
+
|
|
12
|
+
// MARK: Lifecycle
|
|
13
|
+
|
|
14
|
+
init(logger: LottieLogger) {
|
|
15
|
+
self.logger = logger
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
// MARK: Internal
|
|
19
|
+
|
|
20
|
+
/// Registers an `AnyValueProvider` for the given `AnimationKeypath`
|
|
21
|
+
func setValueProvider(_ valueProvider: AnyValueProvider, keypath: AnimationKeypath) {
|
|
22
|
+
logger.assert(
|
|
23
|
+
valueProvider.typeErasedStorage.isSupportedByCoreAnimationRenderingEngine,
|
|
24
|
+
"""
|
|
25
|
+
The Core Animation rendering engine doesn't support Value Providers that vend a closure,
|
|
26
|
+
because that would require calling the closure on the main thread once per frame.
|
|
27
|
+
""")
|
|
28
|
+
|
|
29
|
+
// TODO: Support more value types
|
|
30
|
+
logger.assert(
|
|
31
|
+
keypath.keys.last == PropertyName.color.rawValue,
|
|
32
|
+
"The Core Animation rendering engine currently only supports customizing color values")
|
|
33
|
+
|
|
34
|
+
valueProviders.append((keypath: keypath, valueProvider: valueProvider))
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
// Retrieves the custom value keyframes for the given property,
|
|
38
|
+
// if an `AnyValueProvider` was registered for the given keypath.
|
|
39
|
+
func customKeyframes<Value>(
|
|
40
|
+
of customizableProperty: CustomizableProperty<Value>,
|
|
41
|
+
for keypath: AnimationKeypath,
|
|
42
|
+
context: LayerAnimationContext)
|
|
43
|
+
throws
|
|
44
|
+
-> KeyframeGroup<Value>?
|
|
45
|
+
{
|
|
46
|
+
if context.logHierarchyKeypaths {
|
|
47
|
+
context.logger.info(keypath.fullPath)
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
guard let anyValueProvider = valueProvider(for: keypath) else {
|
|
51
|
+
return nil
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
// Retrieve the type-erased keyframes from the custom `ValueProvider`
|
|
55
|
+
let typeErasedKeyframes: [Keyframe<Any>]
|
|
56
|
+
switch anyValueProvider.typeErasedStorage {
|
|
57
|
+
case .singleValue(let typeErasedValue):
|
|
58
|
+
typeErasedKeyframes = [Keyframe(typeErasedValue)]
|
|
59
|
+
|
|
60
|
+
case .keyframes(let keyframes, _):
|
|
61
|
+
typeErasedKeyframes = keyframes
|
|
62
|
+
|
|
63
|
+
case .closure:
|
|
64
|
+
try context.logCompatibilityIssue("""
|
|
65
|
+
The Core Animation rendering engine doesn't support Value Providers that vend a closure,
|
|
66
|
+
because that would require calling the closure on the main thread once per frame.
|
|
67
|
+
""")
|
|
68
|
+
return nil
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
// Convert the type-erased keyframe values using this `CustomizableProperty`'s conversion closure
|
|
72
|
+
let typedKeyframes = typeErasedKeyframes.compactMap { typeErasedKeyframe -> Keyframe<Value>? in
|
|
73
|
+
guard let convertedValue = customizableProperty.conversion(typeErasedKeyframe.value) else {
|
|
74
|
+
logger.assertionFailure("""
|
|
75
|
+
Could not convert value of type \(type(of: typeErasedKeyframe.value)) to expected type \(Value.self)
|
|
76
|
+
""")
|
|
77
|
+
return nil
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
return typeErasedKeyframe.withValue(convertedValue)
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
// Verify that all of the keyframes were successfully converted to the expected type
|
|
84
|
+
guard typedKeyframes.count == typeErasedKeyframes.count else {
|
|
85
|
+
return nil
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
return KeyframeGroup(keyframes: ContiguousArray(typedKeyframes))
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
// MARK: Private
|
|
92
|
+
|
|
93
|
+
private let logger: LottieLogger
|
|
94
|
+
|
|
95
|
+
private var valueProviders = [(keypath: AnimationKeypath, valueProvider: AnyValueProvider)]()
|
|
96
|
+
|
|
97
|
+
/// Retrieves the most-recently-registered Value Provider that matches the given keypat
|
|
98
|
+
private func valueProvider(for keypath: AnimationKeypath) -> AnyValueProvider? {
|
|
99
|
+
// Find the last keypath matching the given keypath,
|
|
100
|
+
// so we return the value provider that was registered most-recently
|
|
101
|
+
valueProviders.last(where: { registeredKeypath, _ in
|
|
102
|
+
keypath.matches(registeredKeypath)
|
|
103
|
+
})?.valueProvider
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
extension AnyValueProviderStorage {
|
|
109
|
+
/// Whether or not this type of value provider is supported
|
|
110
|
+
/// by the new Core Animation rendering engine
|
|
111
|
+
var isSupportedByCoreAnimationRenderingEngine: Bool {
|
|
112
|
+
switch self {
|
|
113
|
+
case .singleValue, .keyframes:
|
|
114
|
+
return true
|
|
115
|
+
case .closure:
|
|
116
|
+
return false
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
extension AnimationKeypath {
|
|
122
|
+
/// Whether or not this keypath from the animation hierarchy
|
|
123
|
+
/// matches the given keypath (which may contain wildcards)
|
|
124
|
+
func matches(_ keypath: AnimationKeypath) -> Bool {
|
|
125
|
+
var regex = "^" // match the start of the string
|
|
126
|
+
+ keypath.keys.joined(separator: "\\.") // match this keypath, escaping "." characters
|
|
127
|
+
+ "$" // match the end of the string
|
|
128
|
+
|
|
129
|
+
// ** wildcards match anything
|
|
130
|
+
// - "**.Color" matches both "Layer 1.Color" and "Layer 1.Layer 2.Color"
|
|
131
|
+
regex = regex.replacingOccurrences(of: "**", with: ".+")
|
|
132
|
+
|
|
133
|
+
// * wildcards match any individual path component
|
|
134
|
+
// - "*.Color" matches "Layer 1.Color" but not "Layer 1.Layer 2.Color"
|
|
135
|
+
regex = regex.replacingOccurrences(of: "*", with: "[^.]+")
|
|
136
|
+
|
|
137
|
+
return fullPath.range(of: regex, options: .regularExpression) != nil
|
|
138
|
+
}
|
|
139
|
+
}
|