lottie-ios 3.4.0 → 3.4.3

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.
Files changed (394) hide show
  1. package/.github/workflows/main.yml +10 -7
  2. package/.github/workflows/stale_issues.yml +17 -0
  3. package/.swiftpm/xcode/package.xcworkspace/xcuserdata/calstephens.xcuserdatad/UserInterfaceState.xcuserstate +0 -0
  4. package/Lottie.xcodeproj/project.pbxproj +33 -21
  5. package/Lottie.xcodeproj/xcshareddata/xcschemes/Lottie (macOS).xcscheme +2 -2
  6. package/Lottie.xcworkspace/xcuserdata/calstephens.xcuserdatad/UserInterfaceState.xcuserstate +0 -0
  7. package/Lottie.xcworkspace/xcuserdata/calstephens.xcuserdatad/xcdebugger/Breakpoints_v2.xcbkptlist +5 -6
  8. package/Lottie.xcworkspace/xcuserdata/calstephens.xcuserdatad/xcdebugger/Expressions.xcexplist +114 -1
  9. package/Lottie.xcworkspace/xcuserdata/calstephens.xcuserdatad/xcschemes/xcschememanagement.plist +30 -0
  10. package/Package.swift +1 -1
  11. package/README.md +5 -6
  12. package/Rakefile +52 -17
  13. package/Sources/Private/CoreAnimation/Animations/CAAnimation+TimingConfiguration.swift +7 -2
  14. package/Sources/Private/CoreAnimation/Animations/CALayer+addAnimation.swift +192 -67
  15. package/Sources/Private/CoreAnimation/Animations/CombinedShapeAnimation.swift +28 -0
  16. package/Sources/Private/CoreAnimation/Animations/EllipseAnimation.swift +31 -4
  17. package/Sources/Private/CoreAnimation/Animations/GradientAnimations.swift +98 -43
  18. package/Sources/Private/CoreAnimation/Animations/LayerProperty.swift +19 -19
  19. package/Sources/Private/CoreAnimation/Animations/RectangleAnimation.swift +34 -7
  20. package/Sources/Private/CoreAnimation/Animations/ShapeAnimation.swift +25 -14
  21. package/Sources/Private/CoreAnimation/Animations/StarAnimation.swift +61 -32
  22. package/Sources/Private/CoreAnimation/Animations/StrokeAnimation.swift +6 -2
  23. package/Sources/Private/CoreAnimation/CoreAnimationLayer.swift +29 -11
  24. package/Sources/Private/CoreAnimation/Extensions/KeyframeGroup+exactlyOneKeyframe.swift +2 -2
  25. package/Sources/Private/CoreAnimation/Extensions/Keyframes+combinedIfPossible.swift +116 -23
  26. package/Sources/Private/CoreAnimation/Layers/AnimationLayer.swift +9 -0
  27. package/Sources/Private/CoreAnimation/Layers/BaseCompositionLayer.swift +2 -1
  28. package/Sources/Private/CoreAnimation/Layers/CALayer+setupLayerHierarchy.swift +48 -12
  29. package/Sources/Private/CoreAnimation/Layers/GradientRenderLayer.swift +10 -3
  30. package/Sources/Private/CoreAnimation/Layers/LayerModel+makeAnimationLayer.swift +5 -0
  31. package/Sources/Private/CoreAnimation/Layers/MaskCompositionLayer.swift +1 -1
  32. package/Sources/Private/CoreAnimation/Layers/PreCompLayer.swift +2 -2
  33. package/Sources/Private/CoreAnimation/Layers/RepeaterLayer.swift +85 -0
  34. package/Sources/Private/CoreAnimation/Layers/ShapeItemLayer.swift +94 -38
  35. package/Sources/Private/CoreAnimation/Layers/ShapeLayer.swift +131 -46
  36. package/Sources/Private/CoreAnimation/Layers/TextLayer.swift +16 -2
  37. package/Sources/Private/MainThread/LayerContainers/CompLayers/CompositionLayer.swift +1 -1
  38. package/Sources/Private/MainThread/LayerContainers/CompLayers/MaskContainerLayer.swift +0 -2
  39. package/Sources/Private/MainThread/LayerContainers/CompLayers/PreCompositionLayer.swift +2 -2
  40. package/Sources/Private/MainThread/LayerContainers/MainThreadAnimationLayer.swift +1 -2
  41. package/Sources/Private/MainThread/LayerContainers/Utility/CoreTextRenderLayer.swift +30 -1
  42. package/Sources/Private/MainThread/LayerContainers/Utility/InvertedMatteLayer.swift +1 -0
  43. package/Sources/Private/MainThread/LayerContainers/Utility/LayerTransformNode.swift +0 -1
  44. package/Sources/Private/MainThread/NodeRenderSystem/Extensions/ItemsExtension.swift +5 -2
  45. package/Sources/Private/MainThread/NodeRenderSystem/Nodes/ModifierNodes/TrimPathNode.swift +4 -7
  46. package/Sources/Private/MainThread/NodeRenderSystem/Nodes/OutputNodes/Renderables/GradientFillRenderer.swift +5 -0
  47. package/Sources/Private/MainThread/NodeRenderSystem/Nodes/OutputNodes/Renderables/GradientStrokeRenderer.swift +1 -2
  48. package/Sources/Private/MainThread/NodeRenderSystem/Nodes/OutputNodes/Renderables/LegacyGradientFillRenderer.swift +1 -1
  49. package/Sources/Private/MainThread/NodeRenderSystem/Nodes/OutputNodes/Renderables/StrokeRenderer.swift +1 -1
  50. package/Sources/Private/MainThread/NodeRenderSystem/Nodes/PathNodes/RectNode.swift +1 -1
  51. package/Sources/Private/MainThread/NodeRenderSystem/Nodes/PathNodes/StarNode.swift +3 -3
  52. package/Sources/Private/MainThread/NodeRenderSystem/Nodes/RenderNodes/GradientFillNode.swift +3 -0
  53. package/Sources/Private/MainThread/NodeRenderSystem/Nodes/RenderNodes/GradientStrokeNode.swift +1 -1
  54. package/Sources/Private/MainThread/NodeRenderSystem/Nodes/RenderNodes/StrokeNode.swift +28 -1
  55. package/Sources/Private/MainThread/NodeRenderSystem/RenderLayers/ShapeContainerLayer.swift +1 -1
  56. package/Sources/Private/MainThread/NodeRenderSystem/RenderLayers/ShapeRenderLayer.swift +0 -1
  57. package/Sources/Private/Model/Animation.swift +4 -4
  58. package/Sources/Private/Model/Keyframes/KeyframeGroup.swift +25 -0
  59. package/Sources/Private/Model/ShapeItems/Ellipse.swift +0 -1
  60. package/Sources/Private/Model/ShapeItems/Fill.swift +1 -1
  61. package/Sources/Private/Model/ShapeItems/GradientFill.swift +14 -1
  62. package/Sources/Private/Model/ShapeItems/GradientStroke.swift +0 -1
  63. package/Sources/Private/Model/ShapeItems/Group.swift +6 -1
  64. package/Sources/Private/Model/ShapeItems/Merge.swift +0 -1
  65. package/Sources/Private/Model/ShapeItems/Rectangle.swift +0 -1
  66. package/Sources/Private/Model/ShapeItems/Repeater.swift +0 -1
  67. package/Sources/Private/Model/ShapeItems/ShapeTransform.swift +0 -1
  68. package/Sources/Private/Model/ShapeItems/Star.swift +0 -1
  69. package/Sources/Private/Model/ShapeItems/Stroke.swift +0 -1
  70. package/Sources/Private/Model/ShapeItems/Trim.swift +0 -1
  71. package/Sources/Private/Model/Text/TextAnimator.swift +0 -1
  72. package/Sources/Private/Utility/Debugging/LayerDebugging.swift +1 -2
  73. package/Sources/Private/Utility/Extensions/MathKit.swift +1 -2
  74. package/Sources/Private/Utility/Extensions/StringExtensions.swift +0 -1
  75. package/Sources/Private/Utility/Interpolatable/InterpolatableExtensions.swift +0 -1
  76. package/Sources/Private/{MainThread/NodeRenderSystem/NodeProperties/ValueProviders → Utility/Interpolatable}/KeyframeInterpolator.swift +1 -4
  77. package/Sources/Private/Utility/Primitives/BezierPath.swift +1 -2
  78. package/Sources/Private/Utility/Primitives/CurveVertex.swift +2 -4
  79. package/Sources/Public/Animation/AnimationPublic.swift +2 -4
  80. package/Sources/Public/Animation/AnimationView.swift +29 -7
  81. package/Sources/Public/Animation/AnimationViewInitializers.swift +13 -11
  82. package/Sources/Public/DynamicProperties/ValueProviders/GradientValueProvider.swift +0 -2
  83. package/Sources/Public/FontProvider/AnimationFontProvider.swift +1 -1
  84. package/Sources/Public/Logging/LottieLogger.swift +15 -2
  85. package/Sources/Public/TextProvider/AnimationTextProvider.swift +1 -1
  86. package/Sources/Public/iOS/AnimatedButton.swift +10 -4
  87. package/Sources/Public/iOS/AnimatedControl.swift +3 -5
  88. package/Sources/Public/iOS/AnimatedSwitch.swift +9 -6
  89. package/Sources/Public/iOS/BundleImageProvider.swift +2 -3
  90. package/Sources/Public/iOS/FilepathImageProvider.swift +1 -2
  91. package/Sources/Public/macOS/BundleImageProvider.macOS.swift +1 -2
  92. package/Sources/Public/macOS/FilepathImageProvider.macOS.swift +1 -3
  93. package/Tests/AnimationKeypathTests.swift +10 -1
  94. package/Tests/AutomaticEngineTests.swift +1 -0
  95. package/Tests/ParsingTests.swift +2 -1
  96. package/Tests/PerformanceTests.swift +28 -29
  97. package/Tests/SnapshotConfiguration.swift +19 -0
  98. package/Tests/SnapshotTests.swift +4 -0
  99. package/Tests/Utils/HardcodedTextProvider.swift +27 -0
  100. package/lottie-ios.podspec +2 -2
  101. package/package.json +1 -1
  102. package/script/test-carthage/CarthageTest/AppDelegate.swift +6 -7
  103. package/script/test-carthage/CarthageTest/ViewController.swift +1 -1
  104. package/script/test-carthage/CarthageTest-macOS/AppDelegate.swift +7 -0
  105. package/script/test-carthage/CarthageTest-macOS/Assets.xcassets/AccentColor.colorset/Contents.json +11 -0
  106. package/script/test-carthage/CarthageTest-macOS/Assets.xcassets/AppIcon.appiconset/Contents.json +58 -0
  107. package/script/test-carthage/CarthageTest-macOS/Assets.xcassets/Contents.json +6 -0
  108. package/script/test-carthage/CarthageTest-macOS/Base.lproj/Main.storyboard +717 -0
  109. package/script/test-carthage/CarthageTest-macOS/CarthageTest_macOS.entitlements +10 -0
  110. package/script/test-carthage/CarthageTest-macOS/ViewController.swift +15 -0
  111. package/script/test-carthage/CarthageTest.xcodeproj/project.pbxproj +159 -5
  112. package/script/test-carthage/CarthageTest.xcodeproj/project.xcworkspace/xcuserdata/calstephens.xcuserdatad/UserInterfaceState.xcuserstate +0 -0
  113. package/script/test-carthage/CarthageTest.xcodeproj/xcuserdata/calstephens.xcuserdatad/xcschemes/xcschememanagement.plist +19 -0
  114. package/Lottie.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved +0 -23
  115. package/Mintfile +0 -3
  116. package/Tests/Artifacts/LottieTests.xcresult/Data/data.0~-7Vi1RszY1XYnR2CCkEwIpKG8NwwA9zsZEz_WD7Dv6kKh4RC7N7ob8NIRVHGUJKp7eXxlpeI_gzD87Pcs_2u0g== +0 -0
  117. package/Tests/Artifacts/LottieTests.xcresult/Data/data.0~-SKV2drO-SFlrlh-wrzECDMkUSr-aF1lV9h-5onOy94zSTsD-oI45s0-KpOK45L-kq3hRY7v9vm-xmh00_eheg== +0 -0
  118. package/Tests/Artifacts/LottieTests.xcresult/Data/data.0~-_CU_vuaiFfObSeDFfmp7GuB20ThMSAL-P_RUMowiQLbdu-y0bU9upIm3q8g6XmXUG5hP6J1az0Ma5Hi_rhhRg== +0 -0
  119. package/Tests/Artifacts/LottieTests.xcresult/Data/data.0~03aPYP6VHJjZj5DlphGarj0xdw43qu09Onx5SReZoPvg9zh5uL212E-KWfGct9jf6JG0JFV2tdbBi7X_8bH9aw== +0 -0
  120. package/Tests/Artifacts/LottieTests.xcresult/Data/data.0~1Z82GPBBPc1VLvn4O7V5glb6lgyXteNlDREUzV_TPymM4ra4UkBMklzV90lEqoYRCDuRVzaQHaDYbmYp3-8CFw== +0 -0
  121. package/Tests/Artifacts/LottieTests.xcresult/Data/data.0~1mFDCboXpUu9pSHAiVGr1O_QgqEEtvJp_LUhickxLZo0Z5pj3fvadn1l2MzEOd4bFsVBZifUvcyPa7dzlMWF-A== +0 -0
  122. package/Tests/Artifacts/LottieTests.xcresult/Data/data.0~2_L9PUjv2JDKu1n8bDLb4XLB-yex6ZVjDDMwfuKAr7teDw-SKgLgkW6H-m_gjWChIVdB4vW6yvHP7XJxvXtRNA== +0 -0
  123. package/Tests/Artifacts/LottieTests.xcresult/Data/data.0~4VqMqsI5lOfxRppnud6-VDWcNsU8J7VgFCJfW2dXPwOcAkvU-I8Um5yp9n0Zv6nr3VmcxYggaVMDFfR0U_vjKw== +0 -1
  124. package/Tests/Artifacts/LottieTests.xcresult/Data/data.0~4krT4ZMzDOu34msFUq0Xod142kw4pAeSWX4JSxlsjOI0Wanu3343qeespgFi61MTWq1DdH9XXspVKqGlGm_fyw== +0 -0
  125. package/Tests/Artifacts/LottieTests.xcresult/Data/data.0~5_aJsdP-e3dRTAUnH-y1U2plaCuUi1vyHriaZuNK0xFe8wGl9Qft6uLCX2Qt6CRBKJQluEe9o0uRWw1eb42FHQ== +0 -0
  126. package/Tests/Artifacts/LottieTests.xcresult/Data/data.0~8b0bSqV7eND54zvHvu1v2Htpm7yn-BOEFw5d3mITJrXWNykJ5BTR9WbrD80JEctNcT-rDqO2xfrQk1tFWeY6Sw== +0 -0
  127. package/Tests/Artifacts/LottieTests.xcresult/Data/data.0~9u8KAGpgtSm-mQ12Py8RZUbYbDlBhM3w1I2MQO53K2CSn6IePp7g65DBcdXTYMfG1bgoJ-6x30fjnGe-2UYsDQ== +0 -0
  128. package/Tests/Artifacts/LottieTests.xcresult/Data/data.0~Bw7uMs4wqB9ahfEqGii2FkQ9pvZmG6HGe2hmbAT2wyM5hpn8Xh5dELysMcEz6hEsqmn6HdRdLOLZhC_fNaXzgA== +0 -0
  129. package/Tests/Artifacts/LottieTests.xcresult/Data/data.0~BwUq2xXQYuE8ya6HT6lfNsdtEjz5AKGf8GvLY6VBxQyIY1vgj_Gov-3NeM69OS66BQRDK0PG9H4Oyg0R48E4vg== +0 -0
  130. package/Tests/Artifacts/LottieTests.xcresult/Data/data.0~EkDVUR6dcnzxV_lYjkrJ5QGMVTCvb_upAoBF6DBu61sQkGvZN3fSRTsJ1XfJIZO-JUzdNoVA3D_CcvokL0gnQg== +0 -0
  131. package/Tests/Artifacts/LottieTests.xcresult/Data/data.0~FUkcLSJ8RAuPenM4HFG1R-sN5-cDBGcTxgR2jaVCna7xV0ZTyBHriB1Nn59mariNlJDiCoBtMUQEmauGxWtfBA== +0 -0
  132. package/Tests/Artifacts/LottieTests.xcresult/Data/data.0~FqsuZe4RVLOOVUYLTL-GTIohZ8TdSfxx7m2KJtLYFPGOdE4XorTX7Oc7kXbhghPRppXT3jW-slI37M34YNEvLQ== +0 -0
  133. package/Tests/Artifacts/LottieTests.xcresult/Data/data.0~G4F_NtyTj3i46fmKm0NorHAeq8tYWWYf6uv5yC1DwzdpWVoYbOPufmFNvdEbxZt4AMdV0gKx3HI46EAXNOQVFg== +0 -0
  134. package/Tests/Artifacts/LottieTests.xcresult/Data/data.0~GxetzGUNDgaBBXcTmLK6p9JBDX3I3QPshshbui1IaEWvJbQko-E36tCKwaJYHbleAWz9FqkAM_Tqx3YOmSVkVg== +0 -0
  135. package/Tests/Artifacts/LottieTests.xcresult/Data/data.0~H1Wjd5kKWDW4t3SDodxiHV72V8WT0xwPubw5cJTNLkPRLgaILFPh-dpy8EOUNgy1KzrDujFsm9EcTsbuqtMPLA== +0 -0
  136. package/Tests/Artifacts/LottieTests.xcresult/Data/data.0~JpI5MH4zCgebUHFpXVn4zjtsGtMNnO7BQZWfNARAB5UWa9gqz6YXHR3uLCJ_AvJ3lh53BUVkavsx9TY2FMmxbA== +0 -0
  137. package/Tests/Artifacts/LottieTests.xcresult/Data/data.0~JujNYkJtcux0Ni4QnR64zu4Wz_zYjyKvYaYZm5ypxTLPSzF3_jNE_NO4sdbDamF8wEqWoky1uf4ZE0JT3L607A== +0 -0
  138. package/Tests/Artifacts/LottieTests.xcresult/Data/data.0~KJSEA6DKnb2_FRPSqKZGh41eo-C8x448J9kEBrH012bUrZfOSDvrgmIrU0Vz7Ri3gaS9aKKmSaVMvXsHSlTJVA== +0 -0
  139. package/Tests/Artifacts/LottieTests.xcresult/Data/data.0~MStOwu3jBlJtcRnxrseVOuhI4kCj--ggFPG7sqrq5w1hjrI3bVyD-bm1Jwyx0noY3wT1rHDEvaGWnV2qsGjGwg== +0 -0
  140. package/Tests/Artifacts/LottieTests.xcresult/Data/data.0~McsJ8kFVf3IjhgXIRdw8Xx-EXgbV071bmlj2BBnk52xrWl3sEeiIyxwUsF7mIWvMRWfcFfu4VGHYyqfk2BeHXw== +0 -0
  141. package/Tests/Artifacts/LottieTests.xcresult/Data/data.0~NHt9fVe4kDdbxnglKcEwXaRK-WsYEOaD23Kbl8SJPRMYHr_Z6SJd_HmG3BROHHR_M6TgSmucONpDJdTj5tjuFw== +0 -0
  142. package/Tests/Artifacts/LottieTests.xcresult/Data/data.0~Nfo2iwCPcfAcOBIVyoUAK0-PIfr5qYxIKZt-uaSaTBdrTNxAuJ1ItmeDPZ3VdJJmxD_c22No7x482bdd3_yYtw== +0 -0
  143. package/Tests/Artifacts/LottieTests.xcresult/Data/data.0~S2Qlu11xBhEd5aGSzWsnw1TR8u8PiOF93GO0j5bfNoAFCVzxKOwhRFoIXba2EpQnLQqFdIKyhWN3l70A4GPHmg== +0 -0
  144. package/Tests/Artifacts/LottieTests.xcresult/Data/data.0~W7a7M37RO9jgck2zeR0471Pm7e8K0Kqj5tXEouDjvqKZXSrWxMaWD28oqkKKYAiU4608R4S9mM11KyphljdMSw== +0 -0
  145. package/Tests/Artifacts/LottieTests.xcresult/Data/data.0~XUo1oyPCrlL7CA74wG-OzQ06VOWJYWvHGFHU7keZN1SKaIXjHX5qi_kBzjG_rBCi89-S8GVmCy7S3PHSjG8SbQ== +0 -0
  146. package/Tests/Artifacts/LottieTests.xcresult/Data/data.0~Xh0VmDvFNMELHu08-vrs54pegVyUwwDRxx_nXkwyD0NjnYozyqcGAKAr_QWHmw6F8XyuWg51M9KGpJJIFzzGuw== +0 -0
  147. package/Tests/Artifacts/LottieTests.xcresult/Data/data.0~Xve-wMBp_lxVUgD9qH5GwieGP9cAWtm0xULZvdGjBRUMvaevmpCB5gnbMBuIXAO6a1c9v6WUq0jNVX7ut5HvOw== +0 -0
  148. package/Tests/Artifacts/LottieTests.xcresult/Data/data.0~ZU1XkZFgnEE22CXEF-pOlcj5f10x-KM1Vw9d4IOLu-NiTZcz7koYPixhdrB1PJr8J-h9NpJmfqEastfxamA1jQ== +0 -0
  149. package/Tests/Artifacts/LottieTests.xcresult/Data/data.0~_YkNYEHTsbbtFILJpzH3HenH0t4ShI25dIMdve541CF5bl-jPF3X3F7tq-t5dvP0TEkATsOJdLQdBp1xv4Q-ag== +0 -0
  150. package/Tests/Artifacts/LottieTests.xcresult/Data/data.0~boy6mpn2jkwm60jjgQ0TG25UqRdN46LzmgTVCrpy6nBOgkLCGkGHcbceiwjU1itS_vj3-iQX0ZnrWOQrPyfHNA== +0 -0
  151. package/Tests/Artifacts/LottieTests.xcresult/Data/data.0~bwzpVZ9hAqGDHhXs2FRA82dfGfLmc7-m0uQhZDDfHHO7hQ17M_Np341BZX4WDLhYYS4cdUgaDodlNpdfpG3nXw== +0 -0
  152. package/Tests/Artifacts/LottieTests.xcresult/Data/data.0~cBxe-9PpAGFdAsYkmdN3lJVqEliLcRYlyoAov0aPZfJGwUr_cOm3XpjO7nmf_2eLf8UAx-rycjnJzw07xLrNCA== +0 -1
  153. package/Tests/Artifacts/LottieTests.xcresult/Data/data.0~dirWk6W4Pav1oyciuflfJlRu0iuxbYOmrpQapOJ0mV9C1SQ-jvDRv_7h753Cy18-SwULARUdWsyUy3yNNvxF7w== +0 -0
  154. package/Tests/Artifacts/LottieTests.xcresult/Data/data.0~ebwZVjSEHroc9jtIm4jd_h_YAqEBcOkAZ4HPNJT8pLCldjRcTq-obQLakxXOhfuoOBlYBoZLuO-Y0lskeZRYKw== +0 -0
  155. package/Tests/Artifacts/LottieTests.xcresult/Data/data.0~gfcRcmRIr0h09d0jiZsA7nUeQv2XtapxuYEXZy1Z9um0tTJQvz-O5ef5f7zhLenLvjnDtDtlY_aY4Hvpce6e1Q== +0 -0
  156. package/Tests/Artifacts/LottieTests.xcresult/Data/data.0~hgOgiVCyv2R0W-f0qKw5xYPeUwj8_ccCM9vKH_7vAQcCO9t8BwR1APGRBv20AONmp-PYMXmtgsBlQkNBRBpdQA== +0 -0
  157. package/Tests/Artifacts/LottieTests.xcresult/Data/data.0~hrhCl-YRAAr8ByNB_LCgEBsVNHMp92gTIUknetpUHMjcXl4Hpn_uY-h6C45oga0ZALnfGCo6iKTmiPLa4Qvnpg== +0 -0
  158. package/Tests/Artifacts/LottieTests.xcresult/Data/data.0~n2yoR7JsyL4DSUwmjnpE4Iq9Qi_eeZrmpPU8cdehDFKfESK7nwxXxfrSMQbk0BQ2lgGPadoRcd1-qr1xVz97jA== +0 -0
  159. package/Tests/Artifacts/LottieTests.xcresult/Data/data.0~nMCcZm8WvPogyO_nuJ926Q3Q2dqVMN2LdjEL1Kq2wJ_RG-rH-e_6v41l1xZbCsQTa3XykQdEiXNc0HtAvT6IRA== +0 -0
  160. package/Tests/Artifacts/LottieTests.xcresult/Data/data.0~oc3C7xkUt-OWDL6rrsxs-seS4Fu1bqBWAAXCHalgShaGg9MUrOiRbHT2DcAnhyQFKx6x5FRbvjmYoQWrQiXJZA== +0 -0
  161. package/Tests/Artifacts/LottieTests.xcresult/Data/data.0~p-ihj7SEgkDXpMu9hvKE_wiX9cvtwyXrdIn964BfedXHKGpC6o7mMPxEyC0kRPVi_EZs_MRV5bAPEpl5h5we0g== +0 -0
  162. package/Tests/Artifacts/LottieTests.xcresult/Data/data.0~qlhO_D9oE8uSKH-mZqyRF9pp4Zv1Tv0dIYcqrH4hb1VWlIxcdxmg2j0M8496cQeFXC5bn_JMXdBlD-d6cnFF8w== +0 -0
  163. package/Tests/Artifacts/LottieTests.xcresult/Data/data.0~tjpiyIxJR_boTdUNrtFDuKIZoY84fI4lA1oMJbq9e2ZmYKIK5FeRN2O8cV_yMOYJGr4lbv03kTmT70mCjUc2_Q== +0 -0
  164. package/Tests/Artifacts/LottieTests.xcresult/Data/data.0~wULeoj18eEKJWAKx1uFQVwS48cUGFcYPRJQj1Ro5XNJsWCwppGSCdIPhwifD6Z2f_j3zfI2SmC2Gg81sBXXW7g== +0 -0
  165. package/Tests/Artifacts/LottieTests.xcresult/Data/data.0~zrEihMys4NVV5rx6FmuzEGO2TjloI3OiC7yzIhvqYoRo43ibb2F-Km6Jf4NX-ac62pOLBYZRcjQTvYMpn75_oA== +0 -0
  166. package/Tests/Artifacts/LottieTests.xcresult/Data/refs.0~-7Vi1RszY1XYnR2CCkEwIpKG8NwwA9zsZEz_WD7Dv6kKh4RC7N7ob8NIRVHGUJKp7eXxlpeI_gzD87Pcs_2u0g== +0 -0
  167. package/Tests/Artifacts/LottieTests.xcresult/Data/refs.0~-SKV2drO-SFlrlh-wrzECDMkUSr-aF1lV9h-5onOy94zSTsD-oI45s0-KpOK45L-kq3hRY7v9vm-xmh00_eheg== +0 -0
  168. package/Tests/Artifacts/LottieTests.xcresult/Data/refs.0~-_CU_vuaiFfObSeDFfmp7GuB20ThMSAL-P_RUMowiQLbdu-y0bU9upIm3q8g6XmXUG5hP6J1az0Ma5Hi_rhhRg== +0 -0
  169. package/Tests/Artifacts/LottieTests.xcresult/Data/refs.0~03aPYP6VHJjZj5DlphGarj0xdw43qu09Onx5SReZoPvg9zh5uL212E-KWfGct9jf6JG0JFV2tdbBi7X_8bH9aw== +0 -0
  170. package/Tests/Artifacts/LottieTests.xcresult/Data/refs.0~1Z82GPBBPc1VLvn4O7V5glb6lgyXteNlDREUzV_TPymM4ra4UkBMklzV90lEqoYRCDuRVzaQHaDYbmYp3-8CFw== +0 -0
  171. package/Tests/Artifacts/LottieTests.xcresult/Data/refs.0~1mFDCboXpUu9pSHAiVGr1O_QgqEEtvJp_LUhickxLZo0Z5pj3fvadn1l2MzEOd4bFsVBZifUvcyPa7dzlMWF-A== +0 -0
  172. package/Tests/Artifacts/LottieTests.xcresult/Data/refs.0~2_L9PUjv2JDKu1n8bDLb4XLB-yex6ZVjDDMwfuKAr7teDw-SKgLgkW6H-m_gjWChIVdB4vW6yvHP7XJxvXtRNA== +0 -0
  173. package/Tests/Artifacts/LottieTests.xcresult/Data/refs.0~4VqMqsI5lOfxRppnud6-VDWcNsU8J7VgFCJfW2dXPwOcAkvU-I8Um5yp9n0Zv6nr3VmcxYggaVMDFfR0U_vjKw== +0 -0
  174. package/Tests/Artifacts/LottieTests.xcresult/Data/refs.0~4krT4ZMzDOu34msFUq0Xod142kw4pAeSWX4JSxlsjOI0Wanu3343qeespgFi61MTWq1DdH9XXspVKqGlGm_fyw== +0 -0
  175. package/Tests/Artifacts/LottieTests.xcresult/Data/refs.0~5_aJsdP-e3dRTAUnH-y1U2plaCuUi1vyHriaZuNK0xFe8wGl9Qft6uLCX2Qt6CRBKJQluEe9o0uRWw1eb42FHQ== +0 -0
  176. package/Tests/Artifacts/LottieTests.xcresult/Data/refs.0~8b0bSqV7eND54zvHvu1v2Htpm7yn-BOEFw5d3mITJrXWNykJ5BTR9WbrD80JEctNcT-rDqO2xfrQk1tFWeY6Sw== +0 -0
  177. package/Tests/Artifacts/LottieTests.xcresult/Data/refs.0~9u8KAGpgtSm-mQ12Py8RZUbYbDlBhM3w1I2MQO53K2CSn6IePp7g65DBcdXTYMfG1bgoJ-6x30fjnGe-2UYsDQ== +0 -0
  178. package/Tests/Artifacts/LottieTests.xcresult/Data/refs.0~Bw7uMs4wqB9ahfEqGii2FkQ9pvZmG6HGe2hmbAT2wyM5hpn8Xh5dELysMcEz6hEsqmn6HdRdLOLZhC_fNaXzgA== +0 -0
  179. package/Tests/Artifacts/LottieTests.xcresult/Data/refs.0~BwUq2xXQYuE8ya6HT6lfNsdtEjz5AKGf8GvLY6VBxQyIY1vgj_Gov-3NeM69OS66BQRDK0PG9H4Oyg0R48E4vg== +0 -0
  180. package/Tests/Artifacts/LottieTests.xcresult/Data/refs.0~EkDVUR6dcnzxV_lYjkrJ5QGMVTCvb_upAoBF6DBu61sQkGvZN3fSRTsJ1XfJIZO-JUzdNoVA3D_CcvokL0gnQg== +0 -0
  181. package/Tests/Artifacts/LottieTests.xcresult/Data/refs.0~FUkcLSJ8RAuPenM4HFG1R-sN5-cDBGcTxgR2jaVCna7xV0ZTyBHriB1Nn59mariNlJDiCoBtMUQEmauGxWtfBA== +0 -0
  182. package/Tests/Artifacts/LottieTests.xcresult/Data/refs.0~FqsuZe4RVLOOVUYLTL-GTIohZ8TdSfxx7m2KJtLYFPGOdE4XorTX7Oc7kXbhghPRppXT3jW-slI37M34YNEvLQ== +0 -0
  183. package/Tests/Artifacts/LottieTests.xcresult/Data/refs.0~G4F_NtyTj3i46fmKm0NorHAeq8tYWWYf6uv5yC1DwzdpWVoYbOPufmFNvdEbxZt4AMdV0gKx3HI46EAXNOQVFg== +0 -0
  184. package/Tests/Artifacts/LottieTests.xcresult/Data/refs.0~GxetzGUNDgaBBXcTmLK6p9JBDX3I3QPshshbui1IaEWvJbQko-E36tCKwaJYHbleAWz9FqkAM_Tqx3YOmSVkVg== +0 -0
  185. package/Tests/Artifacts/LottieTests.xcresult/Data/refs.0~H1Wjd5kKWDW4t3SDodxiHV72V8WT0xwPubw5cJTNLkPRLgaILFPh-dpy8EOUNgy1KzrDujFsm9EcTsbuqtMPLA== +0 -0
  186. package/Tests/Artifacts/LottieTests.xcresult/Data/refs.0~JpI5MH4zCgebUHFpXVn4zjtsGtMNnO7BQZWfNARAB5UWa9gqz6YXHR3uLCJ_AvJ3lh53BUVkavsx9TY2FMmxbA== +0 -0
  187. package/Tests/Artifacts/LottieTests.xcresult/Data/refs.0~JujNYkJtcux0Ni4QnR64zu4Wz_zYjyKvYaYZm5ypxTLPSzF3_jNE_NO4sdbDamF8wEqWoky1uf4ZE0JT3L607A== +0 -0
  188. package/Tests/Artifacts/LottieTests.xcresult/Data/refs.0~KJSEA6DKnb2_FRPSqKZGh41eo-C8x448J9kEBrH012bUrZfOSDvrgmIrU0Vz7Ri3gaS9aKKmSaVMvXsHSlTJVA== +0 -0
  189. package/Tests/Artifacts/LottieTests.xcresult/Data/refs.0~MStOwu3jBlJtcRnxrseVOuhI4kCj--ggFPG7sqrq5w1hjrI3bVyD-bm1Jwyx0noY3wT1rHDEvaGWnV2qsGjGwg== +0 -0
  190. package/Tests/Artifacts/LottieTests.xcresult/Data/refs.0~McsJ8kFVf3IjhgXIRdw8Xx-EXgbV071bmlj2BBnk52xrWl3sEeiIyxwUsF7mIWvMRWfcFfu4VGHYyqfk2BeHXw== +0 -0
  191. package/Tests/Artifacts/LottieTests.xcresult/Data/refs.0~NHt9fVe4kDdbxnglKcEwXaRK-WsYEOaD23Kbl8SJPRMYHr_Z6SJd_HmG3BROHHR_M6TgSmucONpDJdTj5tjuFw== +0 -0
  192. package/Tests/Artifacts/LottieTests.xcresult/Data/refs.0~Nfo2iwCPcfAcOBIVyoUAK0-PIfr5qYxIKZt-uaSaTBdrTNxAuJ1ItmeDPZ3VdJJmxD_c22No7x482bdd3_yYtw== +0 -0
  193. package/Tests/Artifacts/LottieTests.xcresult/Data/refs.0~S2Qlu11xBhEd5aGSzWsnw1TR8u8PiOF93GO0j5bfNoAFCVzxKOwhRFoIXba2EpQnLQqFdIKyhWN3l70A4GPHmg== +0 -0
  194. package/Tests/Artifacts/LottieTests.xcresult/Data/refs.0~W7a7M37RO9jgck2zeR0471Pm7e8K0Kqj5tXEouDjvqKZXSrWxMaWD28oqkKKYAiU4608R4S9mM11KyphljdMSw== +0 -0
  195. package/Tests/Artifacts/LottieTests.xcresult/Data/refs.0~XUo1oyPCrlL7CA74wG-OzQ06VOWJYWvHGFHU7keZN1SKaIXjHX5qi_kBzjG_rBCi89-S8GVmCy7S3PHSjG8SbQ== +0 -0
  196. package/Tests/Artifacts/LottieTests.xcresult/Data/refs.0~Xh0VmDvFNMELHu08-vrs54pegVyUwwDRxx_nXkwyD0NjnYozyqcGAKAr_QWHmw6F8XyuWg51M9KGpJJIFzzGuw== +0 -0
  197. package/Tests/Artifacts/LottieTests.xcresult/Data/refs.0~Xve-wMBp_lxVUgD9qH5GwieGP9cAWtm0xULZvdGjBRUMvaevmpCB5gnbMBuIXAO6a1c9v6WUq0jNVX7ut5HvOw== +0 -0
  198. package/Tests/Artifacts/LottieTests.xcresult/Data/refs.0~ZU1XkZFgnEE22CXEF-pOlcj5f10x-KM1Vw9d4IOLu-NiTZcz7koYPixhdrB1PJr8J-h9NpJmfqEastfxamA1jQ== +0 -0
  199. package/Tests/Artifacts/LottieTests.xcresult/Data/refs.0~_YkNYEHTsbbtFILJpzH3HenH0t4ShI25dIMdve541CF5bl-jPF3X3F7tq-t5dvP0TEkATsOJdLQdBp1xv4Q-ag== +0 -0
  200. package/Tests/Artifacts/LottieTests.xcresult/Data/refs.0~boy6mpn2jkwm60jjgQ0TG25UqRdN46LzmgTVCrpy6nBOgkLCGkGHcbceiwjU1itS_vj3-iQX0ZnrWOQrPyfHNA== +0 -0
  201. package/Tests/Artifacts/LottieTests.xcresult/Data/refs.0~bwzpVZ9hAqGDHhXs2FRA82dfGfLmc7-m0uQhZDDfHHO7hQ17M_Np341BZX4WDLhYYS4cdUgaDodlNpdfpG3nXw== +0 -0
  202. package/Tests/Artifacts/LottieTests.xcresult/Data/refs.0~cBxe-9PpAGFdAsYkmdN3lJVqEliLcRYlyoAov0aPZfJGwUr_cOm3XpjO7nmf_2eLf8UAx-rycjnJzw07xLrNCA== +0 -0
  203. package/Tests/Artifacts/LottieTests.xcresult/Data/refs.0~dirWk6W4Pav1oyciuflfJlRu0iuxbYOmrpQapOJ0mV9C1SQ-jvDRv_7h753Cy18-SwULARUdWsyUy3yNNvxF7w== +0 -0
  204. package/Tests/Artifacts/LottieTests.xcresult/Data/refs.0~ebwZVjSEHroc9jtIm4jd_h_YAqEBcOkAZ4HPNJT8pLCldjRcTq-obQLakxXOhfuoOBlYBoZLuO-Y0lskeZRYKw== +0 -0
  205. package/Tests/Artifacts/LottieTests.xcresult/Data/refs.0~gfcRcmRIr0h09d0jiZsA7nUeQv2XtapxuYEXZy1Z9um0tTJQvz-O5ef5f7zhLenLvjnDtDtlY_aY4Hvpce6e1Q== +0 -0
  206. package/Tests/Artifacts/LottieTests.xcresult/Data/refs.0~hgOgiVCyv2R0W-f0qKw5xYPeUwj8_ccCM9vKH_7vAQcCO9t8BwR1APGRBv20AONmp-PYMXmtgsBlQkNBRBpdQA== +0 -0
  207. package/Tests/Artifacts/LottieTests.xcresult/Data/refs.0~hrhCl-YRAAr8ByNB_LCgEBsVNHMp92gTIUknetpUHMjcXl4Hpn_uY-h6C45oga0ZALnfGCo6iKTmiPLa4Qvnpg== +0 -0
  208. package/Tests/Artifacts/LottieTests.xcresult/Data/refs.0~n2yoR7JsyL4DSUwmjnpE4Iq9Qi_eeZrmpPU8cdehDFKfESK7nwxXxfrSMQbk0BQ2lgGPadoRcd1-qr1xVz97jA== +0 -0
  209. package/Tests/Artifacts/LottieTests.xcresult/Data/refs.0~nMCcZm8WvPogyO_nuJ926Q3Q2dqVMN2LdjEL1Kq2wJ_RG-rH-e_6v41l1xZbCsQTa3XykQdEiXNc0HtAvT6IRA== +0 -0
  210. package/Tests/Artifacts/LottieTests.xcresult/Data/refs.0~oc3C7xkUt-OWDL6rrsxs-seS4Fu1bqBWAAXCHalgShaGg9MUrOiRbHT2DcAnhyQFKx6x5FRbvjmYoQWrQiXJZA== +0 -0
  211. package/Tests/Artifacts/LottieTests.xcresult/Data/refs.0~p-ihj7SEgkDXpMu9hvKE_wiX9cvtwyXrdIn964BfedXHKGpC6o7mMPxEyC0kRPVi_EZs_MRV5bAPEpl5h5we0g== +0 -0
  212. package/Tests/Artifacts/LottieTests.xcresult/Data/refs.0~qlhO_D9oE8uSKH-mZqyRF9pp4Zv1Tv0dIYcqrH4hb1VWlIxcdxmg2j0M8496cQeFXC5bn_JMXdBlD-d6cnFF8w== +0 -0
  213. package/Tests/Artifacts/LottieTests.xcresult/Data/refs.0~tjpiyIxJR_boTdUNrtFDuKIZoY84fI4lA1oMJbq9e2ZmYKIK5FeRN2O8cV_yMOYJGr4lbv03kTmT70mCjUc2_Q== +0 -0
  214. package/Tests/Artifacts/LottieTests.xcresult/Data/refs.0~wULeoj18eEKJWAKx1uFQVwS48cUGFcYPRJQj1Ro5XNJsWCwppGSCdIPhwifD6Z2f_j3zfI2SmC2Gg81sBXXW7g== +0 -0
  215. package/Tests/Artifacts/LottieTests.xcresult/Data/refs.0~zrEihMys4NVV5rx6FmuzEGO2TjloI3OiC7yzIhvqYoRo43ibb2F-Km6Jf4NX-ac62pOLBYZRcjQTvYMpn75_oA== +0 -0
  216. package/Tests/Artifacts/LottieTests.xcresult/Info.plist +0 -29
  217. package/Tests/Samples/9squares_AlBoardman.json +0 -1
  218. package/Tests/Samples/Boat_Loader.json +0 -1
  219. package/Tests/Samples/HamburgerArrow.json +0 -1
  220. package/Tests/Samples/IconTransitions.json +0 -1
  221. package/Tests/Samples/Images/dog.png +0 -0
  222. package/Tests/Samples/Issues/issue_1403.json +0 -1
  223. package/Tests/Samples/Issues/issue_1407.json +0 -1
  224. package/Tests/Samples/Issues/issue_1488.json +0 -1
  225. package/Tests/Samples/Issues/issue_1505.json +0 -1
  226. package/Tests/Samples/Issues/issue_1628.json +0 -1
  227. package/Tests/Samples/Issues/pr_1536.json +0 -1
  228. package/Tests/Samples/Issues/pr_1563.json +0 -8439
  229. package/Tests/Samples/Issues/pr_1592.json +0 -5527
  230. package/Tests/Samples/Issues/pr_1599.json +0 -738
  231. package/Tests/Samples/Issues/pr_1604_1.json +0 -1
  232. package/Tests/Samples/Issues/pr_1604_2.json +0 -1
  233. package/Tests/Samples/LottieFiles/LICENSE.md +0 -14
  234. package/Tests/Samples/LottieFiles/bounce_strokes.json +0 -1
  235. package/Tests/Samples/LottieFiles/cactus.json +0 -1
  236. package/Tests/Samples/LottieFiles/dog_car_ride.json +0 -1
  237. package/Tests/Samples/LottieFiles/draft_icon.json +0 -1
  238. package/Tests/Samples/LottieFiles/gradient_1.json +0 -1
  239. package/Tests/Samples/LottieFiles/gradient_2.json +0 -1
  240. package/Tests/Samples/LottieFiles/gradient_pill.json +0 -1
  241. package/Tests/Samples/LottieFiles/gradient_shapes.json +0 -1
  242. package/Tests/Samples/LottieFiles/gradient_square.json +0 -1
  243. package/Tests/Samples/LottieFiles/growth.json +0 -1
  244. package/Tests/Samples/LottieFiles/infinity_loader.json +0 -1
  245. package/Tests/Samples/LottieFiles/loading_dots_1.json +0 -1
  246. package/Tests/Samples/LottieFiles/loading_dots_2.json +0 -1
  247. package/Tests/Samples/LottieFiles/loading_dots_3.json +0 -1
  248. package/Tests/Samples/LottieFiles/loading_gradient_strokes.json +0 -1
  249. package/Tests/Samples/LottieFiles/settings_slider.json +0 -1
  250. package/Tests/Samples/LottieFiles/shop.json +0 -1
  251. package/Tests/Samples/LottieFiles/step_loader.json +0 -1
  252. package/Tests/Samples/LottieLogo1.json +0 -1
  253. package/Tests/Samples/LottieLogo1_masked.json +0 -1
  254. package/Tests/Samples/LottieLogo2.json +0 -1
  255. package/Tests/Samples/MotionCorpse_Jrcanest.json +0 -1
  256. package/Tests/Samples/Nonanimating/BasicLayers.json +0 -1
  257. package/Tests/Samples/Nonanimating/DisableNodesTest.json +0 -1
  258. package/Tests/Samples/Nonanimating/FirstText.json +0 -1
  259. package/Tests/Samples/Nonanimating/GeometryTransformTest.json +0 -1
  260. package/Tests/Samples/Nonanimating/Text_AnimatedProperties.json +0 -1
  261. package/Tests/Samples/Nonanimating/Text_Glyph.json +0 -1
  262. package/Tests/Samples/Nonanimating/Text_NoAnimation.json +0 -1
  263. package/Tests/Samples/Nonanimating/Text_NoGlyph.json +0 -1
  264. package/Tests/Samples/Nonanimating/Zoom.json +0 -1
  265. package/Tests/Samples/Nonanimating/_dog.json +0 -1
  266. package/Tests/Samples/Nonanimating/base64Test.json +0 -1
  267. package/Tests/Samples/Nonanimating/blend_mode_test.json +0 -1
  268. package/Tests/Samples/Nonanimating/keypathTest.json +0 -1
  269. package/Tests/Samples/Nonanimating/verifyLineHeight.json +0 -1
  270. package/Tests/Samples/PinJump.json +0 -1
  271. package/Tests/Samples/Private/BrokenLottieFiles/growth_man.json +0 -874
  272. package/Tests/Samples/Private/BrokenLottieFiles/rocket.json +0 -1
  273. package/Tests/Samples/Private/China_EmptyState_Itinerary.json +0 -1
  274. package/Tests/Samples/Private/LoaderHourglass.json +0 -12070
  275. package/Tests/Samples/Private/README.md +0 -7
  276. package/Tests/Samples/Private/Urgency/alarm_animated.json +0 -1
  277. package/Tests/Samples/Private/Urgency/diamond_animated.json +0 -1
  278. package/Tests/Samples/Private/Urgency/eye_animated.json +0 -1
  279. package/Tests/Samples/Private/Urgency/light_bulb_animated.json +0 -1
  280. package/Tests/Samples/Private/Urgency/light_bulb_static.json +0 -1
  281. package/Tests/Samples/Private/Urgency/piggy_bank_static.json +0 -1
  282. package/Tests/Samples/Private/Urgency/price_tag_legacy.json +0 -1
  283. package/Tests/Samples/Private/Urgency/rausch_alarm.json +0 -1
  284. package/Tests/Samples/Private/Urgency/rausch_alert.json +0 -1
  285. package/Tests/Samples/Private/Urgency/rausch_clock.json +0 -1
  286. package/Tests/Samples/Private/Urgency/rausch_diamond.json +0 -1
  287. package/Tests/Samples/Private/Urgency/rausch_money.json +0 -1
  288. package/Tests/Samples/Private/Urgency/rausch_piggy_bank.json +0 -1
  289. package/Tests/Samples/Private/Urgency/rausch_tag.json +0 -1
  290. package/Tests/Samples/Private/Urgency/red_envelope_animated.json +0 -1
  291. package/Tests/Samples/Private/Urgency/tag_animated.json +0 -1
  292. package/Tests/Samples/Private/Urgency/trophy_animated.json +0 -1
  293. package/Tests/Samples/Private/Urgency/wings_key_animated.json +0 -1
  294. package/Tests/Samples/Private/_flexible.json +0 -1
  295. package/Tests/Samples/Private/aircover.json +0 -1
  296. package/Tests/Samples/Private/belo_spin_rausch.json +0 -1
  297. package/Tests/Samples/Private/celebration.json +0 -2821
  298. package/Tests/Samples/Private/checkbox.json +0 -1
  299. package/Tests/Samples/Private/checkbox_small.json +0 -1
  300. package/Tests/Samples/Private/getting_your_trip_ready.json +0 -3540
  301. package/Tests/Samples/Private/gradient_afternoon.json +0 -1
  302. package/Tests/Samples/Private/gradient_brand.json +0 -1
  303. package/Tests/Samples/Private/gradient_evening.json +0 -1
  304. package/Tests/Samples/Private/gradient_morning.json +0 -1
  305. package/Tests/Samples/Private/issue_1467.json +0 -1
  306. package/Tests/Samples/Private/loading_dots.json +0 -1
  307. package/Tests/Samples/Private/loading_dots_small.json +0 -1
  308. package/Tests/Samples/Private/payment_loader.json +0 -1
  309. package/Tests/Samples/Private/radio_button.json +0 -1
  310. package/Tests/Samples/Private/selfie_intro.json +0 -1
  311. package/Tests/Samples/Private/stepper_add.json +0 -1
  312. package/Tests/Samples/Private/stepper_subtract.json +0 -1
  313. package/Tests/Samples/Private/switch.json +0 -1
  314. package/Tests/Samples/Private/thumb.json +0 -1
  315. package/Tests/Samples/Private/toggle_no.json +0 -1
  316. package/Tests/Samples/Private/toggle_yes.json +0 -1
  317. package/Tests/Samples/Private/user_error_black_and_white.json +0 -1
  318. package/Tests/Samples/Private/user_error_cut_off.json +0 -1
  319. package/Tests/Samples/Switch.json +0 -1
  320. package/Tests/Samples/Switch_States.json +0 -1
  321. package/Tests/Samples/TwitterHeart.json +0 -1
  322. package/Tests/Samples/TwitterHeartButton.json +0 -1
  323. package/Tests/Samples/TypeFace/A.json +0 -1
  324. package/Tests/Samples/TypeFace/Apostrophe.json +0 -1
  325. package/Tests/Samples/TypeFace/B.json +0 -1
  326. package/Tests/Samples/TypeFace/BlinkingCursor.json +0 -1
  327. package/Tests/Samples/TypeFace/C.json +0 -1
  328. package/Tests/Samples/TypeFace/Colon.json +0 -1
  329. package/Tests/Samples/TypeFace/Comma.json +0 -1
  330. package/Tests/Samples/TypeFace/D.json +0 -1
  331. package/Tests/Samples/TypeFace/E.json +0 -1
  332. package/Tests/Samples/TypeFace/F.json +0 -1
  333. package/Tests/Samples/TypeFace/G.json +0 -1
  334. package/Tests/Samples/TypeFace/H.json +0 -1
  335. package/Tests/Samples/TypeFace/I.json +0 -1
  336. package/Tests/Samples/TypeFace/J.json +0 -1
  337. package/Tests/Samples/TypeFace/K.json +0 -1
  338. package/Tests/Samples/TypeFace/L.json +0 -1
  339. package/Tests/Samples/TypeFace/M.json +0 -1
  340. package/Tests/Samples/TypeFace/N.json +0 -1
  341. package/Tests/Samples/TypeFace/O.json +0 -1
  342. package/Tests/Samples/TypeFace/P.json +0 -1
  343. package/Tests/Samples/TypeFace/Q.json +0 -1
  344. package/Tests/Samples/TypeFace/R.json +0 -1
  345. package/Tests/Samples/TypeFace/S.json +0 -1
  346. package/Tests/Samples/TypeFace/T.json +0 -1
  347. package/Tests/Samples/TypeFace/U.json +0 -1
  348. package/Tests/Samples/TypeFace/V.json +0 -1
  349. package/Tests/Samples/TypeFace/W.json +0 -1
  350. package/Tests/Samples/TypeFace/X.json +0 -1
  351. package/Tests/Samples/TypeFace/Y.json +0 -1
  352. package/Tests/Samples/TypeFace/Z.json +0 -1
  353. package/Tests/Samples/Watermelon.json +0 -1
  354. package/Tests/Samples/setValueTest.json +0 -1
  355. package/Tests/Samples/timeremap.json +0 -1
  356. package/Tests/Samples/vcTransition1.json +0 -1
  357. package/Tests/Samples/vcTransition2.json +0 -1
  358. package/script/lint/airbnb.swiftformat +0 -68
  359. package/script/lint/swiftlint.yml +0 -38
  360. package/script/test-carthage/Carthage/Build/.lottie-ios.version +0 -19
  361. package/script/test-carthage/Carthage/Build/Lottie.xcframework/Info.plist +0 -46
  362. package/script/test-carthage/Carthage/Build/Lottie.xcframework/ios-arm64/BCSymbolMaps/BF971162-BE99-3507-B5B3-11947DC6B176.bcsymbolmap +0 -14778
  363. package/script/test-carthage/Carthage/Build/Lottie.xcframework/ios-arm64/Lottie.framework/Headers/Lottie-Swift.h +0 -673
  364. package/script/test-carthage/Carthage/Build/Lottie.xcframework/ios-arm64/Lottie.framework/Info.plist +0 -0
  365. package/script/test-carthage/Carthage/Build/Lottie.xcframework/ios-arm64/Lottie.framework/Lottie +0 -0
  366. package/script/test-carthage/Carthage/Build/Lottie.xcframework/ios-arm64/Lottie.framework/Modules/Lottie.swiftmodule/arm64-apple-ios.swiftdoc +0 -0
  367. package/script/test-carthage/Carthage/Build/Lottie.xcframework/ios-arm64/Lottie.framework/Modules/Lottie.swiftmodule/arm64-apple-ios.swiftmodule +0 -0
  368. package/script/test-carthage/Carthage/Build/Lottie.xcframework/ios-arm64/Lottie.framework/Modules/Lottie.swiftmodule/arm64.swiftdoc +0 -0
  369. package/script/test-carthage/Carthage/Build/Lottie.xcframework/ios-arm64/Lottie.framework/Modules/Lottie.swiftmodule/arm64.swiftmodule +0 -0
  370. package/script/test-carthage/Carthage/Build/Lottie.xcframework/ios-arm64/Lottie.framework/Modules/module.modulemap +0 -4
  371. package/script/test-carthage/Carthage/Build/Lottie.xcframework/ios-arm64/dSYMs/Lottie.framework.dSYM/Contents/Info.plist +0 -20
  372. package/script/test-carthage/Carthage/Build/Lottie.xcframework/ios-arm64/dSYMs/Lottie.framework.dSYM/Contents/Resources/DWARF/Lottie +0 -0
  373. package/script/test-carthage/Carthage/Build/Lottie.xcframework/ios-arm64_x86_64-simulator/Lottie.framework/Headers/Lottie-Swift.h +0 -1352
  374. package/script/test-carthage/Carthage/Build/Lottie.xcframework/ios-arm64_x86_64-simulator/Lottie.framework/Info.plist +0 -0
  375. package/script/test-carthage/Carthage/Build/Lottie.xcframework/ios-arm64_x86_64-simulator/Lottie.framework/Lottie +0 -0
  376. 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
  377. package/script/test-carthage/Carthage/Build/Lottie.xcframework/ios-arm64_x86_64-simulator/Lottie.framework/Modules/Lottie.swiftmodule/Project/arm64.swiftsourceinfo +0 -0
  378. 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
  379. package/script/test-carthage/Carthage/Build/Lottie.xcframework/ios-arm64_x86_64-simulator/Lottie.framework/Modules/Lottie.swiftmodule/Project/x86_64.swiftsourceinfo +0 -0
  380. 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
  381. 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
  382. package/script/test-carthage/Carthage/Build/Lottie.xcframework/ios-arm64_x86_64-simulator/Lottie.framework/Modules/Lottie.swiftmodule/arm64.swiftdoc +0 -0
  383. package/script/test-carthage/Carthage/Build/Lottie.xcframework/ios-arm64_x86_64-simulator/Lottie.framework/Modules/Lottie.swiftmodule/arm64.swiftmodule +0 -0
  384. 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
  385. 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
  386. package/script/test-carthage/Carthage/Build/Lottie.xcframework/ios-arm64_x86_64-simulator/Lottie.framework/Modules/Lottie.swiftmodule/x86_64.swiftdoc +0 -0
  387. package/script/test-carthage/Carthage/Build/Lottie.xcframework/ios-arm64_x86_64-simulator/Lottie.framework/Modules/Lottie.swiftmodule/x86_64.swiftmodule +0 -0
  388. package/script/test-carthage/Carthage/Build/Lottie.xcframework/ios-arm64_x86_64-simulator/Lottie.framework/Modules/module.modulemap +0 -4
  389. package/script/test-carthage/Carthage/Build/Lottie.xcframework/ios-arm64_x86_64-simulator/Lottie.framework/_CodeSignature/CodeResources +0 -256
  390. package/script/test-carthage/Carthage/Build/Lottie.xcframework/ios-arm64_x86_64-simulator/dSYMs/Lottie.framework.dSYM/Contents/Info.plist +0 -20
  391. package/script/test-carthage/Carthage/Build/Lottie.xcframework/ios-arm64_x86_64-simulator/dSYMs/Lottie.framework.dSYM/Contents/Resources/DWARF/Lottie +0 -0
  392. package/script/test-carthage/Carthage/Checkouts/lottie-ios/Lottie.xcodeproj/project.xcworkspace/xcuserdata/cal.xcuserdatad/UserInterfaceState.xcuserstate +0 -0
  393. package/script/test-carthage/Carthage/Checkouts/lottie-ios/Lottie.xcodeproj/xcuserdata/cal.xcuserdatad/xcschemes/xcschememanagement.plist +0 -37
  394. package/script/test-carthage/Carthage/Checkouts/lottie-ios/Lottie.xcworkspace/xcuserdata/cal.xcuserdatad/UserInterfaceState.xcuserstate +0 -0
@@ -17,6 +17,7 @@ final class CoreAnimationLayer: BaseAnimationLayer {
17
17
  init(
18
18
  animation: Animation,
19
19
  imageProvider: AnimationImageProvider,
20
+ textProvider: AnimationTextProvider,
20
21
  fontProvider: AnimationFontProvider,
21
22
  compatibilityTrackerMode: CompatibilityTracker.Mode,
22
23
  logger: LottieLogger)
@@ -24,6 +25,7 @@ final class CoreAnimationLayer: BaseAnimationLayer {
24
25
  {
25
26
  self.animation = animation
26
27
  self.imageProvider = imageProvider
28
+ self.textProvider = textProvider
27
29
  self.fontProvider = fontProvider
28
30
  self.logger = logger
29
31
  compatibilityTracker = CompatibilityTracker(mode: compatibilityTrackerMode, logger: logger)
@@ -44,6 +46,7 @@ final class CoreAnimationLayer: BaseAnimationLayer {
44
46
  animation = typedLayer.animation
45
47
  currentAnimationConfiguration = typedLayer.currentAnimationConfiguration
46
48
  imageProvider = typedLayer.imageProvider
49
+ textProvider = typedLayer.textProvider
47
50
  fontProvider = typedLayer.fontProvider
48
51
  didSetUpAnimation = typedLayer.didSetUpAnimation
49
52
  compatibilityTracker = typedLayer.compatibilityTracker
@@ -92,6 +95,16 @@ final class CoreAnimationLayer: BaseAnimationLayer {
92
95
  didSet { reloadImages() }
93
96
  }
94
97
 
98
+ /// The `AnimationTextProvider` that `TextLayer`'s use to retrieve texts,
99
+ /// that they should use to render their text context
100
+ var textProvider: AnimationTextProvider {
101
+ didSet {
102
+ // We need to rebuild the current animation after updating the text provider,
103
+ // since this is used in `TextLayer.setupAnimations(context:)`
104
+ rebuildCurrentAnimation()
105
+ }
106
+ }
107
+
95
108
  /// The `FontProvider` that `TextLayer`s use to retrieve the `CTFont`
96
109
  /// that they should use to render their text content
97
110
  var fontProvider: AnimationFontProvider {
@@ -203,6 +216,7 @@ final class CoreAnimationLayer: BaseAnimationLayer {
203
216
  LayerContext(
204
217
  animation: animation,
205
218
  imageProvider: imageProvider,
219
+ textProvider: textProvider,
206
220
  fontProvider: fontProvider,
207
221
  compatibilityTracker: compatibilityTracker,
208
222
  layerName: "root layer")
@@ -234,6 +248,7 @@ final class CoreAnimationLayer: BaseAnimationLayer {
234
248
  compatibilityTracker: compatibilityTracker,
235
249
  logger: logger,
236
250
  currentKeypath: AnimationKeypath(keys: []),
251
+ textProvider: textProvider,
237
252
  logHierarchyKeypaths: configuration.logHierarchyKeypaths)
238
253
 
239
254
  // Perform a layout pass if necessary so all of the sublayers
@@ -264,6 +279,11 @@ final class CoreAnimationLayer: BaseAnimationLayer {
264
279
 
265
280
  let timedProgressAnimation = animationProgressTracker.timed(with: context, for: self)
266
281
  timedProgressAnimation.delegate = currentAnimationConfiguration?.animationContext.closure
282
+
283
+ // Remove the progress animation once complete so we know when the animation
284
+ // has finished playing (if it doesn't loop infinitely)
285
+ timedProgressAnimation.isRemovedOnCompletion = true
286
+
267
287
  add(timedProgressAnimation, forKey: #keyPath(animationProgress))
268
288
  }
269
289
 
@@ -309,11 +329,18 @@ extension CoreAnimationLayer: RootAnimationLayer {
309
329
  }
310
330
 
311
331
  var isAnimationPlaying: Bool? {
312
- switch playbackState {
332
+ switch pendingAnimationConfiguration?.playbackState {
313
333
  case .playing:
314
334
  return true
315
- case nil, .paused:
335
+ case .paused:
316
336
  return false
337
+ case nil:
338
+ switch playbackState {
339
+ case .playing:
340
+ return animation(forKey: #keyPath(animationProgress)) != nil
341
+ case nil, .paused:
342
+ return false
343
+ }
317
344
  }
318
345
  }
319
346
 
@@ -378,15 +405,6 @@ extension CoreAnimationLayer: RootAnimationLayer {
378
405
  (sublayers ?? []).filter { $0 is AnimationLayer }
379
406
  }
380
407
 
381
- var textProvider: AnimationTextProvider {
382
- get { DictionaryTextProvider([:]) }
383
- set {
384
- logger.assertionFailure("""
385
- The Core Animation rendering engine currently doesn't support `textProvider`s")
386
- """)
387
- }
388
- }
389
-
390
408
  func reloadImages() {
391
409
  // When the image provider changes, we have to update all `ImageLayer`s
392
410
  // so they can query the most up-to-date image from the new image provider.
@@ -23,7 +23,7 @@ extension KeyframeGroup {
23
23
  fileID _: StaticString = #fileID,
24
24
  line _: UInt = #line)
25
25
  throws
26
- -> Keyframe<T>
26
+ -> T
27
27
  {
28
28
  try context.compatibilityAssert(
29
29
  keyframes.count == 1,
@@ -32,6 +32,6 @@ extension KeyframeGroup {
32
32
  for \(description) values (due to limitations of Core Animation `CAKeyframeAnimation`s).
33
33
  """)
34
34
 
35
- return keyframes[0]
35
+ return keyframes[0].value
36
36
  }
37
37
  }
@@ -4,34 +4,113 @@
4
4
  // MARK: - Keyframes
5
5
 
6
6
  enum Keyframes {
7
- /// Combines the given `[KeyframeGroup]` of `Keyframe<T>`s
8
- /// into a single `KeyframeGroup` of `Keyframe<[T]>`s
9
- /// if all of the `KeyframeGroup`s have the exact same animation timing
10
- static func combinedIfPossible<T>(_ groups: [KeyframeGroup<T>]) -> KeyframeGroup<[T]>? {
7
+
8
+ // MARK: Internal
9
+
10
+ /// Combines the given keyframe groups of `Keyframe<T>`s into a single keyframe group of
11
+ /// of `Keyframe<[T]>`s if all of the `KeyframeGroup`s have the exact same animation timing
12
+ static func combinedIfPossible<T>(_ allGroups: [KeyframeGroup<T>]) -> KeyframeGroup<[T]>? {
13
+ combinedIfPossible(allGroups, makeCombinedResult: { index in
14
+ allGroups.map { $0.valueForCombinedKeyframes(at: index) }
15
+ })
16
+ }
17
+
18
+ /// Combines the given keyframe groups of `Keyframe<T>`s into a single keyframe group of
19
+ /// of `Keyframe<[T]>`s if all of the `KeyframeGroup`s have the exact same animation timing
20
+ static func combinedIfPossible<T1, T2, CombinedResult>(
21
+ _ k1: KeyframeGroup<T1>,
22
+ _ k2: KeyframeGroup<T2>,
23
+ makeCombinedResult: (T1, T2) -> CombinedResult)
24
+ -> KeyframeGroup<CombinedResult>?
25
+ {
26
+ combinedIfPossible(
27
+ [k1, k2],
28
+ makeCombinedResult: { index in
29
+ makeCombinedResult(
30
+ k1.valueForCombinedKeyframes(at: index),
31
+ k2.valueForCombinedKeyframes(at: index))
32
+ })
33
+ }
34
+
35
+ /// Combines the given keyframe groups of `Keyframe<T>`s into a single keyframe group of
36
+ /// of `Keyframe<[T]>`s if all of the `KeyframeGroup`s have the exact same animation timing
37
+ static func combinedIfPossible<T1, T2, T3, CombinedResult>(
38
+ _ k1: KeyframeGroup<T1>,
39
+ _ k2: KeyframeGroup<T2>,
40
+ _ k3: KeyframeGroup<T3>,
41
+ makeCombinedResult: (T1, T2, T3) -> CombinedResult)
42
+ -> KeyframeGroup<CombinedResult>?
43
+ {
44
+ combinedIfPossible(
45
+ [k1, k2, k3],
46
+ makeCombinedResult: { index in
47
+ makeCombinedResult(
48
+ k1.valueForCombinedKeyframes(at: index),
49
+ k2.valueForCombinedKeyframes(at: index),
50
+ k3.valueForCombinedKeyframes(at: index))
51
+ })
52
+ }
53
+
54
+ /// Combines the given keyframe groups of `Keyframe<T>`s into a single keyframe group of
55
+ /// of `Keyframe<[T]>`s if all of the `KeyframeGroup`s have the exact same animation timing
56
+ static func combinedIfPossible<T1, T2, T3, T4, T5, T6, T7, CombinedResult>(
57
+ _ k1: KeyframeGroup<T1>,
58
+ _ k2: KeyframeGroup<T2>,
59
+ _ k3: KeyframeGroup<T3>,
60
+ _ k4: KeyframeGroup<T4>,
61
+ _ k5: KeyframeGroup<T5>,
62
+ _ k6: KeyframeGroup<T6>,
63
+ _ k7: KeyframeGroup<T7>,
64
+ makeCombinedResult: (T1, T2, T3, T4, T5, T6, T7) -> CombinedResult)
65
+ -> KeyframeGroup<CombinedResult>?
66
+ {
67
+ combinedIfPossible(
68
+ [k1, k2, k3, k4, k5, k6, k7],
69
+ makeCombinedResult: { index in
70
+ makeCombinedResult(
71
+ k1.valueForCombinedKeyframes(at: index),
72
+ k2.valueForCombinedKeyframes(at: index),
73
+ k3.valueForCombinedKeyframes(at: index),
74
+ k4.valueForCombinedKeyframes(at: index),
75
+ k5.valueForCombinedKeyframes(at: index),
76
+ k6.valueForCombinedKeyframes(at: index),
77
+ k7.valueForCombinedKeyframes(at: index))
78
+ })
79
+ }
80
+
81
+ // MARK: Private
82
+
83
+ /// Combines the given `[KeyframeGroup]` of `Keyframe<T>`s into a single `KeyframeGroup`
84
+ /// of `Keyframe<CombinedResult>`s if all of the `KeyframeGroup`s have the exact same animation timing
85
+ private static func combinedIfPossible<CombinedResult>(
86
+ _ allGroups: [AnyKeyframeGroup],
87
+ makeCombinedResult: (_ index: Int) -> CombinedResult)
88
+ -> KeyframeGroup<CombinedResult>?
89
+ {
90
+ let untypedGroups = allGroups.map { $0.untyped }
91
+
92
+ // Animations with no timing information (e.g. with just a single keyframe)
93
+ // can be trivially combined with any other set of keyframes, so we don't need
94
+ // to check those.
95
+ let animatingKeyframes = untypedGroups.filter { $0.keyframes.count > 1 }
96
+
11
97
  guard
12
- !groups.isEmpty,
13
- groups.allSatisfy({ $0.hasSameTimingParameters(as: groups[0]) })
98
+ !allGroups.isEmpty,
99
+ animatingKeyframes.allSatisfy({ $0.hasSameTimingParameters(as: animatingKeyframes[0]) })
14
100
  else { return nil }
15
101
 
16
- var combinedKeyframes = ContiguousArray<Keyframe<[T]>>()
102
+ var combinedKeyframes = ContiguousArray<Keyframe<CombinedResult>>()
103
+ let baseKeyframes = (animatingKeyframes.first ?? untypedGroups[0]).keyframes
17
104
 
18
- for index in groups[0].keyframes.indices {
19
- let baseKeyframe = groups[0].keyframes[index]
20
- let combinedValues = groups.map { $0.keyframes[index].value }
21
- combinedKeyframes.append(baseKeyframe.withValue(combinedValues))
105
+ for index in baseKeyframes.indices {
106
+ let baseKeyframe = baseKeyframes[index]
107
+ let combinedValue = makeCombinedResult(index)
108
+ combinedKeyframes.append(baseKeyframe.withValue(combinedValue))
22
109
  }
23
110
 
24
111
  return KeyframeGroup(keyframes: combinedKeyframes)
25
112
  }
26
113
 
27
- /// Combines the given `[KeyframeGroup?]` of `Keyframe<T>`s
28
- /// into a single `KeyframeGroup` of `Keyframe<[T]>`s
29
- /// if all of the `KeyframeGroup`s have the exact same animation timing
30
- static func combinedIfPossible<T>(_ groups: [KeyframeGroup<T>?]) -> KeyframeGroup<[T]>? {
31
- let nonOptionalGroups = groups.compactMap { $0 }
32
- guard nonOptionalGroups.count == groups.count else { return nil }
33
- return combinedIfPossible(nonOptionalGroups)
34
- }
35
114
  }
36
115
 
37
116
  extension KeyframeGroup {
@@ -49,13 +128,27 @@ extension KeyframeGroup {
49
128
  }
50
129
 
51
130
  extension Keyframe {
52
- /// Whether or not this keyframe has the same timing parameters as the given keyframe
53
- func hasSameTimingParameters<T>(as other: Keyframe<T>) -> Bool {
131
+ /// Whether or not this keyframe has the same timing parameters as the given keyframe,
132
+ /// excluding `spatialInTangent` and `spatialOutTangent`.
133
+ fileprivate func hasSameTimingParameters<T>(as other: Keyframe<T>) -> Bool {
54
134
  time == other.time
55
135
  && isHold == other.isHold
56
136
  && inTangent == other.inTangent
57
137
  && outTangent == other.outTangent
58
- && spatialInTangent == other.spatialInTangent
59
- && spatialOutTangent == other.spatialOutTangent
138
+ // We intentionally don't compare spatial in/out tangents,
139
+ // since those values are only used in very specific cases
140
+ // (animating the x/y position of a layer), which aren't ever
141
+ // combined in this way.
142
+ }
143
+ }
144
+
145
+ extension KeyframeGroup {
146
+ /// The value to use for a combined set of keyframes, for the given index
147
+ fileprivate func valueForCombinedKeyframes(at index: Int) -> T {
148
+ if keyframes.count == 1 {
149
+ return keyframes[0].value
150
+ } else {
151
+ return keyframes[index].value
152
+ }
60
153
  }
61
154
  }
@@ -41,6 +41,9 @@ struct LayerAnimationContext {
41
41
  /// The AnimationKeypath represented by the current layer
42
42
  var currentKeypath: AnimationKeypath
43
43
 
44
+ /// The `AnimationTextProvider`
45
+ var textProvider: AnimationTextProvider
46
+
44
47
  /// Whether or not to log `AnimationKeypath`s for all of the animation's layers
45
48
  /// - Used for `CoreAnimationLayer.logHierarchyKeypaths()`
46
49
  var logHierarchyKeypaths: Bool
@@ -63,6 +66,12 @@ struct LayerAnimationContext {
63
66
  animation.progressTime(forFrame: timeRemapping(frame), clamped: false)
64
67
  }
65
68
 
69
+ /// The real-time `TimeInterval` for the given `AnimationFrameTime` within this layer,
70
+ /// accounting for the `timeRemapping` applied to this layer
71
+ func time(for frame: AnimationFrameTime) -> TimeInterval {
72
+ animation.time(forFrame: timeRemapping(frame))
73
+ }
74
+
66
75
  /// Chains an additional `timeRemapping` closure onto this layer context
67
76
  func withTimeRemapping(
68
77
  _ additionalTimeRemapping: @escaping (AnimationFrameTime) -> AnimationFrameTime)
@@ -78,7 +78,8 @@ class BaseCompositionLayer: BaseAnimationLayer {
78
78
  private func setupSublayers() {
79
79
  if
80
80
  renderLayerContents,
81
- let masks = baseLayerModel.masks
81
+ let masks = baseLayerModel.masks?.filter({ $0.mode != .none }),
82
+ !masks.isEmpty
82
83
  {
83
84
  mask = MaskCompositionLayer(masks: masks)
84
85
  }
@@ -4,6 +4,9 @@
4
4
  import QuartzCore
5
5
 
6
6
  extension CALayer {
7
+
8
+ // MARK: Internal
9
+
7
10
  /// Sets up an `AnimationLayer` / `CALayer` hierarchy in this layer,
8
11
  /// using the given list of layers.
9
12
  @nonobjc
@@ -48,7 +51,7 @@ extension CALayer {
48
51
  }
49
52
 
50
53
  // Create an `AnimationLayer` for each `LayerModel`
51
- for (layerModel, maskLayerModel) in try layersInZAxisOrder.pairedLayersAndMasks(context: context) {
54
+ for (layerModel, mask) in try layersInZAxisOrder.pairedLayersAndMasks(context: context) {
52
55
  guard let layer = try layerModel.makeAnimationLayer(context: context) else {
53
56
  continue
54
57
  }
@@ -64,14 +67,14 @@ extension CALayer {
64
67
 
65
68
  // Create the `mask` layer for this layer, if it has a `MatteType`
66
69
  if
67
- let maskLayerModel = maskLayerModel,
68
- let maskLayer = try maskLayerModel.makeAnimationLayer(context: context)
70
+ let mask = mask,
71
+ let maskLayer = try maskLayer(for: mask.model, type: mask.matteType, context: context)
69
72
  {
70
73
  let maskParentTransformLayer = makeParentTransformLayer(
71
- childLayerModel: maskLayerModel,
74
+ childLayerModel: mask.model,
72
75
  childLayer: maskLayer,
73
76
  name: { parentLayerModel in
74
- "\(maskLayerModel.name) (mask of \(layerModel.name)) (parent, \(parentLayerModel.name))"
77
+ "\(mask.model.name) (mask of \(layerModel.name)) (parent, \(parentLayerModel.name))"
75
78
  })
76
79
 
77
80
  // Set up a parent container to host both the layer
@@ -96,6 +99,41 @@ extension CALayer {
96
99
  }
97
100
  }
98
101
 
102
+ // MARK: Fileprivate
103
+
104
+ /// Creates a mask `CALayer` from the given matte layer model, using the `MatteType`
105
+ /// from the layer that is being masked.
106
+ fileprivate func maskLayer(
107
+ for matteLayerModel: LayerModel,
108
+ type: MatteType,
109
+ context: LayerContext) throws
110
+ -> CALayer?
111
+ {
112
+ switch type {
113
+ case .add:
114
+ return try matteLayerModel.makeAnimationLayer(context: context)
115
+
116
+ case .invert:
117
+ guard let maskLayer = try matteLayerModel.makeAnimationLayer(context: context) else {
118
+ return nil
119
+ }
120
+
121
+ // We can invert the mask layer by having a large solid black layer with the
122
+ // given mask layer subtracted out using the `xor` blend mode. When applied to the
123
+ // layer being masked, this creates an inverted mask where only areas _outside_
124
+ // of the mask layer are visible.
125
+ // https://developer.apple.com/documentation/coregraphics/cgblendmode/xor
126
+ let base = BaseAnimationLayer()
127
+ base.backgroundColor = .rgb(0, 0, 0)
128
+ base.addSublayer(maskLayer)
129
+ maskLayer.compositingFilter = "xor"
130
+ return base
131
+
132
+ case .none, .unknown:
133
+ return nil
134
+ }
135
+ }
136
+
99
137
  }
100
138
 
101
139
  extension Collection where Element == LayerModel {
@@ -103,8 +141,10 @@ extension Collection where Element == LayerModel {
103
141
  /// a `LayerModel` to use as its mask, if applicable
104
142
  /// based on the layer's `MatteType` configuration.
105
143
  /// - Assumes the layers are sorted in z-axis order.
106
- fileprivate func pairedLayersAndMasks(context: LayerContext) throws -> [(layer: LayerModel, mask: LayerModel?)] {
107
- var layersAndMasks = [(layer: LayerModel, mask: LayerModel?)]()
144
+ fileprivate func pairedLayersAndMasks(context _: LayerContext) throws
145
+ -> [(layer: LayerModel, mask: (model: LayerModel, matteType: MatteType)?)]
146
+ {
147
+ var layersAndMasks = [(layer: LayerModel, mask: (model: LayerModel, matteType: MatteType)?)]()
108
148
  var unprocessedLayers = reversed()
109
149
 
110
150
  while let layer = unprocessedLayers.popLast() {
@@ -114,11 +154,7 @@ extension Collection where Element == LayerModel {
114
154
  matteType != .none,
115
155
  let maskLayer = unprocessedLayers.popLast()
116
156
  {
117
- try context.compatibilityAssert(
118
- matteType == .add,
119
- "The Core Animation rendering engine currently only supports `MatteMode.add`.")
120
-
121
- layersAndMasks.append((layer: layer, mask: maskLayer))
157
+ layersAndMasks.append((layer: layer, mask: (model: maskLayer, matteType: matteType)))
122
158
  }
123
159
 
124
160
  else {
@@ -59,7 +59,7 @@ final class GradientRenderLayer: CAGradientLayer {
59
59
  /// - This specific value is arbitrary and can be increased if necessary.
60
60
  /// Theoretically this should be "infinite", to match the behavior of
61
61
  /// `CGContext.drawLinearGradient` with `[.drawsAfterEndLocation, .drawsBeforeStartLocation]`.
62
- private let gradientPadding: CGFloat = 2_000
62
+ private let gradientPadding: CGFloat = 10_000
63
63
 
64
64
  private func updateLayout() {
65
65
  anchorPoint = .zero
@@ -70,9 +70,12 @@ final class GradientRenderLayer: CAGradientLayer {
70
70
  width: gradientPadding + gradientReferenceBounds.width + gradientPadding,
71
71
  height: gradientPadding + gradientReferenceBounds.height + gradientPadding)
72
72
 
73
+ // Align the center of this layer to be at the center point of its parent layer
74
+ let superlayerSize = superlayer?.frame.size ?? gradientReferenceBounds.size
75
+
73
76
  transform = CATransform3DMakeTranslation(
74
- -gradientPadding,
75
- -gradientPadding,
77
+ (superlayerSize.width - bounds.width) / 2,
78
+ (superlayerSize.height - bounds.height) / 2,
76
79
  0)
77
80
  }
78
81
 
@@ -83,5 +86,9 @@ final class GradientRenderLayer: CAGradientLayer {
83
86
  extension GradientRenderLayer: CustomLayoutLayer {
84
87
  func layout(superlayerBounds: CGRect) {
85
88
  gradientReferenceBounds = superlayerBounds
89
+
90
+ if let gradientMask = mask as? GradientRenderLayer {
91
+ gradientMask.layout(superlayerBounds: superlayerBounds)
92
+ }
86
93
  }
87
94
  }
@@ -9,6 +9,7 @@ import QuartzCore
9
9
  struct LayerContext {
10
10
  let animation: Animation
11
11
  let imageProvider: AnimationImageProvider
12
+ let textProvider: AnimationTextProvider
12
13
  let fontProvider: AnimationFontProvider
13
14
  let compatibilityTracker: CompatibilityTracker
14
15
  var layerName: String
@@ -27,6 +28,10 @@ extension LayerModel {
27
28
  func makeAnimationLayer(context: LayerContext) throws -> BaseCompositionLayer? {
28
29
  let context = context.forLayer(self)
29
30
 
31
+ if hidden {
32
+ return TransformLayer(layerModel: self)
33
+ }
34
+
30
35
  switch (type, self) {
31
36
  case (.precomp, let preCompLayerModel as PreCompLayerModel):
32
37
  let preCompLayer = PreCompLayer(preCompLayer: preCompLayerModel)
@@ -74,7 +74,7 @@ extension MaskCompositionLayer: AnimationLayer {
74
74
  }
75
75
  }
76
76
 
77
- // MARK: - MaskLayer
77
+ // MARK: MaskCompositionLayer.MaskLayer
78
78
 
79
79
  extension MaskCompositionLayer {
80
80
  final class MaskLayer: CAShapeLayer {
@@ -68,12 +68,12 @@ final class PreCompLayer: BaseCompositionLayer {
68
68
  try setupLayerAnimations(context: context)
69
69
 
70
70
  // Precomp layers can adjust the local time of their child layers (relative to the
71
- // animation's global time) via `timeRemapping` or a custom `startTime`
71
+ // animation's global time) via `timeRemapping` or a custom `startTime` / `timeStretch`
72
72
  let contextForChildren = context.withTimeRemapping { [preCompLayer, timeRemappingInterpolator] layerLocalFrame in
73
73
  if let timeRemappingInterpolator = timeRemappingInterpolator {
74
74
  return timeRemappingInterpolator.value(frame: layerLocalFrame) as? AnimationFrameTime ?? layerLocalFrame
75
75
  } else {
76
- return layerLocalFrame + AnimationFrameTime(preCompLayer.startTime)
76
+ return (layerLocalFrame * AnimationFrameTime(preCompLayer.timeStretch)) + AnimationFrameTime(preCompLayer.startTime)
77
77
  }
78
78
  }
79
79
 
@@ -0,0 +1,85 @@
1
+ // Created by Cal Stephens on 8/1/22.
2
+ // Copyright © 2022 Airbnb Inc. All rights reserved.
3
+
4
+ import QuartzCore
5
+
6
+ // MARK: - RepeaterLayer
7
+
8
+ /// A layer that renders a child layer at some offset using a `Repeater`
9
+ final class RepeaterLayer: BaseAnimationLayer {
10
+
11
+ // MARK: Lifecycle
12
+
13
+ init(repeater: Repeater, childLayer: CALayer, index: Int) {
14
+ repeaterTransform = RepeaterTransform(repeater: repeater, index: index)
15
+ super.init()
16
+ addSublayer(childLayer)
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
+ repeaterTransform = typedLayer.repeaterTransform
31
+ super.init(layer: typedLayer)
32
+ }
33
+
34
+ // MARK: Internal
35
+
36
+ override func setupAnimations(context: LayerAnimationContext) throws {
37
+ try super.setupAnimations(context: context)
38
+ try addTransformAnimations(for: repeaterTransform, context: context)
39
+ }
40
+
41
+ // MARK: Private
42
+
43
+ private let repeaterTransform: RepeaterTransform
44
+
45
+ }
46
+
47
+ // MARK: - RepeaterTransform
48
+
49
+ /// A transform model created from a `Repeater`
50
+ private struct RepeaterTransform {
51
+
52
+ // MARK: Lifecycle
53
+
54
+ init(repeater: Repeater, index: Int) {
55
+ anchorPoint = repeater.anchorPoint
56
+ scale = repeater.scale
57
+
58
+ rotation = repeater.rotation.map { rotation in
59
+ Vector1D(rotation.value * Double(index))
60
+ }
61
+
62
+ position = repeater.position.map { position in
63
+ Vector3D(
64
+ x: position.x * Double(index),
65
+ y: position.y * Double(index),
66
+ z: position.z * Double(index))
67
+ }
68
+ }
69
+
70
+ // MARK: Internal
71
+
72
+ let anchorPoint: KeyframeGroup<Vector3D>
73
+ let position: KeyframeGroup<Vector3D>
74
+ let rotation: KeyframeGroup<Vector1D>
75
+ let scale: KeyframeGroup<Vector3D>
76
+
77
+ }
78
+
79
+ // MARK: TransformModel
80
+
81
+ extension RepeaterTransform: TransformModel {
82
+ var _position: KeyframeGroup<Vector3D>? { position }
83
+ var _positionX: KeyframeGroup<Vector1D>? { nil }
84
+ var _positionY: KeyframeGroup<Vector1D>? { nil }
85
+ }