[
  {
    "path": ".gitignore",
    "content": "# Build Folders (you can keep bin if you'd like, to store dlls and pdbs)\n[Bb]in/\n[Oo]bj/\n\n# mstest test results\nTestResults\n\n## Ignore Visual Studio temporary files, build results, and\n## files generated by popular Visual Studio add-ons.\n\n# User-specific files\n*.suo\n*.user\n*.sln.docstates\n\n# Build results\n[Dd]ebug/\n[Rr]elease/\nx64/\n*_i.c\n*_p.c\n*.ilk\n*.meta\n*.obj\n*.pch\n*.pdb\n*.pgc\n*.pgd\n*.rsp\n*.sbr\n*.tlb\n*.tli\n*.tlh\n*.tmp\n*.log\n*.vspscc\n*.vssscc\n.builds\n\n# Visual C++ cache files\nipch/\n*.aps\n*.ncb\n*.opensdf\n*.sdf\n\n# Visual Studio profiler\n*.psess\n*.vsp\n*.vspx\n\n# Guidance Automation Toolkit\n*.gpState\n\n# ReSharper is a .NET coding add-in\n_ReSharper*\n\n# NCrunch\n*.ncrunch*\n.*crunch*.local.xml\n\n# Installshield output folder \n[Ee]xpress\n\n# DocProject is a documentation generator add-in\nDocProject/buildhelp/\nDocProject/Help/*.HxT\nDocProject/Help/*.HxC\nDocProject/Help/*.hhc\nDocProject/Help/*.hhk\nDocProject/Help/*.hhp\nDocProject/Help/Html2\nDocProject/Help/html\n\n# Click-Once directory\npublish\n\n# Publish Web Output\n*.Publish.xml\n\n# NuGet Packages Directory\npackages\n\n# Windows Azure Build Output\ncsx\n*.build.csdef\n\n# Windows Store app package directory\nAppPackages/\n\n# Others\n[Bb]in\n[Oo]bj\nsql\nTestResults\n[Tt]est[Rr]esult*\n*.Cache\nClientBin\n[Ss]tyle[Cc]op.*\n~$*\n*.dbmdl\nGenerated_Code #added for RIA/Silverlight projects\n\n# Backup & report files from converting an old project file to a newer\n# Visual Studio version. Backup files are not needed, because we have git ;-)\n_UpgradeReport_Files/\nBackup*/\nUpgradeLog*.XML\n*.nupkg\n/.vs/*\n*.pfx\n"
  },
  {
    "path": "LICENSE",
    "content": "The MIT License (MIT)\n\nCopyright (c) 2016 Soroush\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n"
  },
  {
    "path": "README.md",
    "content": "# <img src=\"WinFormAnimation/Icon.png\" width=\"42\" alt=\"Icon\"> WinForm Animation Library [.Net3.5+]\n[![](https://img.shields.io/github/license/falahati/WinFormAnimation.svg?style=flat-square)](https://github.com/falahati/WinFormAnimation/blob/master/LICENSE)\n[![](https://img.shields.io/github/commit-activity/y/falahati/WinFormAnimation.svg?style=flat-square)](https://github.com/falahati/WinFormAnimation/commits/master)\n[![](https://img.shields.io/github/issues/falahati/WinFormAnimation.svg?style=flat-square)](https://github.com/falahati/WinFormAnimation/issues)\n\nA simple library for animating controls/values in .Net WinForm (.Net 3.5 and later). Key frame (Path) based and fully customizable.\n\n*Please note that even though this library designed for WinForm but its usage is not limited to WinForm and can be used in other environments. Only reference of the library is to 'System.Drawing' name space.*\n\n## How to get\n[![](https://img.shields.io/nuget/dt/WinFormAnimation.svg?style=flat-square)](https://www.nuget.org/packages/WinFormAnimation)\n[![](https://img.shields.io/nuget/v/WinFormAnimation.svg?style=flat-square)](https://www.nuget.org/packages/WinFormAnimation)\n\nThis library is available as a NuGet package at [nuget.org](https://www.nuget.org/packages/WinFormAnimation/).\n\n## Help me fund my own Death Star\n\n[![](https://img.shields.io/badge/crypto-CoinPayments-8a00a3.svg?style=flat-square)](https://www.coinpayments.net/index.php?cmd=_donate&reset=1&merchant=820707aded07845511b841f9c4c335cd&item_name=Donate&currency=USD&amountf=20.00000000&allow_amount=1&want_shipping=0&allow_extra=1)\n[![](https://img.shields.io/badge/shetab-ZarinPal-8a00a3.svg?style=flat-square)](https://zarinp.al/@falahati)\n[![](https://img.shields.io/badge/usd-Paypal-8a00a3.svg?style=flat-square)](https://www.paypal.com/cgi-bin/webscr?cmd=_donations&business=ramin.graphix@gmail.com&lc=US&item_name=Donate&no_note=0&cn=&curency_code=USD&bn=PP-DonationsBF:btn_donateCC_LG.gif:NonHosted)\n\n**--OR--**\n\nYou can always donate your time by contributing to the project or by introducing it to others..\n\n## Documentation\n\n* `Float2D`: A class containing two `float` values as Vertical and Horizontal coordinates representing a point in a 2D plane.\n* `Float3D`: A class containing three `float` values as Vertical, Horizontal and Depth coordinates representing a point in a 3D plane.\n* `Path`: A class containing a `float` starting and a `float` ending point for a single dimensional animation as well as duration and the function to control the animation.\n* `Path2D`: A class containing a `Float2D` starting and a `Float2D` ending point for a two dimensional animation as well as duration and the function to control the animation.\n* `Path3D`: A class containing a `Float3D` starting and a `Float3D` ending point for a three dimensional animation as well as duration and the function to control the animation.\n* `Animator`: A class for animating an array of `Path` objects. This class is one of the main classes and starting points of a basic animation.\n* `Animator2D`: A class for animating an array of `Path2D` objects. This class is one of the main classes and starting points of a basic animation.\n* `Animator2D`: A class for animating an array of `Path3D` objects. This class is one of the main classes and starting points of a basic animation.\n* `SafeInvoker`: A class holding a reference to a function to invoke in the correct thread, detected by a `Control` object passed to it. Useful for easier UI manipulations.\n* `SafeInvoker<T>`: Same as `SafeInvoker` class but with a generic argument for the function to invoke.\n\nFor full documentation of the classes and their members, please take a look at our doxygen page at [falahati.github.io](https://falahati.github.io/WinFormAnimation/doxygen).\n\n## Basic examples\n### ONE DIMENSIONAL ANIMATION OF A PROPERTY\nFollowing code animates a property named `Value` of a `ProgressBar` named `pb_progress` in 5 seconds from zero to one hundred:\n```C#\nnew Animator(new Path(0, 100, 5000))\n    .Play(pb_progress, Animator.KnownProperties.Value);\n```\n\n### TWO DIMENSIONAL ANIMATION OF A PROPERTY\nFollowing code animates a `Form` in two paths. First one moves the `Form` from (0, -100) to (100, 200) and second path waits for 3 seconds and then moved the `Form` to its initial location in 2 seconds. (`this` is a `Form`)\n```C#\nnew Animator2D(\n        new Path2D(0, 100, -100, 200, 5000).ContinueTo(this.Location.ToFloat2D(), 2000, 3000))\n    .Play(this, Animator2D.KnownProperties.Location);\n```\n\n### THREE DIMENSIONAL ANIMATION OF A PROPERTY\nFollowing code animates a property named `CustomColor` of a `Control` named `c_customLabel` in 2 seconds and after a delay of 1 second using the `AnimationFunctions.CubicEaseIn` function and with maximum of 10 frames per second.\n```C#\nnew Animator3D(\n        new Path3D(Color.Blue.ToFloat3D(), Color.Red.ToFloat3D(), 2000, 1000, AnimationFunctions.CubicEaseIn), \n        FPSLimiterKnownValues.LimitTen)\n    .Play(c_customLabel, \"CustomColor\");\n```\n\n\n### KEYFRAMES\nThere are extension methods for `Path`, `Path2D`, `Path3D` and their arrays to let you continue the path easily and define the key frames as fast as possible. For example, following code moves a `Control` named `c_control` in a rectangular path infinitely:\n```C#\nnew Animator2D(\n    new Path2D(new Float2D(100, 100), new Float2D(200, 100), 1000)\n        .ContinueTo(new Float2D(200, 200), 1000)\n        .ContinueTo(new Float2D(100, 200), 1000)\n        .ContinueTo(new Float2D(100, 100), 1000))\n{\n    Repeat = true\n}.Play(c_control, Animator2D.KnownProperties.Location);\n```\n\n### CALLBACKS\nIt is possible to define a custom callback as frame handler as well as defining a call back to handle the end of the animation. Following example will call a method named `CustomSetMethod` for setting new values and handle the frames, and starts the animation in reverse path after its end for one more time:\n\n```C#\nvar animator = new Animator(new Path(100, 200, 1000).ContinueTo(400, 500));\nanimator.Play(new SafeInvoker<float>(CustomSetMethod), new SafeInvoker(() =>\n{\n    animator.Paths = animator.Paths.Select(path => path.Reverse()).Reverse().ToArray();\n    animator.Play(new SafeInvoker<float>(CustomSetMethod));\n}));\n```\n\n## Demo\nCheck the 'WinFormAnimation.Samples' project for simple usage examples.\n![Screenshot](/screenshot.gif?raw=true \"Screenshot\")\n\n## License\nThe MIT License (MIT)\n\nCopyright (c) 2016-2020 Soroush Falahati\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n"
  },
  {
    "path": "WinFormAnimation/AnimationFunctions.cs",
    "content": "﻿using System;\n\nnamespace WinFormAnimation\n{\n    /// <summary>\n    ///     The functions gallery for animation\n    /// </summary>\n    public static class AnimationFunctions\n    {\n        /// <summary>\n        ///     The base delegate for defining new animation functions.\n        /// </summary>\n        /// <param name=\"time\">\n        ///     The time of the animation.\n        /// </param>\n        /// <param name=\"beginningValue\">\n        ///     The starting value.\n        /// </param>\n        /// <param name=\"changeInValue\">\n        ///     The different between starting and ending value.\n        /// </param>\n        /// <param name=\"duration\">\n        ///     The duration of the animations.\n        /// </param>\n        /// <returns>\n        ///     The calculated current value of the animation\n        /// </returns>\n        public delegate float Function(float time, float beginningValue, float changeInValue, float duration);\n\n        /// <summary>\n        ///     Returns a function delegate based on the the passed known animation function\n        /// </summary>\n        /// <param name=\"knownFunction\">The animation function</param>\n        /// <returns>Animation fucntion delegate</returns>\n        public static Function FromKnown(KnownAnimationFunctions knownFunction)\n        {\n            switch (knownFunction)\n            {\n                case KnownAnimationFunctions.CubicEaseIn:\n                    return CubicEaseIn;\n                case KnownAnimationFunctions.CubicEaseInOut:\n                    return CubicEaseInOut;\n                case KnownAnimationFunctions.CubicEaseOut:\n                    return CubicEaseOut;\n                case KnownAnimationFunctions.Linear:\n                    return Linear;\n                case KnownAnimationFunctions.CircularEaseInOut:\n                    return CircularEaseInOut;\n                case KnownAnimationFunctions.CircularEaseIn:\n                    return CircularEaseIn;\n                case KnownAnimationFunctions.CircularEaseOut:\n                    return CircularEaseOut;\n                case KnownAnimationFunctions.QuadraticEaseIn:\n                    return QuadraticEaseIn;\n                case KnownAnimationFunctions.QuadraticEaseOut:\n                    return QuadraticEaseOut;\n                case KnownAnimationFunctions.QuadraticEaseInOut:\n                    return QuadraticEaseInOut;\n                case KnownAnimationFunctions.QuarticEaseIn:\n                    return QuarticEaseIn;\n                case KnownAnimationFunctions.QuarticEaseOut:\n                    return QuarticEaseOut;\n                case KnownAnimationFunctions.QuarticEaseInOut:\n                    return QuarticEaseInOut;\n                case KnownAnimationFunctions.QuinticEaseInOut:\n                    return QuinticEaseInOut;\n                case KnownAnimationFunctions.QuinticEaseIn:\n                    return QuinticEaseIn;\n                case KnownAnimationFunctions.QuinticEaseOut:\n                    return QuinticEaseOut;\n                case KnownAnimationFunctions.SinusoidalEaseIn:\n                    return SinusoidalEaseIn;\n                case KnownAnimationFunctions.SinusoidalEaseOut:\n                    return SinusoidalEaseOut;\n                case KnownAnimationFunctions.SinusoidalEaseInOut:\n                    return SinusoidalEaseInOut;\n                case KnownAnimationFunctions.ExponentialEaseIn:\n                    return ExponentialEaseIn;\n                case KnownAnimationFunctions.ExponentialEaseOut:\n                    return ExponentialEaseOut;\n                case KnownAnimationFunctions.ExponentialEaseInOut:\n                    return ExponentialEaseInOut;\n                default:\n                    throw new ArgumentOutOfRangeException(nameof(knownFunction), knownFunction,\n                        \"The passed animation function is unknown.\");\n            }\n        }\n\n\n        /// <summary>\n        ///     The cubic ease-in animation function.\n        /// </summary>\n        /// <param name=\"t\">\n        ///     The time of the animation.\n        /// </param>\n        /// <param name=\"b\">\n        ///     The starting value.\n        /// </param>\n        /// <param name=\"c\">\n        ///     The different between starting and ending value.\n        /// </param>\n        /// <param name=\"d\">\n        ///     The duration of the animations.\n        /// </param>\n        /// <returns>\n        ///     The calculated current value of the animation\n        /// </returns>\n        public static float CubicEaseIn(float t, float b, float c, float d)\n        {\n            t /= d;\n            return c*t*t*t + b;\n        }\n\n        /// <summary>\n        ///     The cubic ease-in and ease-out animation function.\n        /// </summary>\n        /// <param name=\"t\">\n        ///     The time of the animation.\n        /// </param>\n        /// <param name=\"b\">\n        ///     The starting value.\n        /// </param>\n        /// <param name=\"c\">\n        ///     The different between starting and ending value.\n        /// </param>\n        /// <param name=\"d\">\n        ///     The duration of the animations.\n        /// </param>\n        /// <returns>\n        ///     The calculated current value of the animation\n        /// </returns>\n        public static float CubicEaseInOut(float t, float b, float c, float d)\n        {\n            t /= d/2;\n            if (t < 1)\n                return c/2*t*t*t + b;\n\n            t -= 2;\n            return c/2*(t*t*t + 2) + b;\n        }\n\n        /// <summary>\n        ///     The cubic ease-out animation function.\n        /// </summary>\n        /// <param name=\"t\">\n        ///     The time of the animation.\n        /// </param>\n        /// <param name=\"b\">\n        ///     The starting value.\n        /// </param>\n        /// <param name=\"c\">\n        ///     The different between starting and ending value.\n        /// </param>\n        /// <param name=\"d\">\n        ///     The duration of the animations.\n        /// </param>\n        /// <returns>\n        ///     The calculated current value of the animation\n        /// </returns>\n        public static float CubicEaseOut(float t, float b, float c, float d)\n        {\n            t /= d;\n            t--;\n            return c*(t*t*t + 1) + b;\n        }\n\n        /// <summary>\n        ///     The linear animation function.\n        /// </summary>\n        /// <param name=\"t\">\n        ///     The time of the animation.\n        /// </param>\n        /// <param name=\"b\">\n        ///     The starting value.\n        /// </param>\n        /// <param name=\"c\">\n        ///     The different between starting and ending value.\n        /// </param>\n        /// <param name=\"d\">\n        ///     The duration of the animations.\n        /// </param>\n        /// <returns>\n        ///     The calculated current value of the animation\n        /// </returns>\n        public static float Linear(float t, float b, float c, float d)\n        {\n            return c*t/d + b;\n        }\n\n        /// <summary>\n        ///     The circular ease-in and ease-out animation function.\n        /// </summary>\n        /// <param name=\"t\">\n        ///     The time of the animation.\n        /// </param>\n        /// <param name=\"b\">\n        ///     The starting value.\n        /// </param>\n        /// <param name=\"c\">\n        ///     The different between starting and ending value.\n        /// </param>\n        /// <param name=\"d\">\n        ///     The duration of the animations.\n        /// </param>\n        /// <returns>\n        ///     The calculated current value of the animation\n        /// </returns>\n        public static float CircularEaseInOut(float t, float b, float c, float d)\n        {\n            t /= d/2;\n            if (t < 1)\n                return (float) (-c/2*(Math.Sqrt(1 - t*t) - 1) + b);\n            t -= 2;\n            return (float) (c/2*(Math.Sqrt(1 - t*t) + 1) + b);\n        }\n\n\n        /// <summary>\n        ///     The circular ease-in animation function.\n        /// </summary>\n        /// <param name=\"t\">\n        ///     The time of the animation.\n        /// </param>\n        /// <param name=\"b\">\n        ///     The starting value.\n        /// </param>\n        /// <param name=\"c\">\n        ///     The different between starting and ending value.\n        /// </param>\n        /// <param name=\"d\">\n        ///     The duration of the animations.\n        /// </param>\n        /// <returns>\n        ///     The calculated current value of the animation\n        /// </returns>\n        public static float CircularEaseIn(float t, float b, float c, float d)\n        {\n            t /= d;\n            return (float) (-c*(Math.Sqrt(1 - t*t) - 1) + b);\n        }\n\n\n        /// <summary>\n        ///     The circular ease-out animation function.\n        /// </summary>\n        /// <param name=\"t\">\n        ///     The time of the animation.\n        /// </param>\n        /// <param name=\"b\">\n        ///     The starting value.\n        /// </param>\n        /// <param name=\"c\">\n        ///     The different between starting and ending value.\n        /// </param>\n        /// <param name=\"d\">\n        ///     The duration of the animations.\n        /// </param>\n        /// <returns>\n        ///     The calculated current value of the animation\n        /// </returns>\n        public static float CircularEaseOut(float t, float b, float c, float d)\n        {\n            t /= d;\n            t--;\n            return (float) (c*Math.Sqrt(1 - t*t) + b);\n        }\n\n\n        /// <summary>\n        ///     The quadratic ease-in animation function.\n        /// </summary>\n        /// <param name=\"t\">\n        ///     The time of the animation.\n        /// </param>\n        /// <param name=\"b\">\n        ///     The starting value.\n        /// </param>\n        /// <param name=\"c\">\n        ///     The different between starting and ending value.\n        /// </param>\n        /// <param name=\"d\">\n        ///     The duration of the animations.\n        /// </param>\n        /// <returns>\n        ///     The calculated current value of the animation\n        /// </returns>\n        public static float QuadraticEaseIn(float t, float b, float c, float d)\n        {\n            t /= d;\n            return c*t*t + b;\n        }\n\n\n        /// <summary>\n        ///     The quadratic ease-out animation function.\n        /// </summary>\n        /// <param name=\"t\">\n        ///     The time of the animation.\n        /// </param>\n        /// <param name=\"b\">\n        ///     The starting value.\n        /// </param>\n        /// <param name=\"c\">\n        ///     The different between starting and ending value.\n        /// </param>\n        /// <param name=\"d\">\n        ///     The duration of the animations.\n        /// </param>\n        /// <returns>\n        ///     The calculated current value of the animation\n        /// </returns>\n        public static float QuadraticEaseOut(float t, float b, float c, float d)\n        {\n            t /= d;\n            return -c*t*(t - 2) + b;\n        }\n\n\n        /// <summary>\n        ///     The quadratic ease-in and ease-out animation function.\n        /// </summary>\n        /// <param name=\"t\">\n        ///     The time of the animation.\n        /// </param>\n        /// <param name=\"b\">\n        ///     The starting value.\n        /// </param>\n        /// <param name=\"c\">\n        ///     The different between starting and ending value.\n        /// </param>\n        /// <param name=\"d\">\n        ///     The duration of the animations.\n        /// </param>\n        /// <returns>\n        ///     The calculated current value of the animation\n        /// </returns>\n        public static float QuadraticEaseInOut(float t, float b, float c, float d)\n        {\n            t /= d/2;\n            if (t < 1) return c/2*t*t + b;\n            t--;\n            return -c/2*(t*(t - 2) - 1) + b;\n        }\n\n        /// <summary>\n        ///     The quartic ease-in animation function.\n        /// </summary>\n        /// <param name=\"t\">\n        ///     The time of the animation.\n        /// </param>\n        /// <param name=\"b\">\n        ///     The starting value.\n        /// </param>\n        /// <param name=\"c\">\n        ///     The different between starting and ending value.\n        /// </param>\n        /// <param name=\"d\">\n        ///     The duration of the animations.\n        /// </param>\n        /// <returns>\n        ///     The calculated current value of the animation\n        /// </returns>\n        public static float QuarticEaseIn(float t, float b, float c, float d)\n        {\n            t /= d;\n            return c*t*t*t*t + b;\n        }\n\n        /// <summary>\n        ///     The quartic ease-out animation function.\n        /// </summary>\n        /// <param name=\"t\">\n        ///     The time of the animation.\n        /// </param>\n        /// <param name=\"b\">\n        ///     The starting value.\n        /// </param>\n        /// <param name=\"c\">\n        ///     The different between starting and ending value.\n        /// </param>\n        /// <param name=\"d\">\n        ///     The duration of the animations.\n        /// </param>\n        /// <returns>\n        ///     The calculated current value of the animation\n        /// </returns>\n        public static float QuarticEaseOut(float t, float b, float c, float d)\n        {\n            t /= d;\n            t--;\n            return -c*(t*t*t*t - 1) + b;\n        }\n\n        /// <summary>\n        ///     The quartic ease-in and ease-out animation function.\n        /// </summary>\n        /// <param name=\"t\">\n        ///     The time of the animation.\n        /// </param>\n        /// <param name=\"b\">\n        ///     The starting value.\n        /// </param>\n        /// <param name=\"c\">\n        ///     The different between starting and ending value.\n        /// </param>\n        /// <param name=\"d\">\n        ///     The duration of the animations.\n        /// </param>\n        /// <returns>\n        ///     The calculated current value of the animation\n        /// </returns>\n        public static float QuarticEaseInOut(float t, float b, float c, float d)\n        {\n            t /= d/2;\n            if (t < 1) return c/2*t*t*t*t + b;\n            t -= 2;\n            return -c/2*(t*t*t*t - 2) + b;\n        }\n\n        /// <summary>\n        ///     The quintic ease-in and ease-out animation function.\n        /// </summary>\n        /// <param name=\"t\">\n        ///     The time of the animation.\n        /// </param>\n        /// <param name=\"b\">\n        ///     The starting value.\n        /// </param>\n        /// <param name=\"c\">\n        ///     The different between starting and ending value.\n        /// </param>\n        /// <param name=\"d\">\n        ///     The duration of the animations.\n        /// </param>\n        /// <returns>\n        ///     The calculated current value of the animation\n        /// </returns>\n        public static float QuinticEaseInOut(float t, float b, float c, float d)\n        {\n            t /= d/2;\n            if (t < 1) return c/2*t*t*t*t*t + b;\n            t -= 2;\n            return c/2*(t*t*t*t*t + 2) + b;\n        }\n\n        /// <summary>\n        ///     The quintic ease-in animation function.\n        /// </summary>\n        /// <param name=\"t\">\n        ///     The time of the animation.\n        /// </param>\n        /// <param name=\"b\">\n        ///     The starting value.\n        /// </param>\n        /// <param name=\"c\">\n        ///     The different between starting and ending value.\n        /// </param>\n        /// <param name=\"d\">\n        ///     The duration of the animations.\n        /// </param>\n        /// <returns>\n        ///     The calculated current value of the animation\n        /// </returns>\n        public static float QuinticEaseIn(float t, float b, float c, float d)\n        {\n            t /= d;\n            return c*t*t*t*t*t + b;\n        }\n\n        /// <summary>\n        ///     The quintic ease-out animation function.\n        /// </summary>\n        /// <param name=\"t\">\n        ///     The time of the animation.\n        /// </param>\n        /// <param name=\"b\">\n        ///     The starting value.\n        /// </param>\n        /// <param name=\"c\">\n        ///     The different between starting and ending value.\n        /// </param>\n        /// <param name=\"d\">\n        ///     The duration of the animations.\n        /// </param>\n        /// <returns>\n        ///     The calculated current value of the animation\n        /// </returns>\n        public static float QuinticEaseOut(float t, float b, float c, float d)\n        {\n            t /= d;\n            t--;\n            return c*(t*t*t*t*t + 1) + b;\n        }\n\n        /// <summary>\n        ///     The sinusoidal ease-in animation function.\n        /// </summary>\n        /// <param name=\"t\">\n        ///     The time of the animation.\n        /// </param>\n        /// <param name=\"b\">\n        ///     The starting value.\n        /// </param>\n        /// <param name=\"c\">\n        ///     The different between starting and ending value.\n        /// </param>\n        /// <param name=\"d\">\n        ///     The duration of the animations.\n        /// </param>\n        /// <returns>\n        ///     The calculated current value of the animation\n        /// </returns>\n        public static float SinusoidalEaseIn(float t, float b, float c, float d)\n        {\n            return (float) (-c*Math.Cos(t/d*(Math.PI/2)) + c + b);\n        }\n\n        /// <summary>\n        ///     The sinusoidal ease-out animation function.\n        /// </summary>\n        /// <param name=\"t\">\n        ///     The time of the animation.\n        /// </param>\n        /// <param name=\"b\">\n        ///     The starting value.\n        /// </param>\n        /// <param name=\"c\">\n        ///     The different between starting and ending value.\n        /// </param>\n        /// <param name=\"d\">\n        ///     The duration of the animations.\n        /// </param>\n        /// <returns>\n        ///     The calculated current value of the animation\n        /// </returns>\n        public static float SinusoidalEaseOut(float t, float b, float c, float d)\n        {\n            return (float) (c*Math.Sin(t/d*(Math.PI/2)) + b);\n        }\n\n        /// <summary>\n        ///     The sinusoidal ease-in and ease-out animation function.\n        /// </summary>\n        /// <param name=\"t\">\n        ///     The time of the animation.\n        /// </param>\n        /// <param name=\"b\">\n        ///     The starting value.\n        /// </param>\n        /// <param name=\"c\">\n        ///     The different between starting and ending value.\n        /// </param>\n        /// <param name=\"d\">\n        ///     The duration of the animations.\n        /// </param>\n        /// <returns>\n        ///     The calculated current value of the animation\n        /// </returns>\n        public static float SinusoidalEaseInOut(float t, float b, float c, float d)\n        {\n            return (float) (-c/2*(Math.Cos(Math.PI*t/d) - 1) + b);\n        }\n\n        /// <summary>\n        ///     The exponential ease-in animation function.\n        /// </summary>\n        /// <param name=\"t\">\n        ///     The time of the animation.\n        /// </param>\n        /// <param name=\"b\">\n        ///     The starting value.\n        /// </param>\n        /// <param name=\"c\">\n        ///     The different between starting and ending value.\n        /// </param>\n        /// <param name=\"d\">\n        ///     The duration of the animations.\n        /// </param>\n        /// <returns>\n        ///     The calculated current value of the animation\n        /// </returns>\n        public static float ExponentialEaseIn(float t, float b, float c, float d)\n        {\n            return (float) (c*Math.Pow(2, 10*(t/d - 1)) + b);\n        }\n\n        /// <summary>\n        ///     The exponential ease-out animation function.\n        /// </summary>\n        /// <param name=\"t\">\n        ///     The time of the animation.\n        /// </param>\n        /// <param name=\"b\">\n        ///     The starting value.\n        /// </param>\n        /// <param name=\"c\">\n        ///     The different between starting and ending value.\n        /// </param>\n        /// <param name=\"d\">\n        ///     The duration of the animations.\n        /// </param>\n        /// <returns>\n        ///     The calculated current value of the animation\n        /// </returns>\n        public static float ExponentialEaseOut(float t, float b, float c, float d)\n        {\n            return (float) (c*(-Math.Pow(2, -10*t/d) + 1) + b);\n        }\n\n\n        /// <summary>\n        ///     The exponential ease-in and ease-out animation function.\n        /// </summary>\n        /// <param name=\"t\">\n        ///     The time of the animation.\n        /// </param>\n        /// <param name=\"b\">\n        ///     The starting value.\n        /// </param>\n        /// <param name=\"c\">\n        ///     The different between starting and ending value.\n        /// </param>\n        /// <param name=\"d\">\n        ///     The duration of the animations.\n        /// </param>\n        /// <returns>\n        ///     The calculated current value of the animation\n        /// </returns>\n        public static float ExponentialEaseInOut(float t, float b, float c, float d)\n        {\n            t /= d/2;\n            if (t < 1)\n                return (float) (c/2*Math.Pow(2, 10*(t - 1)) + b);\n            t--;\n            return (float) (c/2*(-Math.Pow(2, -10*t) + 2) + b);\n        }\n    }\n}"
  },
  {
    "path": "WinFormAnimation/Animator.cs",
    "content": "﻿using System;\nusing System.Collections.Generic;\nusing System.Linq;\nusing System.Linq.Expressions;\nusing System.Reflection;\n\nnamespace WinFormAnimation\n{\n    /// <summary>\n    ///     The one dimensional animator class, useful for animating raw values\n    /// </summary>\n    public class Animator : IAnimator\n    {\n        /// <summary>\n        ///     The known one dimensional properties of WinForm controls\n        /// </summary>\n        public enum KnownProperties\n        {\n            /// <summary>\n            ///     The property named 'Value' of the object\n            /// </summary>\n            Value,\n\n            /// <summary>\n            ///     The property named 'Text' of the object\n            /// </summary>\n            Text,\n\n            /// <summary>\n            ///     The property named 'Caption' of the object\n            /// </summary>\n            Caption,\n\n            /// <summary>\n            ///     The property named 'BackColor' of the object\n            /// </summary>\n            BackColor,\n\n            /// <summary>\n            ///     The property named 'ForeColor' of the object\n            /// </summary>\n            ForeColor,\n\n            /// <summary>\n            ///     The property named 'Opacity' of the object\n            /// </summary>\n            Opacity\n        }\n\n        private readonly List<Path> _paths = new List<Path>();\n\n        private readonly List<Path> _tempPaths = new List<Path>();\n\n        private readonly Timer _timer;\n\n        private bool _tempReverseRepeat;\n\n        /// <summary>\n        ///     The callback to get invoked at the end of the animation\n        /// </summary>\n        protected SafeInvoker EndCallback;\n\n        /// <summary>\n        ///     The callback to get invoked at each frame\n        /// </summary>\n        protected SafeInvoker<float> FrameCallback;\n\n        /// <summary>\n        ///     The target object to change the property of\n        /// </summary>\n        protected object TargetObject;\n\n        /// <summary>\n        ///     Initializes a new instance of the <see cref=\"Animator\" /> class.\n        /// </summary>\n        public Animator()\n            : this(new Path[] {})\n        {\n        }\n\n        /// <summary>\n        ///     Initializes a new instance of the <see cref=\"Animator\" /> class.\n        /// </summary>\n        /// <param name=\"fpsLimiter\">\n        ///     Limits the maximum frames per seconds\n        /// </param>\n        public Animator(FPSLimiterKnownValues fpsLimiter)\n            : this(new Path[] {}, fpsLimiter)\n        {\n        }\n\n        /// <summary>\n        ///     Initializes a new instance of the <see cref=\"Animator\" /> class.\n        /// </summary>\n        /// <param name=\"path\">\n        ///     The path of the animation\n        /// </param>\n        public Animator(Path path)\n            : this(new[] {path})\n        {\n        }\n\n        /// <summary>\n        ///     Initializes a new instance of the <see cref=\"Animator\" /> class.\n        /// </summary>\n        /// <param name=\"path\">\n        ///     The path of the animation\n        /// </param>\n        /// <param name=\"fpsLimiter\">\n        ///     Limits the maximum frames per seconds\n        /// </param>\n        public Animator(Path path, FPSLimiterKnownValues fpsLimiter)\n            : this(new[] {path}, fpsLimiter)\n        {\n        }\n\n        /// <summary>\n        ///     Initializes a new instance of the <see cref=\"Animator\" /> class.\n        /// </summary>\n        /// <param name=\"paths\">\n        ///     An array containing the list of paths of the animation\n        /// </param>\n        public Animator(Path[] paths) : this(paths, FPSLimiterKnownValues.LimitThirty)\n        {\n        }\n\n        /// <summary>\n        ///     Initializes a new instance of the <see cref=\"Animator\" /> class.\n        /// </summary>\n        /// <param name=\"paths\">\n        ///     An array containing the list of paths of the animation\n        /// </param>\n        /// <param name=\"fpsLimiter\">\n        ///     Limits the maximum frames per seconds\n        /// </param>\n        public Animator(Path[] paths, FPSLimiterKnownValues fpsLimiter)\n        {\n            CurrentStatus = AnimatorStatus.Stopped;\n            _timer = new Timer(Elapsed, fpsLimiter);\n            Paths = paths;\n        }\n\n        /// <summary>\n        ///     Gets or sets an array containing the list of paths of the animation\n        /// </summary>\n        /// <exception cref=\"InvalidOperationException\">Animation is running</exception>\n        public Path[] Paths\n        {\n            get { return _paths.ToArray(); }\n            set\n            {\n                if (CurrentStatus == AnimatorStatus.Stopped)\n                {\n                    _paths.Clear();\n                    _paths.AddRange(value);\n                }\n                else\n                {\n                    throw new InvalidOperationException(\"Animation is running.\");\n                }\n            }\n        }\n\n        /// <summary>\n        ///     Gets the currently active path.\n        /// </summary>\n        public Path ActivePath { get; private set; }\n\n        /// <summary>\n        ///     Gets or sets a value indicating whether animator should repeat the animation after its ending\n        /// </summary>\n        public virtual bool Repeat { get; set; }\n\n        /// <summary>\n        ///     Gets or sets a value indicating whether animator should repeat the animation in reverse after its ending.\n        /// </summary>\n        public virtual bool ReverseRepeat { get; set; }\n\n        /// <summary>\n        ///     Gets the current status of the animation\n        /// </summary>\n        public virtual AnimatorStatus CurrentStatus { get; private set; }\n\n        /// <summary>\n        ///     Pause the animation\n        /// </summary>\n        public virtual void Pause()\n        {\n            if (CurrentStatus != AnimatorStatus.OnHold && CurrentStatus != AnimatorStatus.Playing)\n                return;\n            _timer.Stop();\n            CurrentStatus = AnimatorStatus.Paused;\n        }\n\n        /// <summary>\n        ///     Starts the playing of the animation\n        /// </summary>\n        /// <param name=\"targetObject\">\n        ///     The target object to change the property\n        /// </param>\n        /// <param name=\"propertyName\">\n        ///     The name of the property to change\n        /// </param>\n        public virtual void Play(object targetObject, string propertyName)\n        {\n            Play(targetObject, propertyName, null);\n        }\n\n        /// <summary>\n        ///     Starts the playing of the animation\n        /// </summary>\n        /// <param name=\"targetObject\">\n        ///     The target object to change the property\n        /// </param>\n        /// <param name=\"propertyName\">\n        ///     The name of the property to change\n        /// </param>\n        /// <param name=\"endCallback\">\n        ///     The callback to get invoked at the end of the animation\n        /// </param>\n        public virtual void Play(object targetObject, string propertyName, SafeInvoker endCallback)\n        {\n            TargetObject = targetObject;\n            var prop = TargetObject.GetType()\n                .GetProperty(\n                    propertyName,\n                    BindingFlags.IgnoreCase | BindingFlags.Static | BindingFlags.Public | BindingFlags.Instance |\n                    BindingFlags.SetProperty);\n            if (prop == null) return;\n            Play(\n                new SafeInvoker<float>(\n                    value => prop.SetValue(TargetObject, Convert.ChangeType(value, prop.PropertyType), null),\n                    TargetObject),\n                endCallback);\n        }\n\n        /// <summary>\n        ///     Starts the playing of the animation\n        /// </summary>\n        /// <param name=\"targetObject\">\n        ///     The target object to change the property\n        /// </param>\n        /// <param name=\"propertySetter\">\n        ///     The expression that represents the property of the target object\n        /// </param>\n        /// <typeparam name=\"T\">\n        ///     Any object containing a property\n        /// </typeparam>\n        public virtual void Play<T>(T targetObject, Expression<Func<T, object>> propertySetter)\n        {\n            Play(targetObject, propertySetter, null);\n        }\n\n\n        /// <summary>\n        ///     Starts the playing of the animation\n        /// </summary>\n        /// <param name=\"targetObject\">\n        ///     The target object to change the property\n        /// </param>\n        /// <param name=\"propertySetter\">\n        ///     The expression that represents the property of the target object\n        /// </param>\n        /// <param name=\"endCallback\">\n        ///     The callback to get invoked at the end of the animation\n        /// </param>\n        /// <typeparam name=\"T\">\n        ///     Any object containing a property\n        /// </typeparam>\n        public virtual void Play<T>(T targetObject, Expression<Func<T, object>> propertySetter, SafeInvoker endCallback)\n        {\n            if (propertySetter == null)\n                return;\n            TargetObject = targetObject;\n\n            var property =\n                ((propertySetter.Body as MemberExpression) ??\n                 (((UnaryExpression) propertySetter.Body).Operand as MemberExpression))?.Member as PropertyInfo;\n            if (property == null)\n            {\n                throw new ArgumentException(nameof(propertySetter));\n            }\n\n            Play(\n                new SafeInvoker<float>(\n                    value => property.SetValue(TargetObject, Convert.ChangeType(value, property.PropertyType), null),\n                    TargetObject),\n                endCallback);\n        }\n\n        /// <summary>\n        ///     Resume the animation from where it paused\n        /// </summary>\n        public virtual void Resume()\n        {\n            if (CurrentStatus == AnimatorStatus.Paused)\n            {\n                _timer.Resume();\n            }\n        }\n\n        /// <summary>\n        ///     Stops the animation and resets its status, resume is no longer possible\n        /// </summary>\n        public virtual void Stop()\n        {\n            _timer.Stop();\n            lock (_tempPaths)\n            {\n                _tempPaths.Clear();\n            }\n            ActivePath = null;\n            CurrentStatus = AnimatorStatus.Stopped;\n            _tempReverseRepeat = false;\n        }\n\n        /// <summary>\n        ///     Starts the playing of the animation\n        /// </summary>\n        /// <param name=\"targetObject\">\n        ///     The target object to change the property\n        /// </param>\n        /// <param name=\"property\">\n        ///     The property to change\n        /// </param>\n        public virtual void Play(object targetObject, KnownProperties property)\n        {\n            Play(targetObject, property, null);\n        }\n\n\n        /// <summary>\n        ///     Starts the playing of the animation\n        /// </summary>\n        /// <param name=\"targetObject\">\n        ///     The target object to change the property\n        /// </param>\n        /// <param name=\"property\">\n        ///     The property to change\n        /// </param>\n        /// <param name=\"endCallback\">\n        ///     The callback to get invoked at the end of the animation\n        /// </param>\n        public virtual void Play(object targetObject, KnownProperties property, SafeInvoker endCallback)\n        {\n            Play(targetObject, property.ToString(), endCallback);\n        }\n\n        /// <summary>\n        ///     Starts the playing of the animation\n        /// </summary>\n        /// <param name=\"frameCallback\">\n        ///     The callback to get invoked at each frame\n        /// </param>\n        public virtual void Play(SafeInvoker<float> frameCallback)\n        {\n            Play(frameCallback, (SafeInvoker<float>) null);\n        }\n\n\n        /// <summary>\n        ///     Starts the playing of the animation\n        /// </summary>\n        /// <param name=\"frameCallback\">\n        ///     The callback to get invoked at each frame\n        /// </param>\n        /// <param name=\"endCallback\">\n        ///     The callback to get invoked at the end of the animation\n        /// </param>\n        public virtual void Play(SafeInvoker<float> frameCallback, SafeInvoker endCallback)\n        {\n            Stop();\n            FrameCallback = frameCallback;\n            EndCallback = endCallback;\n            _timer.ResetClock();\n            lock (_tempPaths)\n            {\n                _tempPaths.AddRange(_paths);\n            }\n            _timer.Start();\n        }\n\n        private void Elapsed(ulong millSinceBeginning = 0)\n        {\n            while (true)\n            {\n                lock (_tempPaths)\n                {\n                    if (_tempPaths != null && ActivePath == null && _tempPaths.Count > 0)\n                    {\n                        while (ActivePath == null)\n                        {\n                            if (_tempReverseRepeat)\n                            {\n                                ActivePath = _tempPaths.LastOrDefault();\n                                _tempPaths.RemoveAt(_tempPaths.Count - 1);\n                            }\n                            else\n                            {\n                                ActivePath = _tempPaths.FirstOrDefault();\n                                _tempPaths.RemoveAt(0);\n                            }\n                            _timer.ResetClock();\n                            millSinceBeginning = 0;\n                        }\n                    }\n                    var ended = ActivePath == null;\n                    if (ActivePath != null)\n                    {\n                        if (!_tempReverseRepeat && millSinceBeginning < ActivePath.Delay)\n                        {\n                            CurrentStatus = AnimatorStatus.OnHold;\n                            return;\n                        }\n                        if (millSinceBeginning - (!_tempReverseRepeat ? ActivePath.Delay : 0) <= ActivePath.Duration)\n                        {\n                            if (CurrentStatus != AnimatorStatus.Playing)\n                            {\n                                CurrentStatus = AnimatorStatus.Playing;\n                            }\n                            var value = ActivePath.Function(_tempReverseRepeat ? ActivePath.Duration - millSinceBeginning : millSinceBeginning - ActivePath.Delay, ActivePath.Start, ActivePath.Change, ActivePath.Duration);\n                            FrameCallback.Invoke(value);\n                            return;\n                        }\n                        if (CurrentStatus == AnimatorStatus.Playing)\n                        {\n                            if (_tempPaths.Count == 0)\n                            {\n                                // For the last path, we make sure that control is in end point\n                                FrameCallback.Invoke(_tempReverseRepeat ? ActivePath.Start : ActivePath.End);\n                                ended = true;\n                            }\n                            else\n                            {\n                                if ((_tempReverseRepeat && ActivePath.Delay > 0) || !_tempReverseRepeat && _tempPaths.FirstOrDefault()?.Delay > 0)\n                                {\n                                    // Or if the next path or this one in revese order has a delay\n                                    FrameCallback.Invoke(_tempReverseRepeat ? ActivePath.Start : ActivePath.End);\n                                }\n                            }\n                        }\n                        if (_tempReverseRepeat && (millSinceBeginning - ActivePath.Duration) < ActivePath.Delay)\n                        {\n                            CurrentStatus = AnimatorStatus.OnHold;\n                            return;\n                        }\n                        ActivePath = null;\n                    }\n                    if (!ended)\n                    {\n                        return;\n                    }\n                }\n                if (Repeat)\n                {\n                    lock (_tempPaths)\n                    {\n                        _tempPaths.AddRange(_paths);\n                        _tempReverseRepeat = ReverseRepeat && !_tempReverseRepeat;\n                    }\n                    millSinceBeginning = 0;\n                    continue;\n                }\n                Stop();\n                EndCallback?.Invoke();\n                break;\n            }\n        }\n    }\n}"
  },
  {
    "path": "WinFormAnimation/Animator2D.cs",
    "content": "﻿using System;\nusing System.Collections.Generic;\nusing System.Linq.Expressions;\nusing System.Reflection;\n\nnamespace WinFormAnimation\n{\n    /// <summary>\n    ///     The two dimensional animator class, useful for animating values\n    ///     created from two underlying values\n    /// </summary>\n    public class Animator2D : IAnimator\n    {\n        /// <summary>\n        ///     The known two dimensional properties of WinForm controls\n        /// </summary>\n        public enum KnownProperties\n        {\n            /// <summary>\n            ///     The property named 'Size' of the object\n            /// </summary>\n            Size,\n\n            /// <summary>\n            ///     The property named 'Location' of the object\n            /// </summary>\n            Location\n        }\n\n        private readonly List<Path2D> _paths = new List<Path2D>();\n\n\n        /// <summary>\n        ///     The callback to get invoked at the end of the animation\n        /// </summary>\n        protected SafeInvoker EndCallback;\n\n        /// <summary>\n        ///     The callback to get invoked at each frame\n        /// </summary>\n        protected SafeInvoker<Float2D> FrameCallback;\n\n        /// <summary>\n        ///     A boolean value indicating if the EndInvoker already invoked\n        /// </summary>\n        protected bool IsEnded;\n\n        /// <summary>\n        ///     The target object to change the property of\n        /// </summary>\n        protected object TargetObject;\n\n        /// <summary>\n        ///     The latest horizontal value\n        /// </summary>\n        protected float? XValue;\n\n        /// <summary>\n        ///     The latest vertical value\n        /// </summary>\n        protected float? YValue;\n\n\n        /// <summary>\n        ///     Initializes a new instance of the <see cref=\"Animator2D\" /> class.\n        /// </summary>\n        public Animator2D()\n            : this(new Path2D[] {})\n        {\n        }\n\n        /// <summary>\n        ///     Initializes a new instance of the <see cref=\"Animator2D\" /> class.\n        /// </summary>\n        /// <param name=\"fpsLimiter\">\n        ///     Limits the maximum frames per seconds\n        /// </param>\n        public Animator2D(FPSLimiterKnownValues fpsLimiter)\n            : this(new Path2D[] {}, fpsLimiter)\n        {\n        }\n\n        /// <summary>\n        ///     Initializes a new instance of the <see cref=\"Animator2D\" /> class.\n        /// </summary>\n        /// <param name=\"path\">\n        ///     The path of the animation\n        /// </param>\n        public Animator2D(Path2D path)\n            : this(new[] {path})\n        {\n        }\n\n        /// <summary>\n        ///     Initializes a new instance of the <see cref=\"Animator2D\" /> class.\n        /// </summary>\n        /// <param name=\"path\">\n        ///     The path of the animation\n        /// </param>\n        /// <param name=\"fpsLimiter\">\n        ///     Limits the maximum frames per seconds\n        /// </param>\n        public Animator2D(Path2D path, FPSLimiterKnownValues fpsLimiter)\n            : this(new[] {path}, fpsLimiter)\n        {\n        }\n\n\n        /// <summary>\n        ///     Initializes a new instance of the <see cref=\"Animator2D\" /> class.\n        /// </summary>\n        /// <param name=\"paths\">\n        ///     An array containing the list of paths of the animation\n        /// </param>\n        public Animator2D(Path2D[] paths) : this(paths, FPSLimiterKnownValues.LimitThirty)\n        {\n        }\n\n        /// <summary>\n        ///     Initializes a new instance of the <see cref=\"Animator2D\" /> class.\n        /// </summary>\n        /// <param name=\"paths\">\n        ///     An array containing the list of paths of the animation\n        /// </param>\n        /// <param name=\"fpsLimiter\">\n        ///     Limits the maximum frames per seconds\n        /// </param>\n        public Animator2D(Path2D[] paths, FPSLimiterKnownValues fpsLimiter)\n        {\n            HorizontalAnimator = new Animator(fpsLimiter);\n            VerticalAnimator = new Animator(fpsLimiter);\n            Paths = paths;\n        }\n\n        /// <summary>\n        ///     Gets the currently active path.\n        /// </summary>\n        public Path2D ActivePath => new Path2D(HorizontalAnimator.ActivePath, VerticalAnimator.ActivePath);\n\n        /// <summary>\n        ///     Gets the horizontal animator.\n        /// </summary>\n        public Animator HorizontalAnimator { get; protected set; }\n\n        /// <summary>\n        ///     Gets the vertical animator.\n        /// </summary>\n        public Animator VerticalAnimator { get; protected set; }\n\n        /// <summary>\n        ///     Gets or sets an array containing the list of paths of the animation\n        /// </summary>\n        /// <exception cref=\"InvalidOperationException\">Animation is running</exception>\n        public Path2D[] Paths\n        {\n            get { return _paths.ToArray(); }\n            set\n            {\n                if (CurrentStatus == AnimatorStatus.Stopped)\n                {\n                    _paths.Clear();\n                    _paths.AddRange(value);\n                    var pathsH = new List<Path>();\n                    var pathsV = new List<Path>();\n                    foreach (var p in value)\n                    {\n                        pathsH.Add(p.HorizontalPath);\n                        pathsV.Add(p.VerticalPath);\n                    }\n                    HorizontalAnimator.Paths = pathsH.ToArray();\n                    VerticalAnimator.Paths = pathsV.ToArray();\n                }\n                else\n                {\n                    throw new InvalidOperationException(\"Animation is running.\");\n                }\n            }\n        }\n\n        /// <summary>\n        ///     Gets or sets a value indicating whether animator should repeat the animation after its ending\n        /// </summary>\n        public virtual bool Repeat\n        {\n            get { return HorizontalAnimator.Repeat && VerticalAnimator.Repeat; }\n\n            set { HorizontalAnimator.Repeat = VerticalAnimator.Repeat = value; }\n        }\n\n        /// <summary>\n        ///     Gets or sets a value indicating whether animator should repeat the animation in reverse after its ending.\n        /// </summary>\n        public virtual bool ReverseRepeat\n        {\n            get { return HorizontalAnimator.ReverseRepeat && VerticalAnimator.ReverseRepeat; }\n\n            set { HorizontalAnimator.ReverseRepeat = VerticalAnimator.ReverseRepeat = value; }\n        }\n\n        /// <summary>\n        ///     Gets the current status of the animation\n        /// </summary>\n        public virtual AnimatorStatus CurrentStatus\n        {\n            get\n            {\n                if (HorizontalAnimator.CurrentStatus == AnimatorStatus.Stopped\n                    && VerticalAnimator.CurrentStatus == AnimatorStatus.Stopped)\n                {\n                    return AnimatorStatus.Stopped;\n                }\n\n                if (HorizontalAnimator.CurrentStatus == AnimatorStatus.Paused\n                    && VerticalAnimator.CurrentStatus == AnimatorStatus.Paused)\n                {\n                    return AnimatorStatus.Paused;\n                }\n\n                if (HorizontalAnimator.CurrentStatus == AnimatorStatus.OnHold\n                    && VerticalAnimator.CurrentStatus == AnimatorStatus.OnHold)\n                {\n                    return AnimatorStatus.OnHold;\n                }\n\n                return AnimatorStatus.Playing;\n            }\n        }\n\n        /// <summary>\n        ///     Pause the animation\n        /// </summary>\n        public virtual void Pause()\n        {\n            if (CurrentStatus == AnimatorStatus.OnHold || CurrentStatus == AnimatorStatus.Playing)\n            {\n                HorizontalAnimator.Pause();\n                VerticalAnimator.Pause();\n            }\n        }\n\n        /// <summary>\n        ///     Starts the playing of the animation\n        /// </summary>\n        /// <param name=\"targetObject\">\n        ///     The target object to change the property\n        /// </param>\n        /// <param name=\"propertyName\">\n        ///     The name of the property to change\n        /// </param>\n        public virtual void Play(object targetObject, string propertyName)\n        {\n            Play(targetObject, propertyName, null);\n        }\n\n        /// <summary>\n        ///     Starts the playing of the animation\n        /// </summary>\n        /// <param name=\"targetObject\">\n        ///     The target object to change the property\n        /// </param>\n        /// <param name=\"propertyName\">\n        ///     The name of the property to change\n        /// </param>\n        /// <param name=\"endCallback\">\n        ///     The callback to get invoked at the end of the animation\n        /// </param>\n        public virtual void Play(object targetObject, string propertyName, SafeInvoker endCallback)\n        {\n            TargetObject = targetObject;\n            var prop = TargetObject.GetType()\n                .GetProperty(\n                    propertyName,\n                    BindingFlags.IgnoreCase | BindingFlags.Static | BindingFlags.Public | BindingFlags.Instance |\n                    BindingFlags.SetProperty);\n            if (prop == null) return;\n\n            Play(\n                new SafeInvoker<Float2D>(\n                    value =>\n                        prop.SetValue(TargetObject, Convert.ChangeType(value, prop.PropertyType), null),\n                    TargetObject),\n                endCallback);\n        }\n\n        /// <summary>\n        ///     Starts the playing of the animation\n        /// </summary>\n        /// <param name=\"targetObject\">\n        ///     The target object to change the property\n        /// </param>\n        /// <param name=\"propertySetter\">\n        ///     The expression that represents the property of the target object\n        /// </param>\n        /// <typeparam name=\"T\">\n        ///     Any object containing a property\n        /// </typeparam>\n        public virtual void Play<T>(T targetObject, Expression<Func<T, object>> propertySetter)\n        {\n            Play(targetObject, propertySetter, null);\n        }\n\n        /// <summary>\n        ///     Starts the playing of the animation\n        /// </summary>\n        /// <param name=\"targetObject\">\n        ///     The target object to change the property\n        /// </param>\n        /// <param name=\"propertySetter\">\n        ///     The expression that represents the property of the target object\n        /// </param>\n        /// <param name=\"endCallback\">\n        ///     The callback to get invoked at the end of the animation\n        /// </param>\n        /// <typeparam name=\"T\">\n        ///     Any object containing a property\n        /// </typeparam>\n        public virtual void Play<T>(T targetObject, Expression<Func<T, object>> propertySetter, SafeInvoker endCallback)\n        {\n            if (propertySetter == null)\n                return;\n            TargetObject = targetObject;\n\n            var property =\n                ((propertySetter.Body as MemberExpression) ??\n                 (((UnaryExpression) propertySetter.Body).Operand as MemberExpression))?.Member as PropertyInfo;\n            if (property == null)\n            {\n                throw new ArgumentException(nameof(propertySetter));\n            }\n\n            Play(\n                new SafeInvoker<Float2D>(\n                    value =>\n                        property.SetValue(TargetObject, Convert.ChangeType(value, property.PropertyType), null),\n                    TargetObject),\n                endCallback);\n        }\n\n        /// <summary>\n        ///     Resume the animation from where it paused\n        /// </summary>\n        public virtual void Resume()\n        {\n            if (CurrentStatus == AnimatorStatus.Paused)\n            {\n                HorizontalAnimator.Resume();\n                VerticalAnimator.Resume();\n            }\n        }\n\n        /// <summary>\n        ///     Stops the animation and resets its status, resume is no longer possible\n        /// </summary>\n        public virtual void Stop()\n        {\n            HorizontalAnimator.Stop();\n            VerticalAnimator.Stop();\n            XValue = YValue = null;\n        }\n\n        /// <summary>\n        ///     Starts the playing of the animation\n        /// </summary>\n        /// <param name=\"targetObject\">\n        ///     The target object to change the property\n        /// </param>\n        /// <param name=\"property\">\n        ///     The property to change\n        /// </param>\n        public void Play(object targetObject, KnownProperties property)\n        {\n            Play(targetObject, property, null);\n        }\n\n\n        /// <summary>\n        ///     Starts the playing of the animation\n        /// </summary>\n        /// <param name=\"targetObject\">\n        ///     The target object to change the property\n        /// </param>\n        /// <param name=\"property\">\n        ///     The property to change\n        /// </param>\n        /// <param name=\"endCallback\">\n        ///     The callback to get invoked at the end of the animation\n        /// </param>\n        public void Play(object targetObject, KnownProperties property, SafeInvoker endCallback)\n        {\n            Play(targetObject, property.ToString(), endCallback);\n        }\n\n        /// <summary>\n        ///     Starts the playing of the animation\n        /// </summary>\n        /// <param name=\"frameCallback\">\n        ///     The callback to get invoked at each frame\n        /// </param>\n        public void Play(SafeInvoker<Float2D> frameCallback)\n        {\n            Play(frameCallback, (SafeInvoker) null);\n        }\n\n        /// <summary>\n        ///     Starts the playing of the animation\n        /// </summary>\n        /// <param name=\"frameCallback\">\n        ///     The callback to get invoked at each frame\n        /// </param>\n        /// <param name=\"endCallback\">\n        ///     The callback to get invoked at the end of the animation\n        /// </param>\n        public void Play(SafeInvoker<Float2D> frameCallback, SafeInvoker endCallback)\n        {\n            Stop();\n            FrameCallback = frameCallback;\n            EndCallback = endCallback;\n            HorizontalAnimator.Play(\n                new SafeInvoker<float>(\n                    value =>\n                    {\n                        XValue = value;\n                        InvokeSetter();\n                    }),\n                new SafeInvoker(InvokeFinisher));\n            VerticalAnimator.Play(\n                new SafeInvoker<float>(\n                    value =>\n                    {\n                        YValue = value;\n                        InvokeSetter();\n                    }),\n                new SafeInvoker(InvokeFinisher));\n        }\n\n        private void InvokeFinisher()\n        {\n            if (EndCallback != null && !IsEnded)\n            {\n                lock (EndCallback)\n                {\n                    if (CurrentStatus == AnimatorStatus.Stopped)\n                    {\n                        IsEnded = true;\n                        EndCallback.Invoke();\n                    }\n                }\n            }\n        }\n\n        private void InvokeSetter()\n        {\n            if (XValue != null && YValue != null)\n            {\n                FrameCallback.Invoke(new Float2D(XValue.Value, YValue.Value));\n            }\n        }\n    }\n}"
  },
  {
    "path": "WinFormAnimation/Animator3D.cs",
    "content": "﻿using System;\nusing System.Collections.Generic;\nusing System.Linq.Expressions;\nusing System.Reflection;\n\nnamespace WinFormAnimation\n{\n    /// <summary>\n    ///     The three dimensional animator class, useful for animating values\n    ///     created from three underlying values\n    /// </summary>\n    public class Animator3D : IAnimator\n    {\n        /// <summary>\n        ///     The known three dimensional properties of WinForm controls\n        /// </summary>\n        public enum KnownProperties\n        {\n            /// <summary>\n            ///     The property named 'BackColor' of the object\n            /// </summary>\n            BackColor,\n\n            /// <summary>\n            ///     The property named 'ForeColor' of the object\n            /// </summary>\n            ForeColor\n        }\n\n        private readonly List<Path3D> _paths = new List<Path3D>();\n\n        /// <summary>\n        ///     The callback to get invoked at the end of the animation\n        /// </summary>\n        protected SafeInvoker EndCallback;\n\n        /// <summary>\n        ///     The callback to get invoked at each frame\n        /// </summary>\n        protected SafeInvoker<Float3D> FrameCallback;\n\n        /// <summary>\n        ///     A boolean value indicating if the EndInvoker already invoked\n        /// </summary>\n        protected bool IsEnded;\n\n        /// <summary>\n        ///     The target object to change the property of\n        /// </summary>\n        protected object TargetObject;\n\n        /// <summary>\n        ///     The latest horizontal value\n        /// </summary>\n        protected float? XValue;\n\n        /// <summary>\n        ///     The latest vertical value\n        /// </summary>\n        protected float? YValue;\n\n        /// <summary>\n        ///     The latest depth value\n        /// </summary>\n        protected float? ZValue;\n\n\n        /// <summary>\n        ///     Initializes a new instance of the <see cref=\"Animator3D\" /> class.\n        /// </summary>\n        public Animator3D()\n            : this(new Path3D[] {})\n        {\n        }\n\n        /// <summary>\n        ///     Initializes a new instance of the <see cref=\"Animator3D\" /> class.\n        /// </summary>\n        /// <param name=\"fpsLimiter\">\n        ///     Limits the maximum frames per seconds\n        /// </param>\n        public Animator3D(FPSLimiterKnownValues fpsLimiter)\n            : this(new Path3D[] {}, fpsLimiter)\n        {\n        }\n\n        /// <summary>\n        ///     Initializes a new instance of the <see cref=\"Animator3D\" /> class.\n        /// </summary>\n        /// <param name=\"path\">\n        ///     The path of the animation\n        /// </param>\n        public Animator3D(Path3D path)\n            : this(new[] {path})\n        {\n        }\n\n        /// <summary>\n        ///     Initializes a new instance of the <see cref=\"Animator3D\" /> class.\n        /// </summary>\n        /// <param name=\"path\">\n        ///     The path of the animation\n        /// </param>\n        /// <param name=\"fpsLimiter\">\n        ///     Limits the maximum frames per seconds\n        /// </param>\n        public Animator3D(Path3D path, FPSLimiterKnownValues fpsLimiter)\n            : this(new[] {path}, fpsLimiter)\n        {\n        }\n\n        /// <summary>\n        ///     Initializes a new instance of the <see cref=\"Animator3D\" /> class.\n        /// </summary>\n        /// <param name=\"paths\">\n        ///     An array containing the list of paths of the animation\n        /// </param>\n        public Animator3D(Path3D[] paths) : this(paths, FPSLimiterKnownValues.LimitThirty)\n        {\n        }\n\n        /// <summary>\n        ///     Initializes a new instance of the <see cref=\"Animator3D\" /> class.\n        /// </summary>\n        /// <param name=\"paths\">\n        ///     An array containing the list of paths of the animation\n        /// </param>\n        /// <param name=\"fpsLimiter\">\n        ///     Limits the maximum frames per seconds\n        /// </param>\n        public Animator3D(Path3D[] paths, FPSLimiterKnownValues fpsLimiter)\n        {\n            HorizontalAnimator = new Animator(fpsLimiter);\n            VerticalAnimator = new Animator(fpsLimiter);\n            DepthAnimator = new Animator(fpsLimiter);\n            Paths = paths;\n        }\n\n        /// <summary>\n        ///     Gets the currently active path.\n        /// </summary>\n        public Path3D ActivePath => new Path3D(\n            HorizontalAnimator.ActivePath,\n            VerticalAnimator.ActivePath,\n            DepthAnimator.ActivePath);\n\n        /// <summary>\n        ///     Gets the horizontal animator.\n        /// </summary>\n        public Animator HorizontalAnimator { get; protected set; }\n\n        /// <summary>\n        ///     Gets the vertical animator.\n        /// </summary>\n        public Animator VerticalAnimator { get; protected set; }\n\n        /// <summary>\n        ///     Gets the depth animator.\n        /// </summary>\n        public Animator DepthAnimator { get; protected set; }\n\n\n        /// <summary>\n        ///     Gets or sets an array containing the list of paths of the animation\n        /// </summary>\n        /// <exception cref=\"InvalidOperationException\">Animation is running</exception>\n        public Path3D[] Paths\n        {\n            get { return _paths.ToArray(); }\n            set\n            {\n                if (CurrentStatus == AnimatorStatus.Stopped)\n                {\n                    _paths.Clear();\n                    _paths.AddRange(value);\n                    var pathsX = new List<Path>();\n                    var pathsY = new List<Path>();\n                    var pathsZ = new List<Path>();\n                    foreach (var p in value)\n                    {\n                        pathsX.Add(p.HorizontalPath);\n                        pathsY.Add(p.VerticalPath);\n                        pathsZ.Add(p.DepthPath);\n                    }\n\n                    HorizontalAnimator.Paths = pathsX.ToArray();\n                    VerticalAnimator.Paths = pathsY.ToArray();\n                    DepthAnimator.Paths = pathsZ.ToArray();\n                }\n                else\n                {\n                    throw new NotSupportedException(\"Animation is running.\");\n                }\n            }\n        }\n\n        /// <summary>\n        ///     Gets or sets a value indicating whether animator should repeat the animation after its ending\n        /// </summary>\n        public virtual bool Repeat\n        {\n            get { return HorizontalAnimator.Repeat && VerticalAnimator.Repeat && DepthAnimator.Repeat; }\n\n            set { HorizontalAnimator.Repeat = VerticalAnimator.Repeat = DepthAnimator.Repeat = value; }\n        }\n\n        /// <summary>\n        ///     Gets or sets a value indicating whether animator should repeat the animation in reverse after its ending.\n        /// </summary>\n        public virtual bool ReverseRepeat\n        {\n            get\n            {\n                return HorizontalAnimator.ReverseRepeat && VerticalAnimator.ReverseRepeat\n                       && DepthAnimator.ReverseRepeat;\n            }\n\n            set\n            {\n                HorizontalAnimator.ReverseRepeat =\n                    VerticalAnimator.ReverseRepeat = DepthAnimator.ReverseRepeat = value;\n            }\n        }\n\n        /// <summary>\n        ///     Gets the current status of the animation\n        /// </summary>\n        public virtual AnimatorStatus CurrentStatus\n        {\n            get\n            {\n                if (HorizontalAnimator.CurrentStatus == AnimatorStatus.Stopped\n                    && VerticalAnimator.CurrentStatus == AnimatorStatus.Stopped\n                    && DepthAnimator.CurrentStatus == AnimatorStatus.Stopped)\n                {\n                    return AnimatorStatus.Stopped;\n                }\n\n                if (HorizontalAnimator.CurrentStatus == AnimatorStatus.Paused\n                    && VerticalAnimator.CurrentStatus == AnimatorStatus.Paused\n                    && DepthAnimator.CurrentStatus == AnimatorStatus.Paused)\n                {\n                    return AnimatorStatus.Paused;\n                }\n\n                if (HorizontalAnimator.CurrentStatus == AnimatorStatus.OnHold\n                    && VerticalAnimator.CurrentStatus == AnimatorStatus.OnHold\n                    && DepthAnimator.CurrentStatus == AnimatorStatus.OnHold)\n                {\n                    return AnimatorStatus.OnHold;\n                }\n\n                return AnimatorStatus.Playing;\n            }\n        }\n\n        /// <summary>\n        ///     Pause the animation\n        /// </summary>\n        public virtual void Pause()\n        {\n            if (CurrentStatus == AnimatorStatus.OnHold || CurrentStatus == AnimatorStatus.Playing)\n            {\n                HorizontalAnimator.Pause();\n                VerticalAnimator.Pause();\n                DepthAnimator.Pause();\n            }\n        }\n\n        /// <summary>\n        ///     Starts the playing of the animation\n        /// </summary>\n        /// <param name=\"targetObject\">\n        ///     The target object to change the property\n        /// </param>\n        /// <param name=\"propertyName\">\n        ///     The name of the property to change\n        /// </param>\n        public virtual void Play(object targetObject, string propertyName)\n        {\n            Play(targetObject, propertyName, null);\n        }\n\n        /// <summary>\n        ///     Starts the playing of the animation\n        /// </summary>\n        /// <param name=\"targetObject\">\n        ///     The target object to change the property\n        /// </param>\n        /// <param name=\"propertyName\">\n        ///     The name of the property to change\n        /// </param>\n        /// <param name=\"endCallback\">\n        ///     The callback to get invoked at the end of the animation\n        /// </param>\n        public virtual void Play(object targetObject, string propertyName, SafeInvoker endCallback)\n        {\n            TargetObject = targetObject;\n            var prop = TargetObject.GetType()\n                .GetProperty(\n                    propertyName,\n                    BindingFlags.IgnoreCase | BindingFlags.Static | BindingFlags.Public | BindingFlags.Instance |\n                    BindingFlags.SetProperty);\n            if (prop == null) return;\n\n            Play(\n                new SafeInvoker<Float3D>(\n                    value =>\n                        prop.SetValue(TargetObject, Convert.ChangeType(value, prop.PropertyType), null),\n                    TargetObject),\n                endCallback);\n        }\n\n        /// <summary>\n        ///     Starts the playing of the animation\n        /// </summary>\n        /// <param name=\"targetObject\">\n        ///     The target object to change the property\n        /// </param>\n        /// <param name=\"propertySetter\">\n        ///     The expression that represents the property of the target object\n        /// </param>\n        /// <typeparam name=\"T\">\n        ///     Any object containing a property\n        /// </typeparam>\n        public virtual void Play<T>(T targetObject, Expression<Func<T, object>> propertySetter)\n        {\n            Play(targetObject, propertySetter, null);\n        }\n\n        /// <summary>\n        ///     Starts the playing of the animation\n        /// </summary>\n        /// <param name=\"targetObject\">\n        ///     The target object to change the property\n        /// </param>\n        /// <param name=\"propertySetter\">\n        ///     The expression that represents the property of the target object\n        /// </param>\n        /// <param name=\"endCallback\">\n        ///     The callback to get invoked at the end of the animation\n        /// </param>\n        /// <typeparam name=\"T\">\n        ///     Any object containing a property\n        /// </typeparam>\n        public virtual void Play<T>(T targetObject, Expression<Func<T, object>> propertySetter, SafeInvoker endCallback)\n        {\n            if (propertySetter == null)\n                return;\n            TargetObject = targetObject;\n\n            var property =\n                ((propertySetter.Body as MemberExpression) ??\n                 (((UnaryExpression) propertySetter.Body).Operand as MemberExpression))?.Member as PropertyInfo;\n            if (property == null)\n            {\n                throw new ArgumentException(nameof(propertySetter));\n            }\n\n            Play(\n                new SafeInvoker<Float3D>(\n                    value =>\n                        property.SetValue(TargetObject, Convert.ChangeType(value, property.PropertyType), null),\n                    TargetObject),\n                endCallback);\n        }\n\n        /// <summary>\n        ///     Resume the animation from where it paused\n        /// </summary>\n        public virtual void Resume()\n        {\n            if (CurrentStatus == AnimatorStatus.Paused)\n            {\n                HorizontalAnimator.Resume();\n                VerticalAnimator.Resume();\n                DepthAnimator.Resume();\n            }\n        }\n\n        /// <summary>\n        ///     Stops the animation and resets its status, resume is no longer possible\n        /// </summary>\n        public virtual void Stop()\n        {\n            HorizontalAnimator.Stop();\n            VerticalAnimator.Stop();\n            DepthAnimator.Stop();\n            XValue = YValue = ZValue = null;\n        }\n\n        /// <summary>\n        ///     Starts the playing of the animation\n        /// </summary>\n        /// <param name=\"targetObject\">\n        ///     The target object to change the property\n        /// </param>\n        /// <param name=\"property\">\n        ///     The property to change\n        /// </param>\n        public void Play(object targetObject, KnownProperties property)\n        {\n            Play(targetObject, property, null);\n        }\n\n        /// <summary>\n        ///     Starts the playing of the animation\n        /// </summary>\n        /// <param name=\"targetObject\">\n        ///     The target object to change the property\n        /// </param>\n        /// <param name=\"property\">\n        ///     The property to change\n        /// </param>\n        /// <param name=\"endCallback\">\n        ///     The callback to get invoked at the end of the animation\n        /// </param>\n        public void Play(object targetObject, KnownProperties property, SafeInvoker endCallback)\n        {\n            Play(targetObject, property.ToString(), endCallback);\n        }\n\n        /// <summary>\n        ///     Starts the playing of the animation\n        /// </summary>\n        /// <param name=\"frameCallback\">\n        ///     The callback to get invoked at each frame\n        /// </param>\n        public void Play(SafeInvoker<Float3D> frameCallback)\n        {\n            Play(frameCallback, (SafeInvoker) null);\n        }\n\n        /// <summary>\n        ///     Starts the playing of the animation\n        /// </summary>\n        /// <param name=\"frameCallback\">\n        ///     The callback to get invoked at each frame\n        /// </param>\n        /// <param name=\"endCallback\">\n        ///     The callback to get invoked at the end of the animation\n        /// </param>\n        public void Play(SafeInvoker<Float3D> frameCallback, SafeInvoker endCallback)\n        {\n            Stop();\n            FrameCallback = frameCallback;\n            EndCallback = endCallback;\n            IsEnded = false;\n            HorizontalAnimator.Play(\n                new SafeInvoker<float>(\n                    value =>\n                    {\n                        XValue = value;\n                        InvokeSetter();\n                    }),\n                new SafeInvoker(InvokeFinisher));\n            VerticalAnimator.Play(\n                new SafeInvoker<float>(\n                    value =>\n                    {\n                        YValue = value;\n                        InvokeSetter();\n                    }),\n                new SafeInvoker(InvokeFinisher));\n            DepthAnimator.Play(\n                new SafeInvoker<float>(\n                    value =>\n                    {\n                        ZValue = value;\n                        InvokeSetter();\n                    }),\n                new SafeInvoker(InvokeFinisher));\n        }\n\n        private void InvokeFinisher()\n        {\n            if (EndCallback != null && !IsEnded)\n            {\n                lock (EndCallback)\n                {\n                    if (CurrentStatus == AnimatorStatus.Stopped)\n                    {\n                        IsEnded = true;\n                        EndCallback.Invoke();\n                    }\n                }\n            }\n        }\n\n        private void InvokeSetter()\n        {\n            if (XValue != null && YValue != null && ZValue != null)\n            {\n                FrameCallback.Invoke(new Float3D(XValue.Value, YValue.Value, ZValue.Value));\n            }\n        }\n    }\n}"
  },
  {
    "path": "WinFormAnimation/AnimatorStatus.cs",
    "content": "﻿namespace WinFormAnimation\n{\n    /// <summary>\n    ///     The possible statuses for an animator instance\n    /// </summary>\n    public enum AnimatorStatus\n    {\n        /// <summary>\n        ///     Animation is stopped\n        /// </summary>\n        Stopped,\n\n        /// <summary>\n        ///     Animation is now playing\n        /// </summary>\n        Playing,\n\n        /// <summary>\n        ///     Animation is now on hold for path delay, consider this value as playing\n        /// </summary>\n        OnHold,\n\n        /// <summary>\n        ///     Animation is paused\n        /// </summary>\n        Paused\n    }\n}"
  },
  {
    "path": "WinFormAnimation/FPSLimiterKnownValues.cs",
    "content": "﻿namespace WinFormAnimation\n{\n    /// <summary>\n    ///     FPS limiter known values\n    /// </summary>\n    public enum FPSLimiterKnownValues\n    {\n        /// <summary>\n        ///     Limits maximum frames per second to 10fps\n        /// </summary>\n        LimitTen = 10,\n\n        /// <summary>\n        ///     Limits maximum frames per second to 20fps\n        /// </summary>\n        LimitTwenty = 20,\n\n        /// <summary>\n        ///     Limits maximum frames per second to 30fps\n        /// </summary>\n        LimitThirty = 30,\n\n        /// <summary>\n        ///     Limits maximum frames per second to 60fps\n        /// </summary>\n        LimitSixty = 60,\n\n        /// <summary>\n        ///     Limits maximum frames per second to 100fps\n        /// </summary>\n        LimitOneHundred = 100,\n\n        /// <summary>\n        ///     Limits maximum frames per second to 200fps\n        /// </summary>\n        LimitTwoHundred = 200,\n\n        /// <summary>\n        ///     Adds no limit to the number of frames per second\n        /// </summary>\n        NoFPSLimit = -1\n    }\n}"
  },
  {
    "path": "WinFormAnimation/FloatExtensions.cs",
    "content": "﻿using System.Drawing;\n\nnamespace WinFormAnimation\n{\n    /// <summary>\n    ///     Contains public extension methods about Float2D and Fload3D classes\n    /// </summary>\n    public static class FloatExtensions\n    {\n        /// <summary>\n        ///     Creates and returns a new instance of the <see cref=\"Float2D\" /> class from this instance\n        /// </summary>\n        /// <param name=\"point\">The object to create the <see cref=\"Float2D\" /> instance from</param>\n        /// <returns>The newly created <see cref=\"Float2D\" /> instance</returns>\n        public static Float2D ToFloat2D(this Point point)\n        {\n            return Float2D.FromPoint(point);\n        }\n\n        /// <summary>\n        ///     Creates and returns a new instance of the <see cref=\"Float2D\" /> class from this instance\n        /// </summary>\n        /// <param name=\"point\">The object to create the <see cref=\"Float2D\" /> instance from</param>\n        /// <returns>The newly created <see cref=\"Float2D\" /> instance</returns>\n        public static Float2D ToFloat2D(this PointF point)\n        {\n            return Float2D.FromPoint(point);\n        }\n\n        /// <summary>\n        ///     Creates and returns a new instance of the <see cref=\"Float2D\" /> class from this instance\n        /// </summary>\n        /// <param name=\"size\">The object to create the <see cref=\"Float2D\" /> instance from</param>\n        /// <returns>The newly created <see cref=\"Float2D\" /> instance</returns>\n        public static Float2D ToFloat2D(this Size size)\n        {\n            return Float2D.FromSize(size);\n        }\n\n        /// <summary>\n        ///     Creates and returns a new instance of the <see cref=\"Float2D\" /> class from this instance\n        /// </summary>\n        /// <param name=\"size\">The object to create the <see cref=\"Float2D\" /> instance from</param>\n        /// <returns>The newly created <see cref=\"Float2D\" /> instance</returns>\n        public static Float2D ToFloat2D(this SizeF size)\n        {\n            return Float2D.FromSize(size);\n        }\n\n        /// <summary>\n        ///     Creates and returns a new instance of the <see cref=\"Float3D\" /> class from this instance\n        /// </summary>\n        /// <param name=\"color\">The object to create the <see cref=\"Float3D\" /> instance from</param>\n        /// <returns>The newly created <see cref=\"Float3D\" /> instance</returns>\n        public static Float3D ToFloat3D(this Color color)\n        {\n            return Float3D.FromColor(color);\n        }\n    }\n}"
  },
  {
    "path": "WinFormAnimation/IAnimator.cs",
    "content": "﻿using System;\nusing System.Linq.Expressions;\n\nnamespace WinFormAnimation\n{\n    /// <summary>\n    ///     The base interface for any Animator class, custom or build-in\n    /// </summary>\n    public interface IAnimator\n    {\n        /// <summary>\n        ///     Gets the current status of the animation\n        /// </summary>\n        AnimatorStatus CurrentStatus { get; }\n\n        /// <summary>\n        ///     Gets or sets a value indicating whether animator should repeat the animation after its ending\n        /// </summary>\n        bool Repeat { get; set; }\n\n        /// <summary>\n        ///     Gets or sets a value indicating whether animator should repeat the animation in reverse after its ending.\n        /// </summary>\n        bool ReverseRepeat { get; set; }\n\n        /// <summary>\n        ///     Starts the playing of the animation\n        /// </summary>\n        /// <param name=\"targetObject\">\n        ///     The target object to change the property\n        /// </param>\n        /// <param name=\"propertyName\">\n        ///     The name of the property to change\n        /// </param>\n        void Play(object targetObject, string propertyName);\n\n        /// <summary>\n        ///     Starts the playing of the animation\n        /// </summary>\n        /// <param name=\"targetObject\">\n        ///     The target object to change the property\n        /// </param>\n        /// <param name=\"propertyName\">\n        ///     The name of the property to change\n        /// </param>\n        /// <param name=\"endCallback\">\n        ///     The callback to get invoked at the end of the animation\n        /// </param>\n        void Play(object targetObject, string propertyName, SafeInvoker endCallback);\n\n        /// <summary>\n        ///     Starts the playing of the animation\n        /// </summary>\n        /// <param name=\"targetObject\">\n        ///     The target object to change the property\n        /// </param>\n        /// <param name=\"propertySetter\">\n        ///     The expression that represents the property of the target object\n        /// </param>\n        /// <typeparam name=\"T\">\n        ///     Any object containing a property\n        /// </typeparam>\n        void Play<T>(T targetObject, Expression<Func<T, object>> propertySetter);\n\n        /// <summary>\n        ///     Starts the playing of the animation\n        /// </summary>\n        /// <param name=\"targetObject\">\n        ///     The target object to change the property\n        /// </param>\n        /// <param name=\"propertySetter\">\n        ///     The expression that represents the property of the target object\n        /// </param>\n        /// <param name=\"endCallback\">\n        ///     The callback to get invoked at the end of the animation\n        /// </param>\n        /// <typeparam name=\"T\">\n        ///     Any object containing a property\n        /// </typeparam>\n        void Play<T>(T targetObject, Expression<Func<T, object>> propertySetter, SafeInvoker endCallback);\n\n        /// <summary>\n        ///     Resume the animation from where it paused\n        /// </summary>\n        void Resume();\n\n        /// <summary>\n        ///     Stops the animation and resets its status, resume is no longer possible\n        /// </summary>\n        void Stop();\n\n        /// <summary>\n        ///     Pause the animation\n        /// </summary>\n        void Pause();\n    }\n}"
  },
  {
    "path": "WinFormAnimation/KnownAnimationFunctions.cs",
    "content": "﻿namespace WinFormAnimation\n{\n    /// <summary>\n    ///     Contains a list of all known animation functions\n    /// </summary>\n    public enum KnownAnimationFunctions\n    {\n        /// <summary>\n        ///     No known animation function\n        /// </summary>\n        None,\n\n        /// <summary>\n        ///     The cubic ease-in animation function.\n        /// </summary>\n        CubicEaseIn,\n\n        /// <summary>\n        ///     The cubic ease-in and ease-out animation function.\n        /// </summary>\n        CubicEaseInOut,\n\n        /// <summary>\n        ///     The cubic ease-out animation function.\n        /// </summary>\n        CubicEaseOut,\n\n        /// <summary>\n        ///     The linear animation function.\n        /// </summary>\n        Linear,\n\n        /// <summary>\n        ///     The circular ease-in and ease-out animation function.\n        /// </summary>\n        CircularEaseInOut,\n\n        /// <summary>\n        ///     The circular ease-in animation function.\n        /// </summary>\n        CircularEaseIn,\n\n        /// <summary>\n        ///     The circular ease-out animation function.\n        /// </summary>\n        CircularEaseOut,\n\n        /// <summary>\n        ///     The quadratic ease-in animation function.\n        /// </summary>\n        QuadraticEaseIn,\n\n        /// <summary>\n        ///     The quadratic ease-out animation function.\n        /// </summary>\n        QuadraticEaseOut,\n\n        /// <summary>\n        ///     The quadratic ease-in and ease-out animation function.\n        /// </summary>\n        QuadraticEaseInOut,\n\n        /// <summary>\n        ///     The quartic ease-in animation function.\n        /// </summary>\n        QuarticEaseIn,\n\n        /// <summary>\n        ///     The quartic ease-out animation function.\n        /// </summary>\n        QuarticEaseOut,\n\n        /// <summary>\n        ///     The quartic ease-in and ease-out animation function.\n        /// </summary>\n        QuarticEaseInOut,\n\n        /// <summary>\n        ///     The quintic ease-in and ease-out animation function.\n        /// </summary>\n        QuinticEaseInOut,\n\n        /// <summary>\n        ///     The quintic ease-in animation function.\n        /// </summary>\n        QuinticEaseIn,\n\n        /// <summary>\n        ///     The quintic ease-out animation function.\n        /// </summary>\n        QuinticEaseOut,\n\n        /// <summary>\n        ///     The sinusoidal ease-in animation function.\n        /// </summary>\n        SinusoidalEaseIn,\n\n        /// <summary>\n        ///     The sinusoidal ease-out animation function.\n        /// </summary>\n        SinusoidalEaseOut,\n\n        /// <summary>\n        ///     The sinusoidal ease-in and ease-out animation function.\n        /// </summary>\n        SinusoidalEaseInOut,\n\n        /// <summary>\n        ///     The exponential ease-in animation function.\n        /// </summary>\n        ExponentialEaseIn,\n\n        /// <summary>\n        ///     The exponential ease-out animation function.\n        /// </summary>\n        ExponentialEaseOut,\n\n        /// <summary>\n        ///     The exponential ease-in and ease-out animation function.\n        /// </summary>\n        ExponentialEaseInOut\n    }\n}"
  },
  {
    "path": "WinFormAnimation/Path.cs",
    "content": "﻿using System;\n\nnamespace WinFormAnimation\n{\n    /// <summary>\n    ///     The Path class is a representation of a line in a 1D plane and the\n    ///     speed in which the animator plays it\n    /// </summary>\n    public class Path\n    {\n        /// <summary>\n        ///     Initializes a new instance of the <see cref=\"Path\" /> class.\n        /// </summary>\n        public Path() : this(default(float), default(float), default(ulong), 0, null)\n        {\n        }\n\n        /// <summary>\n        ///     Initializes a new instance of the <see cref=\"Path\" /> class.\n        /// </summary>\n        /// <param name=\"start\">\n        ///     The starting value\n        /// </param>\n        /// <param name=\"end\">\n        ///     The ending value\n        /// </param>\n        /// <param name=\"duration\">\n        ///     The time in miliseconds that the animator must play this path\n        /// </param>\n        /// <exception cref=\"ArgumentOutOfRangeException\">\n        ///     Duration is less than zero\n        /// </exception>\n        public Path(float start, float end, ulong duration) : this(start, end, duration, 0, null)\n        {\n        }\n\n        /// <summary>\n        ///     Initializes a new instance of the <see cref=\"Path\" /> class.\n        /// </summary>\n        /// <param name=\"start\">\n        ///     The starting value\n        /// </param>\n        /// <param name=\"end\">\n        ///     The ending value\n        /// </param>\n        /// <param name=\"duration\">\n        ///     The time in miliseconds that the animator must play this path\n        /// </param>\n        /// <param name=\"function\">\n        ///     The animation function\n        /// </param>\n        /// <exception cref=\"ArgumentOutOfRangeException\">\n        ///     Duration is less than zero\n        /// </exception>\n        public Path(float start, float end, ulong duration, AnimationFunctions.Function function)\n            : this(start, end, duration, 0, function)\n        {\n        }\n\n        /// <summary>\n        ///     Initializes a new instance of the <see cref=\"Path\" /> class.\n        /// </summary>\n        /// <param name=\"start\">\n        ///     The starting value\n        /// </param>\n        /// <param name=\"end\">\n        ///     The ending value\n        /// </param>\n        /// <param name=\"duration\">\n        ///     The time in miliseconds that the animator must play this path\n        /// </param>\n        /// <param name=\"delay\">\n        ///     The time in miliseconds that the animator must wait before playing this path\n        /// </param>\n        /// <exception cref=\"ArgumentOutOfRangeException\">\n        ///     Duration is less than zero\n        /// </exception>\n        public Path(float start, float end, ulong duration, ulong delay) : this(start, end, duration, delay, null)\n        {\n        }\n\n        /// <summary>\n        ///     Initializes a new instance of the <see cref=\"Path\" /> class.\n        /// </summary>\n        /// <param name=\"start\">\n        ///     The starting value\n        /// </param>\n        /// <param name=\"end\">\n        ///     The ending value\n        /// </param>\n        /// <param name=\"duration\">\n        ///     The time in miliseconds that the animator must play this path\n        /// </param>\n        /// <param name=\"delay\">\n        ///     The time in miliseconds that the animator must wait before playing this path\n        /// </param>\n        /// <param name=\"function\">\n        ///     The animation function\n        /// </param>\n        /// <exception cref=\"ArgumentOutOfRangeException\">\n        ///     Duration is less than zero\n        /// </exception>\n        public Path(float start, float end, ulong duration, ulong delay, AnimationFunctions.Function function)\n        {\n            Start = start;\n            End = end;\n            Function = function ?? AnimationFunctions.Linear;\n            Duration = duration;\n            Delay = delay;\n        }\n\n        /// <summary>\n        ///     Gets the difference of starting and ending values\n        /// </summary>\n        public float Change => End - Start;\n\n        /// <summary>\n        ///     Gets or sets the starting delay\n        /// </summary>\n        public ulong Delay { get; set; }\n\n        /// <summary>\n        ///     Gets or sets the duration in milliseconds\n        /// </summary>\n        public ulong Duration { get; set; }\n\n        /// <summary>\n        ///     Gets or sets the ending value\n        /// </summary>\n        public float End { get; set; }\n\n        /// <summary>\n        ///     Gets or sets the animation function\n        /// </summary>\n        public AnimationFunctions.Function Function { get; set; }\n\n        /// <summary>\n        ///     Gets or sets the starting value\n        /// </summary>\n        public float Start { get; set; }\n\n        /// <summary>\n        ///     Creates and returns a new <see cref=\"Path\" /> based on the current path but in reverse order\n        /// </summary>\n        /// <returns>\n        ///     A new <see cref=\"Path\" /> which is the reverse of the current <see cref=\"Path\" />\n        /// </returns>\n        public Path Reverse()\n        {\n            return new Path(End, Start, Duration, Delay, Function);\n        }\n    }\n}"
  },
  {
    "path": "WinFormAnimation/Path2D.cs",
    "content": "﻿using System;\n\nnamespace WinFormAnimation\n{\n    /// <summary>\n    ///     The Path2D class is a representation of a line in a 2D plane and the\n    ///     speed in which the animator plays it\n    /// </summary>\n    public class Path2D\n    {\n        /// <summary>\n        ///     Initializes a new instance of the <see cref=\"Path2D\" /> class.\n        /// </summary>\n        /// <param name=\"startX\">\n        ///     The starting horizontal value\n        /// </param>\n        /// <param name=\"endX\">\n        ///     The ending horizontal value\n        /// </param>\n        /// <param name=\"startY\">\n        ///     The starting vertical value\n        /// </param>\n        /// <param name=\"endY\">\n        ///     The ending vertical value\n        /// </param>\n        /// <param name=\"duration\">\n        ///     The time in miliseconds that the animator must play this path\n        /// </param>\n        /// <param name=\"delay\">\n        ///     The time in miliseconds that the animator must wait before playing this path\n        /// </param>\n        /// <param name=\"function\">\n        ///     The animation function\n        /// </param>\n        /// <exception cref=\"ArgumentOutOfRangeException\">\n        ///     Duration is less than zero\n        /// </exception>\n        public Path2D(\n            float startX,\n            float endX,\n            float startY,\n            float endY,\n            ulong duration,\n            ulong delay,\n            AnimationFunctions.Function function)\n            : this(new Path(startX, endX, duration, delay, function), new Path(startY, endY, duration, delay, function))\n        {\n        }\n\n        /// <summary>\n        ///     Initializes a new instance of the <see cref=\"Path2D\" /> class.\n        /// </summary>\n        /// <param name=\"startX\">\n        ///     The starting horizontal value\n        /// </param>\n        /// <param name=\"endX\">\n        ///     The ending horizontal value\n        /// </param>\n        /// <param name=\"startY\">\n        ///     The starting vertical value\n        /// </param>\n        /// <param name=\"endY\">\n        ///     The ending vertical value\n        /// </param>\n        /// <param name=\"duration\">\n        ///     The time in miliseconds that the animator must play this path\n        /// </param>\n        /// <param name=\"delay\">\n        ///     The time in miliseconds that the animator must wait before playing this path\n        /// </param>\n        /// <exception cref=\"ArgumentOutOfRangeException\">\n        ///     Duration is less than zero\n        /// </exception>\n        public Path2D(\n            float startX,\n            float endX,\n            float startY,\n            float endY,\n            ulong duration,\n            ulong delay)\n            : this(new Path(startX, endX, duration, delay), new Path(startY, endY, duration, delay))\n        {\n        }\n\n        /// <summary>\n        ///     Initializes a new instance of the <see cref=\"Path2D\" /> class.\n        /// </summary>\n        /// <param name=\"startX\">\n        ///     The starting horizontal value\n        /// </param>\n        /// <param name=\"endX\">\n        ///     The ending horizontal value\n        /// </param>\n        /// <param name=\"startY\">\n        ///     The starting vertical value\n        /// </param>\n        /// <param name=\"endY\">\n        ///     The ending vertical value\n        /// </param>\n        /// <param name=\"duration\">\n        ///     The time in miliseconds that the animator must play this path\n        /// </param>\n        /// <param name=\"function\">\n        ///     The animation function\n        /// </param>\n        /// <exception cref=\"ArgumentOutOfRangeException\">\n        ///     Duration is less than zero\n        /// </exception>\n        public Path2D(\n            float startX,\n            float endX,\n            float startY,\n            float endY,\n            ulong duration,\n            AnimationFunctions.Function function)\n            : this(new Path(startX, endX, duration, function), new Path(startY, endY, duration, function))\n        {\n        }\n\n        /// <summary>\n        ///     Initializes a new instance of the <see cref=\"Path2D\" /> class.\n        /// </summary>\n        /// <param name=\"startX\">\n        ///     The starting horizontal value\n        /// </param>\n        /// <param name=\"endX\">\n        ///     The ending horizontal value\n        /// </param>\n        /// <param name=\"startY\">\n        ///     The starting vertical value\n        /// </param>\n        /// <param name=\"endY\">\n        ///     The ending vertical value\n        /// </param>\n        /// <param name=\"duration\">\n        ///     The time in miliseconds that the animator must play this path\n        /// </param>\n        /// <exception cref=\"ArgumentOutOfRangeException\">\n        ///     Duration is less than zero\n        /// </exception>\n        public Path2D(\n            float startX,\n            float endX,\n            float startY,\n            float endY,\n            ulong duration)\n            : this(new Path(startX, endX, duration), new Path(startY, endY, duration))\n        {\n        }\n\n        /// <summary>\n        ///     Initializes a new instance of the <see cref=\"Path2D\" /> class.\n        /// </summary>\n        /// <param name=\"start\">\n        ///     The starting point or location\n        /// </param>\n        /// <param name=\"end\">\n        ///     The ending point or location\n        /// </param>\n        /// <param name=\"duration\">\n        ///     The time in miliseconds that the animator must play this path\n        /// </param>\n        /// <param name=\"delay\">\n        ///     The time in miliseconds that the animator must wait before playing this path\n        /// </param>\n        /// <param name=\"function\">\n        ///     The animation function\n        /// </param>\n        /// <exception cref=\"ArgumentOutOfRangeException\">\n        ///     Duration is less than zero\n        /// </exception>\n        public Path2D(Float2D start, Float2D end, ulong duration, ulong delay, AnimationFunctions.Function function)\n            : this(\n                new Path(start.X, end.X, duration, delay, function),\n                new Path(start.Y, end.Y, duration, delay, function))\n        {\n        }\n\n        /// <summary>\n        ///     Initializes a new instance of the <see cref=\"Path2D\" /> class.\n        /// </summary>\n        /// <param name=\"start\">\n        ///     The starting point or location\n        /// </param>\n        /// <param name=\"end\">\n        ///     The ending point or location\n        /// </param>\n        /// <param name=\"duration\">\n        ///     The time in miliseconds that the animator must play this path\n        /// </param>\n        /// <param name=\"delay\">\n        ///     The time in miliseconds that the animator must wait before playing this path\n        /// </param>\n        /// <exception cref=\"ArgumentOutOfRangeException\">\n        ///     Duration is less than zero\n        /// </exception>\n        public Path2D(Float2D start, Float2D end, ulong duration, ulong delay)\n            : this(\n                new Path(start.X, end.X, duration, delay),\n                new Path(start.Y, end.Y, duration, delay))\n        {\n        }\n\n        /// <summary>\n        ///     Initializes a new instance of the <see cref=\"Path2D\" /> class.\n        /// </summary>\n        /// <param name=\"start\">\n        ///     The starting point or location\n        /// </param>\n        /// <param name=\"end\">\n        ///     The ending point or location\n        /// </param>\n        /// <param name=\"duration\">\n        ///     The time in miliseconds that the animator must play this path\n        /// </param>\n        /// <param name=\"function\">\n        ///     The animation function\n        /// </param>\n        /// <exception cref=\"ArgumentOutOfRangeException\">\n        ///     Duration is less than zero\n        /// </exception>\n        public Path2D(Float2D start, Float2D end, ulong duration, AnimationFunctions.Function function)\n            : this(\n                new Path(start.X, end.X, duration, function),\n                new Path(start.Y, end.Y, duration, function))\n        {\n        }\n\n        /// <summary>\n        ///     Initializes a new instance of the <see cref=\"Path2D\" /> class.\n        /// </summary>\n        /// <param name=\"start\">\n        ///     The starting point or location\n        /// </param>\n        /// <param name=\"end\">\n        ///     The ending point or location\n        /// </param>\n        /// <param name=\"duration\">\n        ///     The time in miliseconds that the animator must play this path\n        /// </param>\n        /// <exception cref=\"ArgumentOutOfRangeException\">\n        ///     Duration is less than zero\n        /// </exception>\n        public Path2D(Float2D start, Float2D end, ulong duration)\n            : this(\n                new Path(start.X, end.X, duration),\n                new Path(start.Y, end.Y, duration))\n        {\n        }\n\n        /// <summary>\n        ///     Initializes a new instance of the <see cref=\"Path2D\" /> class.\n        /// </summary>\n        /// <param name=\"x\">\n        ///     The horizontal path.\n        /// </param>\n        /// <param name=\"y\">\n        ///     The vertical path.\n        /// </param>\n        public Path2D(Path x, Path y)\n        {\n            HorizontalPath = x;\n            VerticalPath = y;\n        }\n\n        /// <summary>\n        ///     Gets the horizontal path\n        /// </summary>\n        public Path HorizontalPath { get; }\n\n        /// <summary>\n        ///     Gets the vertical path\n        /// </summary>\n        public Path VerticalPath { get; }\n\n        /// <summary>\n        ///     Gets the starting point of the path\n        /// </summary>\n        public Float2D Start => new Float2D(HorizontalPath.Start, VerticalPath.Start);\n\n\n        /// <summary>\n        ///     Gets the ending point of the path\n        /// </summary>\n        public Float2D End => new Float2D(HorizontalPath.End, VerticalPath.End);\n\n        /// <summary>\n        ///     Creates and returns a new <see cref=\"Path2D\" /> based on the current path but in reverse order\n        /// </summary>\n        /// <returns>\n        ///     A new <see cref=\"Path2D\" /> which is the reverse of the current <see cref=\"Path2D\" />\n        /// </returns>\n        public Path2D Reverse()\n        {\n            return new Path2D(HorizontalPath.Reverse(), VerticalPath.Reverse());\n        }\n    }\n}"
  },
  {
    "path": "WinFormAnimation/Path2DExtensions.cs",
    "content": "﻿using System.Linq;\n\nnamespace WinFormAnimation\n{\n    /// <summary>\n    ///     Contains public extensions methods about Path2D class\n    /// </summary>\n    public static class Path2DExtensions\n    {\n        /// <summary>\n        ///     Continue the last paths with a new one\n        /// </summary>\n        /// <param name=\"paths\">Array of paths</param>\n        /// <param name=\"end\">Next point to follow</param>\n        /// <param name=\"duration\">Duration of the animation</param>\n        /// <returns>An array of paths including the newly created one</returns>\n        public static Path2D[] ContinueTo(this Path2D[] paths, Float2D end, ulong duration)\n        {\n            return paths.Concat(new[] {new Path2D(paths.Last().End, end, duration)}).ToArray();\n        }\n\n        /// <summary>\n        ///     Continue the last paths with a new one\n        /// </summary>\n        /// <param name=\"paths\">Array of paths</param>\n        /// <param name=\"end\">Next point to follow</param>\n        /// <param name=\"duration\">Duration of the animation</param>\n        /// <param name=\"function\">Animation controller function</param>\n        /// <returns>An array of paths including the newly created one</returns>\n        public static Path2D[] ContinueTo(this Path2D[] paths, Float2D end, ulong duration,\n            AnimationFunctions.Function function)\n        {\n            return paths.Concat(new[] {new Path2D(paths.Last().End, end, duration, function)}).ToArray();\n        }\n\n        /// <summary>\n        ///     Continue the last paths with a new one\n        /// </summary>\n        /// <param name=\"paths\">Array of paths</param>\n        /// <param name=\"end\">Next point to follow</param>\n        /// <param name=\"duration\">Duration of the animation</param>\n        /// <param name=\"delay\">Starting delay</param>\n        /// <returns>An array of paths including the newly created one</returns>\n        public static Path2D[] ContinueTo(this Path2D[] paths, Float2D end, ulong duration, ulong delay)\n        {\n            return paths.Concat(new[] {new Path2D(paths.Last().End, end, duration, delay)}).ToArray();\n        }\n\n        /// <summary>\n        ///     Continue the last paths with a new one\n        /// </summary>\n        /// <param name=\"paths\">Array of paths</param>\n        /// <param name=\"end\">Next point to follow</param>\n        /// <param name=\"duration\">Duration of the animation</param>\n        /// <param name=\"delay\">Starting delay</param>\n        /// <param name=\"function\">Animation controller function</param>\n        /// <returns>An array of paths including the newly created one</returns>\n        public static Path2D[] ContinueTo(this Path2D[] paths, Float2D end, ulong duration, ulong delay,\n            AnimationFunctions.Function function)\n        {\n            return paths.Concat(new[] {new Path2D(paths.Last().End, end, duration, delay, function)}).ToArray();\n        }\n\n        /// <summary>\n        ///     Continue the last paths with a new one\n        /// </summary>\n        /// <param name=\"paths\">Array of paths</param>\n        /// <param name=\"endX\">Horizontal value of the next point to follow</param>\n        /// <param name=\"endY\">Vertical value of the next point to follow</param>\n        /// <param name=\"duration\">Duration of the animation</param>\n        /// <returns>An array of paths including the newly created one</returns>\n        public static Path2D[] ContinueTo(this Path2D[] paths, float endX, float endY, ulong duration)\n        {\n            return paths.Concat(new[] {new Path2D(paths.Last().End, new Float2D(endX, endY), duration)}).ToArray();\n        }\n\n        /// <summary>\n        ///     Continue the last paths with a new one\n        /// </summary>\n        /// <param name=\"paths\">Array of paths</param>\n        /// <param name=\"endX\">Horizontal value of the next point to follow</param>\n        /// <param name=\"endY\">Vertical value of the next point to follow</param>\n        /// <param name=\"duration\">Duration of the animation</param>\n        /// <param name=\"function\">Animation controller function</param>\n        /// <returns>An array of paths including the newly created one</returns>\n        public static Path2D[] ContinueTo(this Path2D[] paths, float endX, float endY, ulong duration,\n            AnimationFunctions.Function function)\n        {\n            return\n                paths.Concat(new[] {new Path2D(paths.Last().End, new Float2D(endX, endY), duration, function)})\n                    .ToArray();\n        }\n\n        /// <summary>\n        ///     Continue the last paths with a new one\n        /// </summary>\n        /// <param name=\"paths\">Array of paths</param>\n        /// <param name=\"endX\">Horizontal value of the next point to follow</param>\n        /// <param name=\"endY\">Vertical value of the next point to follow</param>\n        /// <param name=\"duration\">Duration of the animation</param>\n        /// <param name=\"delay\">Starting delay</param>\n        /// <returns>An array of paths including the newly created one</returns>\n        public static Path2D[] ContinueTo(this Path2D[] paths, float endX, float endY, ulong duration, ulong delay)\n        {\n            return\n                paths.Concat(new[] {new Path2D(paths.Last().End, new Float2D(endX, endY), duration, delay)}).ToArray();\n        }\n\n        /// <summary>\n        ///     Continue the last paths with a new one\n        /// </summary>\n        /// <param name=\"paths\">Array of paths</param>\n        /// <param name=\"endX\">Horizontal value of the next point to follow</param>\n        /// <param name=\"endY\">Vertical value of the next point to follow</param>\n        /// <param name=\"duration\">Duration of the animation</param>\n        /// <param name=\"delay\">Starting delay</param>\n        /// <param name=\"function\">Animation controller function</param>\n        /// <returns>An array of paths including the newly created one</returns>\n        public static Path2D[] ContinueTo(this Path2D[] paths, float endX, float endY, ulong duration, ulong delay,\n            AnimationFunctions.Function function)\n        {\n            return\n                paths.Concat(new[] {new Path2D(paths.Last().End, new Float2D(endX, endY), duration, delay, function)})\n                    .ToArray();\n        }\n\n        /// <summary>\n        ///     Continue the path with a new one\n        /// </summary>\n        /// <param name=\"path\">The path to continue</param>\n        /// <param name=\"end\">Next point to follow</param>\n        /// <param name=\"duration\">Duration of the animation</param>\n        /// <returns>An array of paths including the newly created one</returns>\n        public static Path2D[] ContinueTo(this Path2D path, Float2D end, ulong duration)\n        {\n            return path.ToArray().ContinueTo(end, duration);\n        }\n\n        /// <summary>\n        ///     Continue the path with a new one\n        /// </summary>\n        /// <param name=\"path\">The path to continue</param>\n        /// <param name=\"end\">Next point to follow</param>\n        /// <param name=\"duration\">Duration of the animation</param>\n        /// <param name=\"function\">Animation controller function</param>\n        /// <returns>An array of paths including the newly created one</returns>\n        public static Path2D[] ContinueTo(this Path2D path, Float2D end, ulong duration,\n            AnimationFunctions.Function function)\n        {\n            return path.ToArray().ContinueTo(end, duration, function);\n        }\n\n        /// <summary>\n        ///     Continue the path with a new one\n        /// </summary>\n        /// <param name=\"path\">The path to continue</param>\n        /// <param name=\"end\">Next point to follow</param>\n        /// <param name=\"duration\">Duration of the animation</param>\n        /// <param name=\"delay\">Starting delay</param>\n        /// <returns>An array of paths including the newly created one</returns>\n        public static Path2D[] ContinueTo(this Path2D path, Float2D end, ulong duration, ulong delay)\n        {\n            return path.ToArray().ContinueTo(end, duration, delay);\n        }\n\n        /// <summary>\n        ///     Continue the path with a new one\n        /// </summary>\n        /// <param name=\"path\">The path to continue</param>\n        /// <param name=\"end\">Next point to follow</param>\n        /// <param name=\"duration\">Duration of the animation</param>\n        /// <param name=\"delay\">Starting delay</param>\n        /// <param name=\"function\">Animation controller function</param>\n        /// <returns>An array of paths including the newly created one</returns>\n        public static Path2D[] ContinueTo(this Path2D path, Float2D end, ulong duration, ulong delay,\n            AnimationFunctions.Function function)\n        {\n            return path.ToArray().ContinueTo(end, duration, delay, function);\n        }\n\n        /// <summary>\n        ///     Continue the path with a new one\n        /// </summary>\n        /// <param name=\"path\">The path to continue</param>\n        /// <param name=\"endX\">Horizontal value of the next point to follow</param>\n        /// <param name=\"endY\">Vertical value of the next point to follow</param>\n        /// <param name=\"duration\">Duration of the animation</param>\n        /// <returns>An array of paths including the newly created one</returns>\n        public static Path2D[] ContinueTo(this Path2D path, float endX, float endY, ulong duration)\n        {\n            return path.ToArray().ContinueTo(endX, endY, duration);\n        }\n\n        /// <summary>\n        ///     Continue the path with a new one\n        /// </summary>\n        /// <param name=\"path\">The path to continue</param>\n        /// <param name=\"endX\">Horizontal value of the next point to follow</param>\n        /// <param name=\"endY\">Vertical value of the next point to follow</param>\n        /// <param name=\"duration\">Duration of the animation</param>\n        /// <param name=\"function\">Animation controller function</param>\n        /// <returns>An array of paths including the newly created one</returns>\n        public static Path2D[] ContinueTo(this Path2D path, float endX, float endY, ulong duration,\n            AnimationFunctions.Function function)\n        {\n            return path.ToArray().ContinueTo(endX, endY, duration, function);\n        }\n\n        /// <summary>\n        ///     Continue the path with a new one\n        /// </summary>\n        /// <param name=\"path\">The path to continue</param>\n        /// <param name=\"endX\">Horizontal value of the next point to follow</param>\n        /// <param name=\"endY\">Vertical value of the next point to follow</param>\n        /// <param name=\"duration\">Duration of the animation</param>\n        /// <param name=\"delay\">Starting delay</param>\n        /// <returns>An array of paths including the newly created one</returns>\n        public static Path2D[] ContinueTo(this Path2D path, float endX, float endY, ulong duration, ulong delay)\n        {\n            return path.ToArray().ContinueTo(endX, endY, duration, delay);\n        }\n\n        /// <summary>\n        ///     Continue the path with a new one\n        /// </summary>\n        /// <param name=\"path\">The path to continue</param>\n        /// <param name=\"endX\">Horizontal value of the next point to follow</param>\n        /// <param name=\"endY\">Vertical value of the next point to follow</param>\n        /// <param name=\"duration\">Duration of the animation</param>\n        /// <param name=\"delay\">Starting delay</param>\n        /// <param name=\"function\">Animation controller function</param>\n        /// <returns>An array of paths including the newly created one</returns>\n        public static Path2D[] ContinueTo(this Path2D path, float endX, float endY, ulong duration, ulong delay,\n            AnimationFunctions.Function function)\n        {\n            return path.ToArray().ContinueTo(endX, endY, duration, delay, function);\n        }\n\n        /// <summary>\n        ///     Continue the path array with a new ones\n        /// </summary>\n        /// <param name=\"paths\">Array of paths</param>\n        /// <param name=\"newPaths\">An array of new paths to adds</param>\n        /// <returns>An array of paths including the new ones</returns>\n        public static Path2D[] ContinueTo(this Path2D[] paths, params Path2D[] newPaths)\n        {\n            return paths.Concat(newPaths).ToArray();\n        }\n\n        /// <summary>\n        ///     Continue the path with a new ones\n        /// </summary>\n        /// <param name=\"path\">The path to continue</param>\n        /// <param name=\"newPaths\">An array of new paths to adds</param>\n        /// <returns>An array of paths including the new ones</returns>\n        public static Path2D[] ContinueTo(this Path2D path, params Path2D[] newPaths)\n        {\n            return path.ToArray().ContinueTo(newPaths);\n        }\n\n        /// <summary>\n        ///     Contains a single path in an array\n        /// </summary>\n        /// <param name=\"path\">The path to add to the array</param>\n        /// <returns>An array of paths including the new ones</returns>\n        public static Path2D[] ToArray(this Path2D path)\n        {\n            return new[] {path};\n        }\n    }\n}"
  },
  {
    "path": "WinFormAnimation/Path3D.cs",
    "content": "﻿using System;\n\nnamespace WinFormAnimation\n{\n    /// <summary>\n    ///     The Path3D class is a representation of a line in a 3D plane and the\n    ///     speed in which the animator plays it\n    /// </summary>\n    public class Path3D\n    {\n        /// <summary>\n        ///     Initializes a new instance of the <see cref=\"Path3D\" /> class.\n        /// </summary>\n        /// <param name=\"startX\">\n        ///     The starting horizontal value\n        /// </param>\n        /// <param name=\"endX\">\n        ///     The ending horizontal value\n        /// </param>\n        /// <param name=\"startY\">\n        ///     The starting vertical value\n        /// </param>\n        /// <param name=\"endY\">\n        ///     The ending vertical value\n        /// </param>\n        /// <param name=\"startZ\">\n        ///     The starting depth value\n        /// </param>\n        /// <param name=\"endZ\">\n        ///     The ending depth value\n        /// </param>\n        /// <param name=\"duration\">\n        ///     The time in miliseconds that the animator must play this path\n        /// </param>\n        /// <param name=\"delay\">\n        ///     The time in miliseconds that the animator must wait before playing this path\n        /// </param>\n        /// <param name=\"function\">\n        ///     The animation function\n        /// </param>\n        /// <exception cref=\"ArgumentOutOfRangeException\">\n        ///     Duration is less than zero\n        /// </exception>\n        public Path3D(\n            float startX,\n            float endX,\n            float startY,\n            float endY,\n            float startZ,\n            float endZ,\n            ulong duration,\n            ulong delay,\n            AnimationFunctions.Function function)\n            : this(\n                new Path(startX, endX, duration, delay, function),\n                new Path(startY, endY, duration, delay, function),\n                new Path(startZ, endZ, duration, delay, function))\n        {\n        }\n\n        /// <summary>\n        ///     Initializes a new instance of the <see cref=\"Path3D\" /> class.\n        /// </summary>\n        /// <param name=\"startX\">\n        ///     The starting horizontal value\n        /// </param>\n        /// <param name=\"endX\">\n        ///     The ending horizontal value\n        /// </param>\n        /// <param name=\"startY\">\n        ///     The starting vertical value\n        /// </param>\n        /// <param name=\"endY\">\n        ///     The ending vertical value\n        /// </param>\n        /// <param name=\"startZ\">\n        ///     The starting depth value\n        /// </param>\n        /// <param name=\"endZ\">\n        ///     The ending depth value\n        /// </param>\n        /// <param name=\"duration\">\n        ///     The time in miliseconds that the animator must play this path\n        /// </param>\n        /// <param name=\"delay\">\n        ///     The time in miliseconds that the animator must wait before playing this path\n        /// </param>\n        /// <exception cref=\"ArgumentOutOfRangeException\">\n        ///     Duration is less than zero\n        /// </exception>\n        public Path3D(\n            float startX,\n            float endX,\n            float startY,\n            float endY,\n            float startZ,\n            float endZ,\n            ulong duration,\n            ulong delay)\n            : this(\n                new Path(startX, endX, duration, delay),\n                new Path(startY, endY, duration, delay),\n                new Path(startZ, endZ, duration, delay))\n        {\n        }\n\n        /// <summary>\n        ///     Initializes a new instance of the <see cref=\"Path3D\" /> class.\n        /// </summary>\n        /// <param name=\"startX\">\n        ///     The starting horizontal value\n        /// </param>\n        /// <param name=\"endX\">\n        ///     The ending horizontal value\n        /// </param>\n        /// <param name=\"startY\">\n        ///     The starting vertical value\n        /// </param>\n        /// <param name=\"endY\">\n        ///     The ending vertical value\n        /// </param>\n        /// <param name=\"startZ\">\n        ///     The starting depth value\n        /// </param>\n        /// <param name=\"endZ\">\n        ///     The ending depth value\n        /// </param>\n        /// <param name=\"duration\">\n        ///     The time in miliseconds that the animator must play this path\n        /// </param>\n        /// <param name=\"function\">\n        ///     The animation function\n        /// </param>\n        /// <exception cref=\"ArgumentOutOfRangeException\">\n        ///     Duration is less than zero\n        /// </exception>\n        public Path3D(\n            float startX,\n            float endX,\n            float startY,\n            float endY,\n            float startZ,\n            float endZ,\n            ulong duration,\n            AnimationFunctions.Function function)\n            : this(\n                new Path(startX, endX, duration, function),\n                new Path(startY, endY, duration, function),\n                new Path(startZ, endZ, duration, function))\n        {\n        }\n\n        /// <summary>\n        ///     Initializes a new instance of the <see cref=\"Path3D\" /> class.\n        /// </summary>\n        /// <param name=\"startX\">\n        ///     The starting horizontal value\n        /// </param>\n        /// <param name=\"endX\">\n        ///     The ending horizontal value\n        /// </param>\n        /// <param name=\"startY\">\n        ///     The starting vertical value\n        /// </param>\n        /// <param name=\"endY\">\n        ///     The ending vertical value\n        /// </param>\n        /// <param name=\"startZ\">\n        ///     The starting depth value\n        /// </param>\n        /// <param name=\"endZ\">\n        ///     The ending depth value\n        /// </param>\n        /// <param name=\"duration\">\n        ///     The time in miliseconds that the animator must play this path\n        /// </param>\n        /// <exception cref=\"ArgumentOutOfRangeException\">\n        ///     Duration is less than zero\n        /// </exception>\n        public Path3D(\n            float startX,\n            float endX,\n            float startY,\n            float endY,\n            float startZ,\n            float endZ,\n            ulong duration)\n            : this(new Path(startX, endX, duration), new Path(startY, endY, duration), new Path(startZ, endZ, duration))\n        {\n        }\n\n        /// <summary>\n        ///     Initializes a new instance of the <see cref=\"Path3D\" /> class.\n        /// </summary>\n        /// <param name=\"start\">\n        ///     The starting point in a 3D plane\n        /// </param>\n        /// <param name=\"end\">\n        ///     The ending point in a 3D plane\n        /// </param>\n        /// <param name=\"duration\">\n        ///     The time in miliseconds that the animator must play this path\n        /// </param>\n        /// <param name=\"delay\">\n        ///     The time in miliseconds that the animator must wait before playing this path\n        /// </param>\n        /// <param name=\"function\">\n        ///     The animation function\n        /// </param>\n        /// <exception cref=\"ArgumentOutOfRangeException\">\n        ///     Duration is less than zero\n        /// </exception>\n        public Path3D(Float3D start, Float3D end, ulong duration, ulong delay, AnimationFunctions.Function function)\n            : this(\n                new Path(start.X, end.X, duration, delay, function),\n                new Path(start.Y, end.Y, duration, delay, function),\n                new Path(start.Z, end.Z, duration, delay, function))\n        {\n        }\n\n        /// <summary>\n        ///     Initializes a new instance of the <see cref=\"Path3D\" /> class.\n        /// </summary>\n        /// <param name=\"start\">\n        ///     The starting point in a 3D plane\n        /// </param>\n        /// <param name=\"end\">\n        ///     The ending point in a 3D plane\n        /// </param>\n        /// <param name=\"duration\">\n        ///     The time in miliseconds that the animator must play this path\n        /// </param>\n        /// <param name=\"delay\">\n        ///     The time in miliseconds that the animator must wait before playing this path\n        /// </param>\n        /// <exception cref=\"ArgumentOutOfRangeException\">\n        ///     Duration is less than zero\n        /// </exception>\n        public Path3D(Float3D start, Float3D end, ulong duration, ulong delay)\n            : this(\n                new Path(start.X, end.X, duration, delay),\n                new Path(start.Y, end.Y, duration, delay),\n                new Path(start.Z, end.Z, duration, delay))\n        {\n        }\n\n        /// <summary>\n        ///     Initializes a new instance of the <see cref=\"Path3D\" /> class.\n        /// </summary>\n        /// <param name=\"start\">\n        ///     The starting point in a 3D plane\n        /// </param>\n        /// <param name=\"end\">\n        ///     The ending point in a 3D plane\n        /// </param>\n        /// <param name=\"duration\">\n        ///     The time in miliseconds that the animator must play this path\n        /// </param>\n        /// <param name=\"function\">\n        ///     The animation function\n        /// </param>\n        /// <exception cref=\"ArgumentOutOfRangeException\">\n        ///     Duration is less than zero\n        /// </exception>\n        public Path3D(Float3D start, Float3D end, ulong duration, AnimationFunctions.Function function)\n            : this(\n                new Path(start.X, end.X, duration, function),\n                new Path(start.Y, end.Y, duration, function),\n                new Path(start.Z, end.Z, duration, function))\n        {\n        }\n\n        /// <summary>\n        ///     Initializes a new instance of the <see cref=\"Path3D\" /> class.\n        /// </summary>\n        /// <param name=\"start\">\n        ///     The starting point in a 3D plane\n        /// </param>\n        /// <param name=\"end\">\n        ///     The ending point in a 3D plane\n        /// </param>\n        /// <param name=\"duration\">\n        ///     The time in miliseconds that the animator must play this path\n        /// </param>\n        /// <exception cref=\"ArgumentOutOfRangeException\">\n        ///     Duration is less than zero\n        /// </exception>\n        public Path3D(Float3D start, Float3D end, ulong duration)\n            : this(\n                new Path(start.X, end.X, duration),\n                new Path(start.Y, end.Y, duration),\n                new Path(start.Z, end.Z, duration))\n        {\n        }\n\n        /// <summary>\n        ///     Initializes a new instance of the <see cref=\"Path3D\" /> class.\n        /// </summary>\n        /// <param name=\"x\">\n        ///     The horizontal path.\n        /// </param>\n        /// <param name=\"y\">\n        ///     The vertical path.\n        /// </param>\n        /// <param name=\"z\">\n        ///     The depth path.\n        /// </param>\n        public Path3D(Path x, Path y, Path z)\n        {\n            HorizontalPath = x;\n            VerticalPath = y;\n            DepthPath = z;\n        }\n\n        /// <summary>\n        ///     Gets the horizontal path\n        /// </summary>\n        public Path HorizontalPath { get; }\n\n        /// <summary>\n        ///     Gets the vertical path\n        /// </summary>\n        public Path VerticalPath { get; }\n\n        /// <summary>\n        ///     Gets the depth path\n        /// </summary>\n        public Path DepthPath { get; }\n\n\n        /// <summary>\n        ///     Gets the starting point of the path\n        /// </summary>\n        public Float3D Start => new Float3D(HorizontalPath.Start, VerticalPath.Start, DepthPath.Start);\n\n\n        /// <summary>\n        ///     Gets the ending point of the path\n        /// </summary>\n        public Float3D End => new Float3D(HorizontalPath.End, VerticalPath.End, DepthPath.End);\n\n        /// <summary>\n        ///     Creates and returns a new <see cref=\"Path3D\" /> based on the current path but in reverse order\n        /// </summary>\n        /// <returns>\n        ///     A new <see cref=\"Path\" /> which is the reverse of the current <see cref=\"Path3D\" />\n        /// </returns>\n        public Path3D Reverse()\n        {\n            return new Path3D(HorizontalPath.Reverse(), VerticalPath.Reverse(), DepthPath.Reverse());\n        }\n    }\n}"
  },
  {
    "path": "WinFormAnimation/Path3DExtensions.cs",
    "content": "﻿using System.Linq;\n\nnamespace WinFormAnimation\n{\n    /// <summary>\n    ///     Contains public extensions methods about Path3D class\n    /// </summary>\n    public static class Path3DExtensions\n    {\n        /// <summary>\n        ///     Continue the last paths with a new one\n        /// </summary>\n        /// <param name=\"paths\">Array of paths</param>\n        /// <param name=\"end\">Next point to follow</param>\n        /// <param name=\"duration\">Duration of the animation</param>\n        /// <returns>An array of paths including the newly created one</returns>\n        public static Path3D[] ContinueTo(this Path3D[] paths, Float3D end, ulong duration)\n        {\n            return paths.Concat(new[] {new Path3D(paths.Last().End, end, duration)}).ToArray();\n        }\n\n        /// <summary>\n        ///     Continue the last paths with a new one\n        /// </summary>\n        /// <param name=\"paths\">Array of paths</param>\n        /// <param name=\"end\">Next point to follow</param>\n        /// <param name=\"duration\">Duration of the animation</param>\n        /// <param name=\"function\">Animation controller function</param>\n        /// <returns>An array of paths including the newly created one</returns>\n        public static Path3D[] ContinueTo(this Path3D[] paths, Float3D end, ulong duration,\n            AnimationFunctions.Function function)\n        {\n            return paths.Concat(new[] {new Path3D(paths.Last().End, end, duration, function)}).ToArray();\n        }\n\n        /// <summary>\n        ///     Continue the last paths with a new one\n        /// </summary>\n        /// <param name=\"paths\">Array of paths</param>\n        /// <param name=\"end\">Next point to follow</param>\n        /// <param name=\"duration\">Duration of the animation</param>\n        /// <param name=\"delay\">Starting delay</param>\n        /// <returns>An array of paths including the newly created one</returns>\n        public static Path3D[] ContinueTo(this Path3D[] paths, Float3D end, ulong duration, ulong delay)\n        {\n            return paths.Concat(new[] {new Path3D(paths.Last().End, end, duration, delay)}).ToArray();\n        }\n\n        /// <summary>\n        ///     Continue the last paths with a new one\n        /// </summary>\n        /// <param name=\"paths\">Array of paths</param>\n        /// <param name=\"end\">Next point to follow</param>\n        /// <param name=\"duration\">Duration of the animation</param>\n        /// <param name=\"delay\">Starting delay</param>\n        /// <param name=\"function\">Animation controller function</param>\n        /// <returns>An array of paths including the newly created one</returns>\n        public static Path3D[] ContinueTo(this Path3D[] paths, Float3D end, ulong duration, ulong delay,\n            AnimationFunctions.Function function)\n        {\n            return paths.Concat(new[] {new Path3D(paths.Last().End, end, duration, delay, function)}).ToArray();\n        }\n\n        /// <summary>\n        ///     Continue the last paths with a new one\n        /// </summary>\n        /// <param name=\"paths\">Array of paths</param>\n        /// <param name=\"endX\">Horizontal value of the next point to follow</param>\n        /// <param name=\"endY\">Vertical value of the next point to follow</param>\n        /// <param name=\"endZ\">Depth value of the next point to follow</param>\n        /// <param name=\"duration\">Duration of the animation</param>\n        /// <returns>An array of paths including the newly created one</returns>\n        public static Path3D[] ContinueTo(this Path3D[] paths, float endX, float endY, float endZ, ulong duration)\n        {\n            return paths.Concat(new[] {new Path3D(paths.Last().End, new Float3D(endX, endY, endZ), duration)}).ToArray();\n        }\n\n        /// <summary>\n        ///     Continue the last paths with a new one\n        /// </summary>\n        /// <param name=\"paths\">Array of paths</param>\n        /// <param name=\"endX\">Horizontal value of the next point to follow</param>\n        /// <param name=\"endY\">Vertical value of the next point to follow</param>\n        /// <param name=\"endZ\">Depth value of the next point to follow</param>\n        /// <param name=\"duration\">Duration of the animation</param>\n        /// <param name=\"function\">Animation controller function</param>\n        /// <returns>An array of paths including the newly created one</returns>\n        public static Path3D[] ContinueTo(this Path3D[] paths, float endX, float endY, float endZ, ulong duration,\n            AnimationFunctions.Function function)\n        {\n            return\n                paths.Concat(new[] {new Path3D(paths.Last().End, new Float3D(endX, endY, endZ), duration, function)})\n                    .ToArray();\n        }\n\n        /// <summary>\n        ///     Continue the last paths with a new one\n        /// </summary>\n        /// <param name=\"paths\">Array of paths</param>\n        /// <param name=\"endX\">Horizontal value of the next point to follow</param>\n        /// <param name=\"endY\">Vertical value of the next point to follow</param>\n        /// <param name=\"endZ\">Depth value of the next point to follow</param>\n        /// <param name=\"duration\">Duration of the animation</param>\n        /// <param name=\"delay\">Starting delay</param>\n        /// <returns>An array of paths including the newly created one</returns>\n        public static Path3D[] ContinueTo(this Path3D[] paths, float endX, float endY, float endZ, ulong duration,\n            ulong delay)\n        {\n            return\n                paths.Concat(new[] {new Path3D(paths.Last().End, new Float3D(endX, endY, endZ), duration, delay)})\n                    .ToArray();\n        }\n\n        /// <summary>\n        ///     Continue the last paths with a new one\n        /// </summary>\n        /// <param name=\"paths\">Array of paths</param>\n        /// <param name=\"endX\">Horizontal value of the next point to follow</param>\n        /// <param name=\"endY\">Vertical value of the next point to follow</param>\n        /// <param name=\"endZ\">Depth value of the next point to follow</param>\n        /// <param name=\"duration\">Duration of the animation</param>\n        /// <param name=\"delay\">Starting delay</param>\n        /// <param name=\"function\">Animation controller function</param>\n        /// <returns>An array of paths including the newly created one</returns>\n        public static Path3D[] ContinueTo(this Path3D[] paths, float endX, float endY, float endZ, ulong duration,\n            ulong delay,\n            AnimationFunctions.Function function)\n        {\n            return\n                paths.Concat(new[]\n                {new Path3D(paths.Last().End, new Float3D(endX, endY, endZ), duration, delay, function)})\n                    .ToArray();\n        }\n\n\n        /// <summary>\n        ///     Continue the path with a new one\n        /// </summary>\n        /// <param name=\"path\">The path to continue</param>\n        /// <param name=\"end\">Next point to follow</param>\n        /// <param name=\"duration\">Duration of the animation</param>\n        /// <returns>An array of paths including the newly created one</returns>\n        public static Path3D[] ContinueTo(this Path3D path, Float3D end, ulong duration)\n        {\n            return path.ToArray().ContinueTo(end, duration);\n        }\n\n        /// <summary>\n        ///     Continue the path with a new one\n        /// </summary>\n        /// <param name=\"path\">The path to continue</param>\n        /// <param name=\"end\">Next point to follow</param>\n        /// <param name=\"duration\">Duration of the animation</param>\n        /// <param name=\"function\">Animation controller function</param>\n        /// <returns>An array of paths including the newly created one</returns>\n        public static Path3D[] ContinueTo(this Path3D path, Float3D end, ulong duration,\n            AnimationFunctions.Function function)\n        {\n            return path.ToArray().ContinueTo(end, duration, function);\n        }\n\n        /// <summary>\n        ///     Continue the path with a new one\n        /// </summary>\n        /// <param name=\"path\">The path to continue</param>\n        /// <param name=\"end\">Next point to follow</param>\n        /// <param name=\"duration\">Duration of the animation</param>\n        /// <param name=\"delay\">Starting delay</param>\n        /// <returns>An array of paths including the newly created one</returns>\n        public static Path3D[] ContinueTo(this Path3D path, Float3D end, ulong duration, ulong delay)\n        {\n            return path.ToArray().ContinueTo(end, duration, delay);\n        }\n\n        /// <summary>\n        ///     Continue the path with a new one\n        /// </summary>\n        /// <param name=\"path\">The path to continue</param>\n        /// <param name=\"end\">Next point to follow</param>\n        /// <param name=\"duration\">Duration of the animation</param>\n        /// <param name=\"delay\">Starting delay</param>\n        /// <param name=\"function\">Animation controller function</param>\n        /// <returns>An array of paths including the newly created one</returns>\n        public static Path3D[] ContinueTo(this Path3D path, Float3D end, ulong duration, ulong delay,\n            AnimationFunctions.Function function)\n        {\n            return path.ToArray().ContinueTo(end, duration, delay, function);\n        }\n\n        /// <summary>\n        ///     Continue the path with a new one\n        /// </summary>\n        /// <param name=\"path\">The path to continue</param>\n        /// <param name=\"endX\">Horizontal value of the next point to follow</param>\n        /// <param name=\"endY\">Vertical value of the next point to follow</param>\n        /// <param name=\"endZ\">Depth value of the next point to follow</param>\n        /// <param name=\"duration\">Duration of the animation</param>\n        /// <returns>An array of paths including the newly created one</returns>\n        public static Path3D[] ContinueTo(this Path3D path, float endX, float endY, float endZ, ulong duration)\n        {\n            return path.ToArray().ContinueTo(endX, endY, endZ, duration);\n        }\n\n        /// <summary>\n        ///     Continue the path with a new one\n        /// </summary>\n        /// <param name=\"path\">The path to continue</param>\n        /// <param name=\"endX\">Horizontal value of the next point to follow</param>\n        /// <param name=\"endY\">Vertical value of the next point to follow</param>\n        /// <param name=\"endZ\">Depth value of the next point to follow</param>\n        /// <param name=\"duration\">Duration of the animation</param>\n        /// <param name=\"function\">Animation controller function</param>\n        /// <returns>An array of paths including the newly created one</returns>\n        public static Path3D[] ContinueTo(this Path3D path, float endX, float endY, float endZ, ulong duration,\n            AnimationFunctions.Function function)\n        {\n            return path.ToArray().ContinueTo(endX, endY, endZ, duration, function);\n        }\n\n        /// <summary>\n        ///     Continue the path with a new one\n        /// </summary>\n        /// <param name=\"path\">The path to continue</param>\n        /// <param name=\"endX\">Horizontal value of the next point to follow</param>\n        /// <param name=\"endY\">Vertical value of the next point to follow</param>\n        /// <param name=\"endZ\">Depth value of the next point to follow</param>\n        /// <param name=\"duration\">Duration of the animation</param>\n        /// <param name=\"delay\">Starting delay</param>\n        /// <returns>An array of paths including the newly created one</returns>\n        public static Path3D[] ContinueTo(this Path3D path, float endX, float endY, float endZ, ulong duration,\n            ulong delay)\n        {\n            return path.ToArray().ContinueTo(endX, endY, endZ, duration, delay);\n        }\n\n        /// <summary>\n        ///     Continue the path with a new one\n        /// </summary>\n        /// <param name=\"path\">The path to continue</param>\n        /// <param name=\"endX\">Horizontal value of the next point to follow</param>\n        /// <param name=\"endY\">Vertical value of the next point to follow</param>\n        /// <param name=\"endZ\">Depth value of the next point to follow</param>\n        /// <param name=\"duration\">Duration of the animation</param>\n        /// <param name=\"delay\">Starting delay</param>\n        /// <param name=\"function\">Animation controller function</param>\n        /// <returns>An array of paths including the newly created one</returns>\n        public static Path3D[] ContinueTo(this Path3D path, float endX, float endY, float endZ, ulong duration,\n            ulong delay,\n            AnimationFunctions.Function function)\n        {\n            return path.ToArray().ContinueTo(endX, endY, endZ, duration, delay, function);\n        }\n\n\n        /// <summary>\n        ///     Continue the path array with a new ones\n        /// </summary>\n        /// <param name=\"paths\">Array of paths</param>\n        /// <param name=\"newPaths\">An array of new paths to adds</param>\n        /// <returns>An array of paths including the new ones</returns>\n        public static Path3D[] ContinueTo(this Path3D[] paths, params Path3D[] newPaths)\n        {\n            return paths.Concat(newPaths).ToArray();\n        }\n\n        /// <summary>\n        ///     Continue the path with a new ones\n        /// </summary>\n        /// <param name=\"path\">The path to continue</param>\n        /// <param name=\"newPaths\">An array of new paths to adds</param>\n        /// <returns>An array of paths including the new ones</returns>\n        public static Path3D[] ContinueTo(this Path3D path, params Path3D[] newPaths)\n        {\n            return path.ToArray().ContinueTo(newPaths);\n        }\n\n        /// <summary>\n        ///     Contains a single path in an array\n        /// </summary>\n        /// <param name=\"path\">The path to add to the array</param>\n        /// <returns>An array of paths including the new ones</returns>\n        public static Path3D[] ToArray(this Path3D path)\n        {\n            return new[] {path};\n        }\n    }\n}"
  },
  {
    "path": "WinFormAnimation/PathExtensions.cs",
    "content": "﻿using System.Linq;\n\nnamespace WinFormAnimation\n{\n    /// <summary>\n    ///     Contains public extensions methods about Path class\n    /// </summary>\n    public static class PathExtensions\n    {\n        /// <summary>\n        ///     Continue the last paths with a new one\n        /// </summary>\n        /// <param name=\"paths\">Array of paths</param>\n        /// <param name=\"end\">Next point to follow</param>\n        /// <param name=\"duration\">Duration of the animation</param>\n        /// <returns>An array of paths including the newly created one</returns>\n        public static Path[] ContinueTo(this Path[] paths, float end, ulong duration)\n        {\n            return paths.Concat(new[] {new Path(paths.Last().End, end, duration)}).ToArray();\n        }\n\n        /// <summary>\n        ///     Continue the last paths with a new one\n        /// </summary>\n        /// <param name=\"paths\">Array of paths</param>\n        /// <param name=\"end\">Next point to follow</param>\n        /// <param name=\"duration\">Duration of the animation</param>\n        /// <param name=\"function\">Animation controller function</param>\n        /// <returns>An array of paths including the newly created one</returns>\n        public static Path[] ContinueTo(this Path[] paths, float end, ulong duration,\n            AnimationFunctions.Function function)\n        {\n            return paths.Concat(new[] {new Path(paths.Last().End, end, duration, function)}).ToArray();\n        }\n\n        /// <summary>\n        ///     Continue the last paths with a new one\n        /// </summary>\n        /// <param name=\"paths\">Array of paths</param>\n        /// <param name=\"end\">Next point to follow</param>\n        /// <param name=\"duration\">Duration of the animation</param>\n        /// <param name=\"delay\">Starting delay</param>\n        /// <returns>An array of paths including the newly created one</returns>\n        public static Path[] ContinueTo(this Path[] paths, float end, ulong duration, ulong delay)\n        {\n            return paths.Concat(new[] {new Path(paths.Last().End, end, duration, delay)}).ToArray();\n        }\n\n        /// <summary>\n        ///     Continue the last paths with a new one\n        /// </summary>\n        /// <param name=\"paths\">Array of paths</param>\n        /// <param name=\"end\">Next point to follow</param>\n        /// <param name=\"duration\">Duration of the animation</param>\n        /// <param name=\"delay\">Starting delay</param>\n        /// <param name=\"function\">Animation controller function</param>\n        /// <returns>An array of paths including the newly created one</returns>\n        public static Path[] ContinueTo(this Path[] paths, float end, ulong duration, ulong delay,\n            AnimationFunctions.Function function)\n        {\n            return paths.Concat(new[] {new Path(paths.Last().End, end, duration, delay, function)}).ToArray();\n        }\n\n\n        /// <summary>\n        ///     Continue the path with a new one\n        /// </summary>\n        /// <param name=\"path\">The path to continue</param>\n        /// <param name=\"end\">Next point to follow</param>\n        /// <param name=\"duration\">Duration of the animation</param>\n        /// <returns>An array of paths including the newly created one</returns>\n        public static Path[] ContinueTo(this Path path, float end, ulong duration)\n        {\n            return path.ToArray().ContinueTo(end, duration);\n        }\n\n        /// <summary>\n        ///     Continue the path with a new one\n        /// </summary>\n        /// <param name=\"path\">The path to continue</param>\n        /// <param name=\"end\">Next point to follow</param>\n        /// <param name=\"duration\">Duration of the animation</param>\n        /// <param name=\"function\">Animation controller function</param>\n        /// <returns>An array of paths including the newly created one</returns>\n        public static Path[] ContinueTo(this Path path, float end, ulong duration, AnimationFunctions.Function function)\n        {\n            return path.ToArray().ContinueTo(end, duration, function);\n        }\n\n        /// <summary>\n        ///     Continue the path with a new one\n        /// </summary>\n        /// <param name=\"path\">The path to continue</param>\n        /// <param name=\"end\">Next point to follow</param>\n        /// <param name=\"duration\">Duration of the animation</param>\n        /// <param name=\"delay\">Starting delay</param>\n        /// <returns>An array of paths including the newly created one</returns>\n        public static Path[] ContinueTo(this Path path, float end, ulong duration, ulong delay)\n        {\n            return path.ToArray().ContinueTo(end, duration, delay);\n        }\n\n        /// <summary>\n        ///     Continue the path with a new one\n        /// </summary>\n        /// <param name=\"path\">The path to continue</param>\n        /// <param name=\"end\">Next point to follow</param>\n        /// <param name=\"duration\">Duration of the animation</param>\n        /// <param name=\"delay\">Starting delay</param>\n        /// <param name=\"function\">Animation controller function</param>\n        /// <returns>An array of paths including the newly created one</returns>\n        public static Path[] ContinueTo(this Path path, float end, ulong duration, ulong delay,\n            AnimationFunctions.Function function)\n        {\n            return path.ToArray().ContinueTo(end, duration, delay, function);\n        }\n\n\n        /// <summary>\n        ///     Continue the path array with a new ones\n        /// </summary>\n        /// <param name=\"paths\">Array of paths</param>\n        /// <param name=\"newPaths\">An array of new paths to adds</param>\n        /// <returns>An array of paths including the new ones</returns>\n        public static Path[] ContinueTo(this Path[] paths, params Path[] newPaths)\n        {\n            return paths.Concat(newPaths).ToArray();\n        }\n\n        /// <summary>\n        ///     Continue the path with a new ones\n        /// </summary>\n        /// <param name=\"path\">The path to continue</param>\n        /// <param name=\"newPaths\">An array of new paths to adds</param>\n        /// <returns>An array of paths including the new ones</returns>\n        public static Path[] ContinueTo(this Path path, params Path[] newPaths)\n        {\n            return path.ToArray().ContinueTo(newPaths);\n        }\n\n        /// <summary>\n        ///     Contains a single path in an array\n        /// </summary>\n        /// <param name=\"path\">The path to add to the array</param>\n        /// <returns>An array of paths including the new ones</returns>\n        public static Path[] ToArray(this Path path)\n        {\n            return new[] {path};\n        }\n    }\n}"
  },
  {
    "path": "WinFormAnimation/SafeInvoker.cs",
    "content": "﻿using System;\nusing System.Reflection;\nusing System.Threading;\n\nnamespace WinFormAnimation\n{\n    /// <summary>\n    ///     The safe invoker class is a delegate reference holder that always\n    ///     execute them in the correct thread based on the passed control.\n    /// </summary>\n    public class SafeInvoker\n    {\n        private MethodInfo _invokeMethod;\n\n        private PropertyInfo _invokeRequiredProperty;\n        private object _targetControl;\n\n        /// <summary>\n        ///     Initializes a new instance of the SafeInvoker class.\n        /// </summary>\n        /// <param name=\"action\">\n        ///     The callback to be invoked\n        /// </param>\n        /// <param name=\"targetControl\">\n        ///     The control to be used to invoke the callback in UI thread\n        /// </param>\n        public SafeInvoker(Action action, object targetControl) : this((Delegate) action, targetControl)\n        {\n        }\n\n        /// <summary>\n        ///     Initializes a new instance of the SafeInvoker class.\n        /// </summary>\n        /// <param name=\"action\">\n        ///     The callback to be invoked\n        /// </param>\n        /// <param name=\"targetControl\">\n        ///     The control to be used to invoke the callback in UI thread\n        /// </param>\n        protected SafeInvoker(Delegate action, object targetControl)\n        {\n            UnderlyingDelegate = action;\n            if (targetControl != null)\n            {\n                TargetControl = targetControl;\n            }\n        }\n\n        /// <summary>\n        ///     Initializes a new instance of the SafeInvoker class.\n        /// </summary>\n        /// <param name=\"action\">\n        ///     The callback to be invoked\n        /// </param>\n        public SafeInvoker(Action action) : this(action, null)\n        {\n        }\n\n        /// <summary>\n        ///     Gets or sets the reference to the control thats going to be used to invoke the callback in UI thread\n        /// </summary>\n        protected object TargetControl\n        {\n            get { return _targetControl; }\n            set\n            {\n                _invokeRequiredProperty = value.GetType()\n                    .GetProperty(\"InvokeRequired\", BindingFlags.Instance | BindingFlags.Public);\n                _invokeMethod = value.GetType()\n                    .GetMethod(\n                        \"Invoke\",\n                        BindingFlags.Instance | BindingFlags.Public,\n                        Type.DefaultBinder,\n                        new[] {typeof(Delegate)},\n                        null);\n                if (_invokeRequiredProperty != null && _invokeMethod != null)\n                {\n                    _targetControl = value;\n                }\n            }\n        }\n\n\n        /// <summary>\n        ///     Gets the reference to the callback to be invoked\n        /// </summary>\n        protected Delegate UnderlyingDelegate { get; }\n\n        /// <summary>\n        ///     Invoke the contained callback\n        /// </summary>\n        public virtual void Invoke()\n        {\n            Invoke(null);\n        }\n\n        /// <summary>\n        ///     Invoke the referenced callback\n        /// </summary>\n        /// <param name=\"value\">The argument to send to the callback</param>\n        protected void Invoke(object value)\n        {\n            try\n            {\n                ThreadPool.QueueUserWorkItem(\n                    state =>\n                    {\n                        try\n                        {\n                            if (TargetControl != null && (bool)_invokeRequiredProperty.GetValue(TargetControl, null))\n                            {\n                                _invokeMethod.Invoke(\n                                    TargetControl,\n                                    new object[]\n                                    {\n                                    new Action(\n                                        () => UnderlyingDelegate.DynamicInvoke(value != null ? new[] {value} : null))\n                                    });\n                                return;\n                            }\n                        }\n                        catch\n                        {\n                            // ignored\n                        }\n                        UnderlyingDelegate.DynamicInvoke(value != null ? new[] {value} : null);\n                    });\n            }\n            catch\n            {\n                // ignored\n            }\n        }\n    }\n}"
  },
  {
    "path": "WinFormAnimation/SafeInvoker`1.cs",
    "content": "﻿using System;\n\nnamespace WinFormAnimation\n{\n    /// <summary>\n    ///     The safe invoker class is a delegate reference holder that always\n    ///     execute them in the correct thread based on the passed control.\n    /// </summary>\n    public class SafeInvoker<T> : SafeInvoker\n    {\n        /// <summary>\n        ///     Initializes a new instance of the SafeInvoker class.\n        /// </summary>\n        /// <param name=\"action\">\n        ///     The callback to be invoked\n        /// </param>\n        /// <param name=\"targetControl\">\n        ///     The control to be used to invoke the callback in UI thread\n        /// </param>\n        public SafeInvoker(Action<T> action, object targetControl) : base(action, targetControl)\n        {\n        }\n\n        /// <summary>\n        ///     Initializes a new instance of the SafeInvoker class.\n        /// </summary>\n        /// <param name=\"action\">\n        ///     The callback to be invoked\n        /// </param>\n        public SafeInvoker(Action<T> action) : this(action, null)\n        {\n        }\n\n        /// <summary>\n        ///     Invoke the contained callback with the specified value as the parameter\n        /// </summary>\n        /// <param name=\"value\"></param>\n        public void Invoke(T value)\n        {\n            Invoke((object) value);\n        }\n    }\n}"
  },
  {
    "path": "WinFormAnimation/Timer.cs",
    "content": "﻿using System;\nusing System.Collections.Generic;\nusing System.Linq;\nusing System.Threading;\n\nnamespace WinFormAnimation\n{\n    /// <summary>\n    ///     The timer class, will execute your code in specific time frames\n    /// </summary>\n    public class Timer\n    {\n        private static Thread _timerThread;\n\n        private static readonly object LockHandle = new object();\n\n        private static readonly long StartTimeAsMs = DateTime.Now.Ticks;\n\n        private static readonly List<Timer> Subscribers = new List<Timer>();\n\n        private readonly Action<ulong> _callback;\n\n        /// <summary>\n        ///     Initializes a new instance of the <see cref=\"Timer\" /> class.\n        /// </summary>\n        /// <param name=\"callback\">\n        ///     The callback to be executed at each tick\n        /// </param>\n        /// <param name=\"fpsKnownLimit\">\n        ///     The max ticks per second\n        /// </param>\n        public Timer(Action<ulong> callback, FPSLimiterKnownValues fpsKnownLimit = FPSLimiterKnownValues.LimitThirty)\n            : this(callback, (int) fpsKnownLimit)\n        {\n        }\n\n        /// <summary>\n        ///     Initializes a new instance of the <see cref=\"Timer\" /> class.\n        /// </summary>\n        /// <param name=\"callback\">\n        ///     The callback to be executed at each tick\n        /// </param>\n        /// <param name=\"fpsLimit\">\n        ///     The max ticks per second\n        /// </param>\n        public Timer(Action<ulong> callback, int fpsLimit)\n        {\n            if (callback == null)\n            {\n                throw new ArgumentNullException(nameof(callback));\n            }\n\n            _callback = callback;\n            FrameLimiter = fpsLimit;\n            lock (LockHandle)\n            {\n                if (_timerThread == null)\n                {\n                    (_timerThread = new Thread(ThreadCycle) {IsBackground = true}).Start();\n                }\n            }\n        }\n\n        /// <summary>\n        ///     Gets the time of the last frame/tick related to the global-timer start reference\n        /// </summary>\n        public long LastTick { get; private set; }\n\n        /// <summary>\n        ///     Gets or sets the maximum frames/ticks per second\n        /// </summary>\n        public int FrameLimiter { get; set; }\n\n        /// <summary>\n        ///     Gets the time of the first frame/tick related to the global-timer start reference\n        /// </summary>\n        public long FirstTick { get; private set; }\n\n\n        private void Tick()\n        {\n            if ((1000/FrameLimiter) < (GetTimeDifferenceAsMs() - LastTick))\n            {\n                LastTick = GetTimeDifferenceAsMs();\n                _callback((ulong) (LastTick - FirstTick));\n            }\n        }\n\n        private static long GetTimeDifferenceAsMs()\n        {\n            return (DateTime.Now.Ticks - StartTimeAsMs)/10000;\n        }\n\n        private static void ThreadCycle()\n        {\n            while (true)\n            {\n                try\n                {\n                    bool hibernate;\n                    lock (Subscribers)\n                    {\n                        hibernate = Subscribers.Count == 0;\n                        if (!hibernate)\n                        {\n                            foreach (var t in Subscribers.ToList())\n                            {\n                                t.Tick();\n                            }\n                        }\n                    }\n\n                    Thread.Sleep(hibernate ? 50 : 1);\n                }\n                catch\n                {\n                    // ignored\n                }\n            }\n            // ReSharper disable once FunctionNeverReturns\n        }\n\n        /// <summary>\n        ///     The method to reset the time of the starting frame/tick\n        /// </summary>\n        public void ResetClock()\n        {\n            FirstTick = GetTimeDifferenceAsMs();\n        }\n\n        /// <summary>\n        ///     The method to resume the timer after stopping it\n        /// </summary>\n        public void Resume()\n        {\n            lock (Subscribers)\n                if (!Subscribers.Contains(this))\n                {\n                    FirstTick += GetTimeDifferenceAsMs() - LastTick;\n                    Subscribers.Add(this);\n                }\n        }\n\n        /// <summary>\n        ///     The method to start the timer from the beginning\n        /// </summary>\n        public void Start()\n        {\n            lock (Subscribers)\n                if (!Subscribers.Contains(this))\n                {\n                    FirstTick = GetTimeDifferenceAsMs();\n                    Subscribers.Add(this);\n                }\n        }\n\n        /// <summary>\n        ///     The method to stop the timer from generating any new ticks/frames\n        /// </summary>\n        public void Stop()\n        {\n            lock (Subscribers)\n                if (Subscribers.Contains(this))\n                {\n                    Subscribers.Remove(this);\n                }\n        }\n    }\n}"
  },
  {
    "path": "WinFormAnimation/WinFormAnimation.csproj",
    "content": "﻿<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<Project Sdk=\"Microsoft.NET.Sdk\">\n  <PropertyGroup>\n    <TargetFrameworks>net4</TargetFrameworks>\n    <PackageId>WinFormAnimation</PackageId>\n    <Version>1.6.0.4</Version>\n    <Authors>Soroush Falahati</Authors>\n    <Description>A simple library for animating controls/values in .Net using key-frames.</Description>\n    <PackageLicenseUrl>https://github.com/falahati/WinFormAnimation/blob/master/LICENSE</PackageLicenseUrl>\n    <PackageProjectUrl>https://falahati.github.io/WinFormAnimation/</PackageProjectUrl>\n    <PackageIconUrl>https://github.com/falahati/WinFormAnimation/blob/master/WinFormAnimation/Icon.png?raw=true</PackageIconUrl>\n    <RepositoryUrl>https://github.com/falahati/WinFormAnimatio</RepositoryUrl>\n    <IncludeSymbols>true</IncludeSymbols>\n    <IncludeSource>true</IncludeSource>\n    <NeutralLanguage>en-US</NeutralLanguage>\n    <Copyright>Copyright (c) 2019 Soroush Falahati</Copyright>\n    <PlatformTarget>AnyCPU</PlatformTarget>\n    <Title>Key-Frame Based Animation Library (.Net 4+)</Title>\n    <AssemblyOriginatorKeyFile>OpenSourceStrongNameSignKey.pfx</AssemblyOriginatorKeyFile>\n  </PropertyGroup>\n  <ItemGroup>\n    <PackageReference PrivateAssets=\"all\" Include=\"MSBump\" Version=\"2.3.2\">\n      <PrivateAssets>all</PrivateAssets>\n      <IncludeAssets>runtime; build; native; contentfiles; analyzers</IncludeAssets>\n    </PackageReference>\n  </ItemGroup>\n  <ItemGroup>\n    <Content Include=\"Icon.png\">\n      <Pack>true</Pack>\n      <PackagePath>\\</PackagePath>\n    </Content>\n    <Content Include=\"readme.txt\">\n      <Pack>true</Pack>\n      <PackagePath>\\</PackagePath>\n    </Content>\n  </ItemGroup>\n  <PropertyGroup Condition=\"'$(Configuration)|$(Platform)'=='Debug|AnyCPU'\">\n    <OutputPath>..\\Debug</OutputPath>\n  </PropertyGroup>\n  <PropertyGroup Condition=\"'$(Configuration)|$(Platform)'=='Release|AnyCPU'\">\n    <BumpRevision>True</BumpRevision>\n    <GeneratePackageOnBuild>true</GeneratePackageOnBuild>\n    <OutputPath>..\\Release</OutputPath>\n    <SignAssembly>true</SignAssembly>\n  </PropertyGroup>\n</Project>"
  },
  {
    "path": "WinFormAnimation/float2D.cs",
    "content": "﻿using System;\nusing System.Drawing;\n\nnamespace WinFormAnimation\n{\n    /// <summary>\n    ///     The Float2D class contains two <see langword=\"float\" /> values and\n    ///     represents a point in a 2D plane\n    /// </summary>\n    public class Float2D : IConvertible, IEquatable<Float2D>, IEquatable<Point>, IEquatable<PointF>, IEquatable<Size>,\n        IEquatable<SizeF>\n    {\n        /// <summary>\n        ///     Initializes a new instance of the <see cref=\"Float2D\" /> class.\n        /// </summary>\n        /// <param name=\"x\">\n        ///     The horizontal value\n        /// </param>\n        /// <param name=\"y\">\n        ///     The vertical value\n        /// </param>\n        public Float2D(float x, float y)\n        {\n            X = x;\n            Y = y;\n        }\n\n        /// <summary>\n        ///     Initializes a new instance of the <see cref=\"Float2D\" /> class.\n        /// </summary>\n        public Float2D() : this(default(float), default(float))\n        {\n        }\n\n        /// <summary>\n        ///     Gets the horizontal value of the point\n        /// </summary>\n        public float X { get; set; }\n\n        /// <summary>\n        ///     Gets the vertical value of the point\n        /// </summary>\n        public float Y { get; set; }\n\n        /// <summary>\n        ///     Returns the <see cref=\"T:System.TypeCode\" /> for this instance.\n        /// </summary>\n        /// <returns>\n        ///     The enumerated constant that is the <see cref=\"T:System.TypeCode\" /> of the class or value type that implements\n        ///     this interface.\n        /// </returns>\n        public TypeCode GetTypeCode()\n        {\n            return TypeCode.Object;\n        }\n\n        /// <summary>\n        ///     Converts the value of this instance to an equivalent Boolean value using the specified culture-specific formatting\n        ///     information.\n        /// </summary>\n        /// <returns>\n        ///     A Boolean value equivalent to the value of this instance.\n        /// </returns>\n        /// <param name=\"provider\">\n        ///     An <see cref=\"T:System.IFormatProvider\" /> interface implementation that supplies\n        ///     culture-specific formatting information.\n        /// </param>\n        /// <exception cref=\"InvalidCastException\">This method is not supported</exception>\n        public bool ToBoolean(IFormatProvider provider)\n        {\n            throw new InvalidCastException();\n        }\n\n        /// <summary>\n        ///     Converts the value of this instance to an equivalent 8-bit unsigned integer using the specified culture-specific\n        ///     formatting information.\n        /// </summary>\n        /// <returns>\n        ///     An 8-bit unsigned integer equivalent to the value of this instance.\n        /// </returns>\n        /// <param name=\"provider\">\n        ///     An <see cref=\"T:System.IFormatProvider\" /> interface implementation that supplies\n        ///     culture-specific formatting information.\n        /// </param>\n        /// <exception cref=\"InvalidCastException\">This method is not supported</exception>\n        public byte ToByte(IFormatProvider provider)\n        {\n            throw new InvalidCastException();\n        }\n\n        /// <summary>\n        ///     Converts the value of this instance to an equivalent Unicode character using the specified culture-specific\n        ///     formatting information.\n        /// </summary>\n        /// <returns>\n        ///     A Unicode character equivalent to the value of this instance.\n        /// </returns>\n        /// <param name=\"provider\">\n        ///     An <see cref=\"T:System.IFormatProvider\" /> interface implementation that supplies\n        ///     culture-specific formatting information.\n        /// </param>\n        /// <exception cref=\"InvalidCastException\">This method is not supported</exception>\n        public char ToChar(IFormatProvider provider)\n        {\n            throw new InvalidCastException();\n        }\n\n\n        /// <summary>\n        ///     Converts the value of this instance to an equivalent <see cref=\"T:System.DateTime\" /> using the specified\n        ///     culture-specific formatting information.\n        /// </summary>\n        /// <returns>\n        ///     A <see cref=\"T:System.DateTime\" /> instance equivalent to the value of this instance.\n        /// </returns>\n        /// <param name=\"provider\">\n        ///     An <see cref=\"T:System.IFormatProvider\" /> interface implementation that supplies\n        ///     culture-specific formatting information.\n        /// </param>\n        /// <exception cref=\"InvalidCastException\">This method is not supported</exception>\n        public DateTime ToDateTime(IFormatProvider provider)\n        {\n            throw new InvalidCastException();\n        }\n\n\n        /// <summary>\n        ///     Converts the value of this instance to an equivalent <see cref=\"T:System.Decimal\" /> number using the specified\n        ///     culture-specific formatting information.\n        /// </summary>\n        /// <returns>\n        ///     A <see cref=\"T:System.Decimal\" /> number equivalent to the value of this instance.\n        /// </returns>\n        /// <param name=\"provider\">\n        ///     An <see cref=\"T:System.IFormatProvider\" /> interface implementation that supplies\n        ///     culture-specific formatting information.\n        /// </param>\n        /// <exception cref=\"InvalidCastException\">This method is not supported</exception>\n        public decimal ToDecimal(IFormatProvider provider)\n        {\n            throw new InvalidCastException();\n        }\n\n\n        /// <summary>\n        ///     Converts the value of this instance to an equivalent double-precision floating-point number using the specified\n        ///     culture-specific formatting information.\n        /// </summary>\n        /// <returns>\n        ///     A double-precision floating-point number equivalent to the value of this instance.\n        /// </returns>\n        /// <param name=\"provider\">\n        ///     An <see cref=\"T:System.IFormatProvider\" /> interface implementation that supplies\n        ///     culture-specific formatting information.\n        /// </param>\n        /// <exception cref=\"InvalidCastException\">This method is not supported</exception>\n        public double ToDouble(IFormatProvider provider)\n        {\n            throw new InvalidCastException();\n        }\n\n\n        /// <summary>\n        ///     Converts the value of this instance to an equivalent 16-bit signed integer using the specified culture-specific\n        ///     formatting information.\n        /// </summary>\n        /// <returns>\n        ///     An 16-bit signed integer equivalent to the value of this instance.\n        /// </returns>\n        /// <param name=\"provider\">\n        ///     An <see cref=\"T:System.IFormatProvider\" /> interface implementation that supplies\n        ///     culture-specific formatting information.\n        /// </param>\n        /// <exception cref=\"InvalidCastException\">This method is not supported</exception>\n        public short ToInt16(IFormatProvider provider)\n        {\n            throw new InvalidCastException();\n        }\n\n        /// <summary>\n        ///     Converts the value of this instance to an equivalent 32-bit signed integer using the specified culture-specific\n        ///     formatting information.\n        /// </summary>\n        /// <returns>\n        ///     An 32-bit signed integer equivalent to the value of this instance.\n        /// </returns>\n        /// <param name=\"provider\">\n        ///     An <see cref=\"T:System.IFormatProvider\" /> interface implementation that supplies\n        ///     culture-specific formatting information.\n        /// </param>\n        /// <exception cref=\"InvalidCastException\">This method is not supported</exception>\n        public int ToInt32(IFormatProvider provider)\n        {\n            throw new InvalidCastException();\n        }\n\n\n        /// <summary>\n        ///     Converts the value of this instance to an equivalent 64-bit signed integer using the specified culture-specific\n        ///     formatting information.\n        /// </summary>\n        /// <returns>\n        ///     An 64-bit signed integer equivalent to the value of this instance.\n        /// </returns>\n        /// <param name=\"provider\">\n        ///     An <see cref=\"T:System.IFormatProvider\" /> interface implementation that supplies\n        ///     culture-specific formatting information.\n        /// </param>\n        /// <exception cref=\"InvalidCastException\">This method is not supported</exception>\n        public long ToInt64(IFormatProvider provider)\n        {\n            throw new InvalidCastException();\n        }\n\n\n        /// <summary>\n        ///     Converts the value of this instance to an equivalent 8-bit signed integer using the specified culture-specific\n        ///     formatting information.\n        /// </summary>\n        /// <returns>\n        ///     An 8-bit signed integer equivalent to the value of this instance.\n        /// </returns>\n        /// <param name=\"provider\">\n        ///     An <see cref=\"T:System.IFormatProvider\" /> interface implementation that supplies\n        ///     culture-specific formatting information.\n        /// </param>\n        /// <exception cref=\"InvalidCastException\">This method is not supported</exception>\n        public sbyte ToSByte(IFormatProvider provider)\n        {\n            throw new InvalidCastException();\n        }\n\n\n        /// <summary>\n        ///     Converts the value of this instance to an equivalent single-precision floating-point number using the specified\n        ///     culture-specific formatting information.\n        /// </summary>\n        /// <returns>\n        ///     A single-precision floating-point number equivalent to the value of this instance.\n        /// </returns>\n        /// <param name=\"provider\">\n        ///     An <see cref=\"T:System.IFormatProvider\" /> interface implementation that supplies\n        ///     culture-specific formatting information.\n        /// </param>\n        /// <exception cref=\"InvalidCastException\">This method is not supported</exception>\n        public float ToSingle(IFormatProvider provider)\n        {\n            throw new InvalidCastException();\n        }\n\n        /// <summary>\n        ///     Converts the value of this instance to an equivalent 16-bit unsigned integer using the specified culture-specific\n        ///     formatting information.\n        /// </summary>\n        /// <returns>\n        ///     An 16-bit unsigned integer equivalent to the value of this instance.\n        /// </returns>\n        /// <param name=\"provider\">\n        ///     An <see cref=\"T:System.IFormatProvider\" /> interface implementation that supplies\n        ///     culture-specific formatting information.\n        /// </param>\n        /// <exception cref=\"InvalidCastException\">This method is not supported</exception>\n        public ushort ToUInt16(IFormatProvider provider)\n        {\n            throw new InvalidCastException();\n        }\n\n\n        /// <summary>\n        ///     Converts the value of this instance to an equivalent 32-bit unsigned integer using the specified culture-specific\n        ///     formatting information.\n        /// </summary>\n        /// <returns>\n        ///     An 32-bit unsigned integer equivalent to the value of this instance.\n        /// </returns>\n        /// <param name=\"provider\">\n        ///     An <see cref=\"T:System.IFormatProvider\" /> interface implementation that supplies\n        ///     culture-specific formatting information.\n        /// </param>\n        /// <exception cref=\"InvalidCastException\">This method is not supported</exception>\n        public uint ToUInt32(IFormatProvider provider)\n        {\n            throw new InvalidCastException();\n        }\n\n\n        /// <summary>\n        ///     Converts the value of this instance to an equivalent 64-bit unsigned integer using the specified culture-specific\n        ///     formatting information.\n        /// </summary>\n        /// <returns>\n        ///     An 64-bit unsigned integer equivalent to the value of this instance.\n        /// </returns>\n        /// <param name=\"provider\">\n        ///     An <see cref=\"T:System.IFormatProvider\" /> interface implementation that supplies\n        ///     culture-specific formatting information.\n        /// </param>\n        /// <exception cref=\"InvalidCastException\">This method is not supported</exception>\n        public ulong ToUInt64(IFormatProvider provider)\n        {\n            throw new InvalidCastException();\n        }\n\n        /// <summary>\n        ///     Converts the value of this instance to an equivalent <see cref=\"T:System.String\" /> using the specified\n        ///     culture-specific formatting information.\n        /// </summary>\n        /// <returns>\n        ///     A <see cref=\"T:System.String\" /> instance equivalent to the value of this instance.\n        /// </returns>\n        /// <param name=\"provider\">\n        ///     An <see cref=\"T:System.IFormatProvider\" /> interface implementation that supplies\n        ///     culture-specific formatting information.\n        /// </param>\n        public string ToString(IFormatProvider provider)\n        {\n            return ToString();\n        }\n\n        /// <summary>\n        ///     Converts the value of this instance to an <see cref=\"T:System.Object\" /> of the specified\n        ///     <see cref=\"T:System.Type\" /> that has an equivalent value, using the specified culture-specific formatting\n        ///     information.\n        /// </summary>\n        /// <returns>\n        ///     An <see cref=\"T:System.Object\" /> instance of type <paramref name=\"conversionType\" /> whose value is equivalent to\n        ///     the value of this instance.\n        /// </returns>\n        /// <param name=\"conversionType\">The <see cref=\"T:System.Type\" /> to which the value of this instance is converted. </param>\n        /// <param name=\"provider\">\n        ///     An <see cref=\"T:System.IFormatProvider\" /> interface implementation that supplies\n        ///     culture-specific formatting information.\n        /// </param>\n        public object ToType(Type conversionType, IFormatProvider provider)\n        {\n            if (conversionType == typeof (Point))\n            {\n                return (Point) this;\n            }\n            if (conversionType == typeof (Size))\n            {\n                return (Size) this;\n            }\n            if (conversionType == typeof (PointF))\n            {\n                return (PointF) this;\n            }\n            if (conversionType == typeof (SizeF))\n            {\n                return (SizeF) this;\n            }\n            throw new InvalidCastException();\n        }\n\n        /// <summary>\n        ///     Indicates whether the current object is equal to another object of the same type.\n        /// </summary>\n        /// <returns>\n        ///     true if the current object is equal to the <paramref name=\"other\" /> parameter; otherwise, false.\n        /// </returns>\n        /// <param name=\"other\">An object to compare with this object.</param>\n        public bool Equals(Float2D other)\n        {\n            return this == other;\n        }\n\n        /// <summary>\n        ///     Indicates whether the current object is equal to a <see cref=\"Point\" /> object.\n        /// </summary>\n        /// <returns>\n        ///     true if the current object is equal to the <paramref name=\"other\" /> parameter; otherwise, false.\n        /// </returns>\n        /// <param name=\"other\">An object to compare with this object.</param>\n        public bool Equals(Point other)\n        {\n            return this == other;\n        }\n\n        /// <summary>\n        ///     Indicates whether the current object is equal to a <see cref=\"PointF\" /> object.\n        /// </summary>\n        /// <returns>\n        ///     true if the current object is equal to the <paramref name=\"other\" /> parameter; otherwise, false.\n        /// </returns>\n        /// <param name=\"other\">An object to compare with this object.</param>\n        public bool Equals(PointF other)\n        {\n            return this == other;\n        }\n\n        /// <summary>\n        ///     Indicates whether the current object is equal to a <see cref=\"Size\" /> object.\n        /// </summary>\n        /// <returns>\n        ///     true if the current object is equal to the <paramref name=\"other\" /> parameter; otherwise, false.\n        /// </returns>\n        /// <param name=\"other\">An object to compare with this object.</param>\n        public bool Equals(Size other)\n        {\n            return this == other;\n        }\n\n        /// <summary>\n        ///     Indicates whether the current object is equal to a <see cref=\"SizeF\" /> object.\n        /// </summary>\n        /// <returns>\n        ///     true if the current object is equal to the <paramref name=\"other\" /> parameter; otherwise, false.\n        /// </returns>\n        /// <param name=\"other\">An object to compare with this object.</param>\n        public bool Equals(SizeF other)\n        {\n            return this == other;\n        }\n\n        /// <summary>\n        ///     Determines whether the specified <see cref=\"T:System.Object\" /> is equal to the current\n        ///     <see cref=\"T:System.Object\" />.\n        /// </summary>\n        /// <returns>\n        ///     true if the specified <see cref=\"T:System.Object\" /> is equal to the current <see cref=\"T:System.Object\" />;\n        ///     otherwise, false.\n        /// </returns>\n        /// <param name=\"obj\">The <see cref=\"T:System.Object\" /> to compare with the current <see cref=\"T:System.Object\" />. </param>\n        public override bool Equals(object obj)\n        {\n            if (ReferenceEquals(null, obj)) return false;\n            if (ReferenceEquals(this, obj)) return true;\n            var conversionType = obj.GetType();\n            if (conversionType == typeof (Point))\n            {\n                return this == (Point) obj;\n            }\n            if (conversionType == typeof (PointF))\n            {\n                return this == (PointF) obj;\n            }\n            if (conversionType == typeof (Size))\n            {\n                return this == (Size) obj;\n            }\n            if (conversionType == typeof (SizeF))\n            {\n                return this == (SizeF) obj;\n            }\n            return obj.GetType() == GetType() && Equals((Float2D) obj);\n        }\n\n        /// <summary>\n        ///     Serves as a hash function for a particular type. This code will change of the values of the X and Y changes. Make\n        ///     sure to not change the values while stored in a hash dependent data structure.\n        /// </summary>\n        /// <returns>\n        ///     A hash code for the current <see cref=\"Float2D\" />.\n        /// </returns>\n        public override int GetHashCode()\n        {\n            unchecked\n            {\n                // ReSharper disable NonReadonlyMemberInGetHashCode\n                return (X.GetHashCode()*397) ^ Y.GetHashCode();\n                // ReSharper restore NonReadonlyMemberInGetHashCode\n            }\n        }\n\n        /// <summary>\n        ///     Compares two <see cref=\"Float2D\" /> objects for equality\n        /// </summary>\n        /// <param name=\"left\">Left <see cref=\"Float2D\" /> object</param>\n        /// <param name=\"right\">Right <see cref=\"Float2D\" /> object</param>\n        /// <returns>true if both objects are equal, otherwise false</returns>\n        public static bool operator ==(Float2D left, Float2D right)\n        {\n            if (ReferenceEquals(left, null) || ReferenceEquals(right, null))\n            {\n                return ReferenceEquals(left, null) && ReferenceEquals(right, null);\n            }\n            // ReSharper disable CompareOfFloatsByEqualityOperator\n            return ReferenceEquals(left, right) || ((double) (left.X) == right.X && (double) (left.Y) == right.Y);\n            // ReSharper restore CompareOfFloatsByEqualityOperator\n        }\n\n        /// <summary>\n        ///     Compares two <see cref=\"Float2D\" /> objects for in-equality\n        /// </summary>\n        /// <param name=\"left\">Left <see cref=\"Float2D\" /> object</param>\n        /// <param name=\"right\">Right <see cref=\"Float2D\" /> object</param>\n        /// <returns>false if both objects are equal, otherwise true</returns>\n        public static bool operator !=(Float2D left, Float2D right)\n        {\n            return !(left == right);\n        }\n\n        /// <summary>\n        ///     Represents the values as an instance of the <see cref=\"Size\" /> class\n        /// </summary>\n        /// <param name=\"float2D\">\n        ///     The <see cref=\"Float2D\" /> class to convert\n        /// </param>\n        /// <returns>\n        ///     A new instance of the <see cref=\"Size\" /> class representing the values in the <see cref=\"Float2D\" /> instance\n        /// </returns>\n        public static implicit operator Size(Float2D float2D)\n        {\n            return new Size((int) float2D.X, (int) float2D.Y);\n        }\n\n        /// <summary>\n        ///     Represents the values as an instance of the <see cref=\"Point\" /> class\n        /// </summary>\n        /// <param name=\"float2D\">\n        ///     The <see cref=\"Float2D\" /> class to convert\n        /// </param>\n        /// <returns>\n        ///     A new instance of the <see cref=\"Point\" /> class representing the values in the <see cref=\"Float2D\" /> instance\n        /// </returns>\n        public static implicit operator Point(Float2D float2D)\n        {\n            return new Point((int) float2D.X, (int) float2D.Y);\n        }\n\n\n        /// <summary>\n        ///     Represents the values as an instance of the <see cref=\"SizeF\" /> class\n        /// </summary>\n        /// <param name=\"float2D\">\n        ///     The <see cref=\"Float2D\" /> class to convert\n        /// </param>\n        /// <returns>\n        ///     A new instance of the <see cref=\"SizeF\" /> class representing the values in the <see cref=\"Float2D\" /> instance\n        /// </returns>\n        public static implicit operator SizeF(Float2D float2D)\n        {\n            return new SizeF(float2D.X, float2D.Y);\n        }\n\n        /// <summary>\n        ///     Represents the values as an instance of the <see cref=\"PointF\" /> class\n        /// </summary>\n        /// <param name=\"float2D\">\n        ///     The <see cref=\"Float2D\" /> class to convert\n        /// </param>\n        /// <returns>\n        ///     A new instance of the <see cref=\"PointF\" /> class representing the values in the <see cref=\"Float2D\" /> instance\n        /// </returns>\n        public static implicit operator PointF(Float2D float2D)\n        {\n            return new PointF(float2D.X, float2D.Y);\n        }\n\n        /// <summary>\n        ///     Returns a string that represents the current <see cref=\"Float2D\" />.\n        /// </summary>\n        /// <returns>\n        ///     A string that represents the current <see cref=\"Float2D\" />.\n        /// </returns>\n        public override string ToString()\n        {\n            return \"(\" + X.ToString(\"0.00\") + \",\" + Y.ToString(\"0.00\") + \")\";\n        }\n\n        /// <summary>\n        ///     Creates and returns a new instance of the <see cref=\"Float2D\" /> class from a <see cref=\"Point\" /> instance\n        /// </summary>\n        /// <param name=\"point\">The object to create the <see cref=\"Float2D\" /> instance from</param>\n        /// <returns>The newly created <see cref=\"Float2D\" /> instance</returns>\n        public static Float2D FromPoint(Point point)\n        {\n            return new Float2D(point.X, point.Y);\n        }\n\n        /// <summary>\n        ///     Creates and returns a new instance of the <see cref=\"Float2D\" /> class from a <see cref=\"PointF\" /> instance\n        /// </summary>\n        /// <param name=\"point\">The object to create the <see cref=\"Float2D\" /> instance from</param>\n        /// <returns>The newly created <see cref=\"Float2D\" /> instance</returns>\n        public static Float2D FromPoint(PointF point)\n        {\n            return new Float2D(point.X, point.Y);\n        }\n\n        /// <summary>\n        ///     Creates and returns a new instance of the <see cref=\"Float2D\" /> class from a <see cref=\"Size\" /> instance\n        /// </summary>\n        /// <param name=\"size\">The object to create the <see cref=\"Float2D\" /> instance from</param>\n        /// <returns>The newly created <see cref=\"Float2D\" /> instance</returns>\n        public static Float2D FromSize(Size size)\n        {\n            return new Float2D(size.Width, size.Height);\n        }\n\n        /// <summary>\n        ///     Creates and returns a new instance of the <see cref=\"Float2D\" /> class from a <see cref=\"SizeF\" /> instance\n        /// </summary>\n        /// <param name=\"size\">The object to create the <see cref=\"Float2D\" /> instance from</param>\n        /// <returns>The newly created <see cref=\"Float2D\" /> instance</returns>\n        public static Float2D FromSize(SizeF size)\n        {\n            return new Float2D(size.Width, size.Height);\n        }\n    }\n}"
  },
  {
    "path": "WinFormAnimation/float3D.cs",
    "content": "﻿using System;\nusing System.Drawing;\n\nnamespace WinFormAnimation\n{\n    /// <summary>\n    ///     The Float3D class contains two <see langword=\"float\" /> values and\n    ///     represents a point in a 3D plane\n    /// </summary>\n    public class Float3D : IConvertible, IEquatable<Float3D>, IEquatable<Color>\n    {\n        /// <summary>\n        ///     Initializes a new instance of the <see cref=\"Float3D\" /> class.\n        /// </summary>\n        /// <param name=\"x\">\n        ///     The horizontal value\n        /// </param>\n        /// <param name=\"y\">\n        ///     The vertical value\n        /// </param>\n        /// <param name=\"z\">\n        ///     The depth value\n        /// </param>\n        public Float3D(float x, float y, float z)\n        {\n            X = x;\n            Y = y;\n            Z = z;\n        }\n\n        /// <summary>\n        ///     Initializes a new instance of the <see cref=\"Float3D\" /> class.\n        /// </summary>\n        public Float3D() : this(default(float), default(float), default(float))\n        {\n        }\n\n        /// <summary>\n        ///     Gets the horizontal value of the point\n        /// </summary>\n        public float X { get; set; }\n\n        /// <summary>\n        ///     Gets the vertical value of the point\n        /// </summary>\n        public float Y { get; set; }\n\n        /// <summary>\n        ///     Gets the depth value of the point\n        /// </summary>\n        public float Z { get; set; }\n\n        /// <summary>\n        ///     Returns the <see cref=\"T:System.TypeCode\" /> for this instance.\n        /// </summary>\n        /// <returns>\n        ///     The enumerated constant that is the <see cref=\"T:System.TypeCode\" /> of the class or value type that implements\n        ///     this interface.\n        /// </returns>\n        public TypeCode GetTypeCode()\n        {\n            return TypeCode.Object;\n        }\n\n\n        /// <summary>\n        ///     Converts the value of this instance to an equivalent Boolean value using the specified culture-specific formatting\n        ///     information.\n        /// </summary>\n        /// <returns>\n        ///     A Boolean value equivalent to the value of this instance.\n        /// </returns>\n        /// <param name=\"provider\">\n        ///     An <see cref=\"T:System.IFormatProvider\" /> interface implementation that supplies\n        ///     culture-specific formatting information.\n        /// </param>\n        /// <exception cref=\"InvalidCastException\">This method is not supported</exception>\n        public bool ToBoolean(IFormatProvider provider)\n        {\n            throw new InvalidCastException();\n        }\n\n        /// <summary>\n        ///     Converts the value of this instance to an equivalent 8-bit unsigned integer using the specified culture-specific\n        ///     formatting information.\n        /// </summary>\n        /// <returns>\n        ///     An 8-bit unsigned integer equivalent to the value of this instance.\n        /// </returns>\n        /// <param name=\"provider\">\n        ///     An <see cref=\"T:System.IFormatProvider\" /> interface implementation that supplies\n        ///     culture-specific formatting information.\n        /// </param>\n        /// <exception cref=\"InvalidCastException\">This method is not supported</exception>\n        public byte ToByte(IFormatProvider provider)\n        {\n            throw new InvalidCastException();\n        }\n\n        /// <summary>\n        ///     Converts the value of this instance to an equivalent Unicode character using the specified culture-specific\n        ///     formatting information.\n        /// </summary>\n        /// <returns>\n        ///     A Unicode character equivalent to the value of this instance.\n        /// </returns>\n        /// <param name=\"provider\">\n        ///     An <see cref=\"T:System.IFormatProvider\" /> interface implementation that supplies\n        ///     culture-specific formatting information.\n        /// </param>\n        /// <exception cref=\"InvalidCastException\">This method is not supported</exception>\n        public char ToChar(IFormatProvider provider)\n        {\n            throw new InvalidCastException();\n        }\n\n\n        /// <summary>\n        ///     Converts the value of this instance to an equivalent <see cref=\"T:System.DateTime\" /> using the specified\n        ///     culture-specific formatting information.\n        /// </summary>\n        /// <returns>\n        ///     A <see cref=\"T:System.DateTime\" /> instance equivalent to the value of this instance.\n        /// </returns>\n        /// <param name=\"provider\">\n        ///     An <see cref=\"T:System.IFormatProvider\" /> interface implementation that supplies\n        ///     culture-specific formatting information.\n        /// </param>\n        /// <exception cref=\"InvalidCastException\">This method is not supported</exception>\n        public DateTime ToDateTime(IFormatProvider provider)\n        {\n            throw new InvalidCastException();\n        }\n\n\n        /// <summary>\n        ///     Converts the value of this instance to an equivalent <see cref=\"T:System.Decimal\" /> number using the specified\n        ///     culture-specific formatting information.\n        /// </summary>\n        /// <returns>\n        ///     A <see cref=\"T:System.Decimal\" /> number equivalent to the value of this instance.\n        /// </returns>\n        /// <param name=\"provider\">\n        ///     An <see cref=\"T:System.IFormatProvider\" /> interface implementation that supplies\n        ///     culture-specific formatting information.\n        /// </param>\n        /// <exception cref=\"InvalidCastException\">This method is not supported</exception>\n        public decimal ToDecimal(IFormatProvider provider)\n        {\n            throw new InvalidCastException();\n        }\n\n\n        /// <summary>\n        ///     Converts the value of this instance to an equivalent double-precision floating-point number using the specified\n        ///     culture-specific formatting information.\n        /// </summary>\n        /// <returns>\n        ///     A double-precision floating-point number equivalent to the value of this instance.\n        /// </returns>\n        /// <param name=\"provider\">\n        ///     An <see cref=\"T:System.IFormatProvider\" /> interface implementation that supplies\n        ///     culture-specific formatting information.\n        /// </param>\n        /// <exception cref=\"InvalidCastException\">This method is not supported</exception>\n        public double ToDouble(IFormatProvider provider)\n        {\n            throw new InvalidCastException();\n        }\n\n\n        /// <summary>\n        ///     Converts the value of this instance to an equivalent 16-bit signed integer using the specified culture-specific\n        ///     formatting information.\n        /// </summary>\n        /// <returns>\n        ///     An 16-bit signed integer equivalent to the value of this instance.\n        /// </returns>\n        /// <param name=\"provider\">\n        ///     An <see cref=\"T:System.IFormatProvider\" /> interface implementation that supplies\n        ///     culture-specific formatting information.\n        /// </param>\n        /// <exception cref=\"InvalidCastException\">This method is not supported</exception>\n        public short ToInt16(IFormatProvider provider)\n        {\n            throw new InvalidCastException();\n        }\n\n        /// <summary>\n        ///     Converts the value of this instance to an equivalent 32-bit signed integer using the specified culture-specific\n        ///     formatting information.\n        /// </summary>\n        /// <returns>\n        ///     An 32-bit signed integer equivalent to the value of this instance.\n        /// </returns>\n        /// <param name=\"provider\">\n        ///     An <see cref=\"T:System.IFormatProvider\" /> interface implementation that supplies\n        ///     culture-specific formatting information.\n        /// </param>\n        /// <exception cref=\"InvalidCastException\">This method is not supported</exception>\n        public int ToInt32(IFormatProvider provider)\n        {\n            throw new InvalidCastException();\n        }\n\n\n        /// <summary>\n        ///     Converts the value of this instance to an equivalent 64-bit signed integer using the specified culture-specific\n        ///     formatting information.\n        /// </summary>\n        /// <returns>\n        ///     An 64-bit signed integer equivalent to the value of this instance.\n        /// </returns>\n        /// <param name=\"provider\">\n        ///     An <see cref=\"T:System.IFormatProvider\" /> interface implementation that supplies\n        ///     culture-specific formatting information.\n        /// </param>\n        /// <exception cref=\"InvalidCastException\">This method is not supported</exception>\n        public long ToInt64(IFormatProvider provider)\n        {\n            throw new InvalidCastException();\n        }\n\n\n        /// <summary>\n        ///     Converts the value of this instance to an equivalent 8-bit signed integer using the specified culture-specific\n        ///     formatting information.\n        /// </summary>\n        /// <returns>\n        ///     An 8-bit signed integer equivalent to the value of this instance.\n        /// </returns>\n        /// <param name=\"provider\">\n        ///     An <see cref=\"T:System.IFormatProvider\" /> interface implementation that supplies\n        ///     culture-specific formatting information.\n        /// </param>\n        /// <exception cref=\"InvalidCastException\">This method is not supported</exception>\n        public sbyte ToSByte(IFormatProvider provider)\n        {\n            throw new InvalidCastException();\n        }\n\n\n        /// <summary>\n        ///     Converts the value of this instance to an equivalent single-precision floating-point number using the specified\n        ///     culture-specific formatting information.\n        /// </summary>\n        /// <returns>\n        ///     A single-precision floating-point number equivalent to the value of this instance.\n        /// </returns>\n        /// <param name=\"provider\">\n        ///     An <see cref=\"T:System.IFormatProvider\" /> interface implementation that supplies\n        ///     culture-specific formatting information.\n        /// </param>\n        /// <exception cref=\"InvalidCastException\">This method is not supported</exception>\n        public float ToSingle(IFormatProvider provider)\n        {\n            throw new InvalidCastException();\n        }\n\n        /// <summary>\n        ///     Converts the value of this instance to an equivalent 16-bit unsigned integer using the specified culture-specific\n        ///     formatting information.\n        /// </summary>\n        /// <returns>\n        ///     An 16-bit unsigned integer equivalent to the value of this instance.\n        /// </returns>\n        /// <param name=\"provider\">\n        ///     An <see cref=\"T:System.IFormatProvider\" /> interface implementation that supplies\n        ///     culture-specific formatting information.\n        /// </param>\n        /// <exception cref=\"InvalidCastException\">This method is not supported</exception>\n        public ushort ToUInt16(IFormatProvider provider)\n        {\n            throw new InvalidCastException();\n        }\n\n\n        /// <summary>\n        ///     Converts the value of this instance to an equivalent 32-bit unsigned integer using the specified culture-specific\n        ///     formatting information.\n        /// </summary>\n        /// <returns>\n        ///     An 32-bit unsigned integer equivalent to the value of this instance.\n        /// </returns>\n        /// <param name=\"provider\">\n        ///     An <see cref=\"T:System.IFormatProvider\" /> interface implementation that supplies\n        ///     culture-specific formatting information.\n        /// </param>\n        /// <exception cref=\"InvalidCastException\">This method is not supported</exception>\n        public uint ToUInt32(IFormatProvider provider)\n        {\n            throw new InvalidCastException();\n        }\n\n\n        /// <summary>\n        ///     Converts the value of this instance to an equivalent 64-bit unsigned integer using the specified culture-specific\n        ///     formatting information.\n        /// </summary>\n        /// <returns>\n        ///     An 64-bit unsigned integer equivalent to the value of this instance.\n        /// </returns>\n        /// <param name=\"provider\">\n        ///     An <see cref=\"T:System.IFormatProvider\" /> interface implementation that supplies\n        ///     culture-specific formatting information.\n        /// </param>\n        /// <exception cref=\"InvalidCastException\">This method is not supported</exception>\n        public ulong ToUInt64(IFormatProvider provider)\n        {\n            throw new InvalidCastException();\n        }\n\n        /// <summary>\n        ///     Converts the value of this instance to an equivalent <see cref=\"T:System.String\" /> using the specified\n        ///     culture-specific formatting information.\n        /// </summary>\n        /// <returns>\n        ///     A <see cref=\"T:System.String\" /> instance equivalent to the value of this instance.\n        /// </returns>\n        /// <param name=\"provider\">\n        ///     An <see cref=\"T:System.IFormatProvider\" /> interface implementation that supplies\n        ///     culture-specific formatting information.\n        /// </param>\n        public string ToString(IFormatProvider provider)\n        {\n            return ToString();\n        }\n\n        /// <summary>\n        ///     Converts the value of this instance to an <see cref=\"T:System.Object\" /> of the specified\n        ///     <see cref=\"T:System.Type\" /> that has an equivalent value, using the specified culture-specific formatting\n        ///     information.\n        /// </summary>\n        /// <returns>\n        ///     An <see cref=\"T:System.Object\" /> instance of type <paramref name=\"conversionType\" /> whose value is equivalent to\n        ///     the value of this instance.\n        /// </returns>\n        /// <param name=\"conversionType\">The <see cref=\"T:System.Type\" /> to which the value of this instance is converted. </param>\n        /// <param name=\"provider\">\n        ///     An <see cref=\"T:System.IFormatProvider\" /> interface implementation that supplies\n        ///     culture-specific formatting information.\n        /// </param>\n        public object ToType(Type conversionType, IFormatProvider provider)\n        {\n            if (conversionType == typeof (Color))\n            {\n                return (Color) this;\n            }\n            throw new InvalidCastException();\n        }\n\n        /// <summary>\n        ///     Indicates whether the current object is equal to a <see cref=\"Color\" /> object.\n        /// </summary>\n        /// <returns>\n        ///     true if the current object is equal to the <paramref name=\"other\" /> parameter; otherwise, false.\n        /// </returns>\n        /// <param name=\"other\">An object to compare with this object.</param>\n        public bool Equals(Color other)\n        {\n            return this == other;\n        }\n\n        /// <summary>\n        ///     Indicates whether the current object is equal to another object of the same type.\n        /// </summary>\n        /// <returns>\n        ///     true if the current object is equal to the <paramref name=\"other\" /> parameter; otherwise, false.\n        /// </returns>\n        /// <param name=\"other\">An object to compare with this object.</param>\n        public bool Equals(Float3D other)\n        {\n            return this == other;\n        }\n\n        /// <summary>\n        ///     Determines whether the specified <see cref=\"T:System.Object\" /> is equal to the current\n        ///     <see cref=\"T:System.Object\" />.\n        /// </summary>\n        /// <returns>\n        ///     true if the specified <see cref=\"T:System.Object\" /> is equal to the current <see cref=\"T:System.Object\" />;\n        ///     otherwise, false.\n        /// </returns>\n        /// <param name=\"obj\">The <see cref=\"T:System.Object\" /> to compare with the current <see cref=\"T:System.Object\" />. </param>\n        public override bool Equals(object obj)\n        {\n            if (ReferenceEquals(null, obj)) return false;\n            if (ReferenceEquals(this, obj)) return true;\n            var conversionType = obj.GetType();\n            if (conversionType == typeof (Color))\n            {\n                return this == (Color) obj;\n            }\n            return obj.GetType() == GetType() && Equals((Float3D) obj);\n        }\n\n        /// <summary>\n        ///     Serves as a hash function for a particular type. This code will change of the values of the X and Y changes. Make\n        ///     sure to not change the values while stored in a hash dependent data structure.\n        /// </summary>\n        /// <returns>\n        ///     A hash code for the current <see cref=\"Float3D\" />.\n        /// </returns>\n        public override int GetHashCode()\n        {\n            unchecked\n            {\n                // ReSharper disable NonReadonlyMemberInGetHashCode\n                var hashCode = X.GetHashCode();\n                hashCode = (hashCode*397) ^ Y.GetHashCode();\n                hashCode = (hashCode*397) ^ Z.GetHashCode();\n                return hashCode;\n                // ReSharper restore NonReadonlyMemberInGetHashCode\n            }\n        }\n\n\n        /// <summary>\n        ///     Compares two <see cref=\"Float3D\" /> objects for equality\n        /// </summary>\n        /// <param name=\"left\">Left <see cref=\"Float3D\" /> object</param>\n        /// <param name=\"right\">Right <see cref=\"Float3D\" /> object</param>\n        /// <returns>true if both objects are equal, otherwise false</returns>\n        public static bool operator ==(Float3D left, Float3D right)\n        {\n            if (ReferenceEquals(left, null) || ReferenceEquals(right, null))\n            {\n                return ReferenceEquals(left, null) && ReferenceEquals(right, null);\n            }\n            // ReSharper disable CompareOfFloatsByEqualityOperator\n            return ReferenceEquals(left, right) ||\n                   ((double) (left.X) == right.X && (double) (left.Y) == right.Y && (double) (left.Z) == right.Z);\n            // ReSharper restore CompareOfFloatsByEqualityOperator\n        }\n\n        /// <summary>\n        ///     Compares two <see cref=\"Float3D\" /> objects for in-equality\n        /// </summary>\n        /// <param name=\"left\">Left <see cref=\"Float3D\" /> object</param>\n        /// <param name=\"right\">Right <see cref=\"Float3D\" /> object</param>\n        /// <returns>false if both objects are equal, otherwise true</returns>\n        public static bool operator !=(Float3D left, Float3D right)\n        {\n            return !(left == right);\n        }\n\n        /// <summary>\n        ///     Represents the values as an instance of the <see cref=\"Color\" /> class\n        /// </summary>\n        /// <param name=\"float3D\">\n        ///     The <see cref=\"Float3D\" /> class to convert\n        /// </param>\n        /// <returns>\n        ///     A new instance of the <see cref=\"Color\" /> class representing the values in the <see cref=\"Float3D\" /> instance\n        /// </returns>\n        public static implicit operator Color(Float3D float3D)\n        {\n            return Color.FromArgb((int) float3D.X, (int) float3D.Y, (int) float3D.Z);\n        }\n\n        /// <summary>\n        ///     Returns a string that represents the current <see cref=\"Float3D\" />.\n        /// </summary>\n        /// <returns>\n        ///     A string that represents the current <see cref=\"Float3D\" />.\n        /// </returns>\n        public override string ToString()\n        {\n            return \"(\" + X.ToString(\"0.00\") + \",\" + Y.ToString(\"0.00\") + \",\" + Z.ToString(\"0.00\") + \")\";\n        }\n\n        /// <summary>\n        ///     Creates and returns a new instance of the <see cref=\"Float3D\" /> class from a <see cref=\"Color\" /> instance\n        /// </summary>\n        /// <param name=\"color\">The object to create the <see cref=\"Float3D\" /> instance from</param>\n        /// <returns>The newly created <see cref=\"Float3D\" /> instance</returns>\n        public static Float3D FromColor(Color color)\n        {\n            return new Float3D(color.R, color.G, color.B);\n        }\n    }\n}"
  },
  {
    "path": "WinFormAnimation/readme.txt",
    "content": "\t\t\t\t\t\t          WinForm Animation Library\n\t\t    A simple library for animating controls/values in .Net\n        WinForm (.Net 3.5 and later). \n\n=========================================================================\n\nUSAGE\n\tUse the  three  'Animator',  'Animator2D' and  'Animator3D' classes  to\n  start an animation.\n\nSAMPLE ON ONE DIMENSIONAL ANIMATION OF A PROPERTY\n  new Animator(new Path(0, 100, 5000))\n    .Play(pb_progress, Animator.KnownProperties.Value);\n\nSAMPLE ON TWO DIMENSIONAL ANIMATION OF A PROPERTY\n  new Animator2D(\n      new Path2D(0, 100, -100, 200, 5000)\n      .ContinueTo(this.Location.ToFloat2D(), 2000, 3000))\n    .Play(this, Animator2D.KnownProperties.Location);\n\nSAMPLE ON THREE DIMENSIONAL ANIMATION OF A PROPERTY\n  new Animator3D(\n      new Path3D(\n                Color.Blue.ToFloat3D(), \n                Color.Red.ToFloat3D(), \n                2000, 1000, \n                AnimationFunctions.CubicEaseIn), \n      FPSLimiterKnownValues.LimitTen)\n    .Play(c_customLabel, \"CustomColor\");\n\nMORE SAMPLES:\n  Check the Project's Github page at: \n              https://github.com/falahati/WinFormAnimation"
  },
  {
    "path": "WinFormAnimation.Samples/Demo1.Designer.cs",
    "content": "﻿namespace WinFormAnimation.Samples\n{\n    partial class Demo1\n    {\n        /// <summary> \n        /// Required designer variable.\n        /// </summary>\n        private System.ComponentModel.IContainer components = null;\n\n        /// <summary> \n        /// Clean up any resources being used.\n        /// </summary>\n        /// <param name=\"disposing\">true if managed resources should be disposed; otherwise, false.</param>\n        protected override void Dispose(bool disposing)\n        {\n            if (disposing && (components != null))\n            {\n                components.Dispose();\n            }\n            base.Dispose(disposing);\n        }\n\n        /// <summary> \n        /// Required method for Designer support - do not modify \n        /// the contents of this method with the code editor.\n        /// </summary>\n        private void InitializeComponent()\n        {\n            this.lbl_res = new System.Windows.Forms.Label();\n            this.btn_play = new System.Windows.Forms.Button();\n            this.btn_stop = new System.Windows.Forms.Button();\n            this.btn_pause = new System.Windows.Forms.Button();\n            this.btn_resume = new System.Windows.Forms.Button();\n            this.SuspendLayout();\n            // \n            // lbl_res\n            // \n            this.lbl_res.AutoSize = true;\n            this.lbl_res.Location = new System.Drawing.Point(69, 10);\n            this.lbl_res.Name = \"lbl_res\";\n            this.lbl_res.Size = new System.Drawing.Size(13, 13);\n            this.lbl_res.TabIndex = 4;\n            this.lbl_res.Text = \"0\";\n            // \n            // btn_play\n            // \n            this.btn_play.Location = new System.Drawing.Point(36, 3);\n            this.btn_play.Name = \"btn_play\";\n            this.btn_play.Size = new System.Drawing.Size(27, 24);\n            this.btn_play.TabIndex = 1;\n            this.btn_play.Text = \">\";\n            this.btn_play.UseVisualStyleBackColor = true;\n            this.btn_play.Click += new System.EventHandler(this.PlayButton);\n            // \n            // btn_stop\n            // \n            this.btn_stop.Font = new System.Drawing.Font(\"Microsoft Sans Serif\", 9F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, ((byte)(178)));\n            this.btn_stop.Location = new System.Drawing.Point(3, 3);\n            this.btn_stop.Name = \"btn_stop\";\n            this.btn_stop.Size = new System.Drawing.Size(27, 24);\n            this.btn_stop.TabIndex = 0;\n            this.btn_stop.Text = \"□\";\n            this.btn_stop.UseVisualStyleBackColor = true;\n            this.btn_stop.Click += new System.EventHandler(this.StopButton);\n            // \n            // btn_pause\n            // \n            this.btn_pause.Location = new System.Drawing.Point(3, 33);\n            this.btn_pause.Name = \"btn_pause\";\n            this.btn_pause.Size = new System.Drawing.Size(27, 24);\n            this.btn_pause.TabIndex = 2;\n            this.btn_pause.Text = \"| |\";\n            this.btn_pause.UseVisualStyleBackColor = true;\n            this.btn_pause.Click += new System.EventHandler(this.PauseButton);\n            // \n            // btn_resume\n            // \n            this.btn_resume.Location = new System.Drawing.Point(36, 33);\n            this.btn_resume.Name = \"btn_resume\";\n            this.btn_resume.Size = new System.Drawing.Size(27, 24);\n            this.btn_resume.TabIndex = 3;\n            this.btn_resume.Text = \">\";\n            this.btn_resume.UseVisualStyleBackColor = true;\n            this.btn_resume.Click += new System.EventHandler(this.ResumeButton);\n            // \n            // Demo1\n            // \n            this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);\n            this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;\n            this.Controls.Add(this.lbl_res);\n            this.Controls.Add(this.btn_play);\n            this.Controls.Add(this.btn_stop);\n            this.Controls.Add(this.btn_pause);\n            this.Controls.Add(this.btn_resume);\n            this.DoubleBuffered = true;\n            this.Name = \"Demo1\";\n            this.Size = new System.Drawing.Size(130, 66);\n            this.ResumeLayout(false);\n            this.PerformLayout();\n\n        }\n\n        private System.Windows.Forms.Label lbl_res;\n        private System.Windows.Forms.Button btn_play;\n        private System.Windows.Forms.Button btn_stop;\n        private System.Windows.Forms.Button btn_pause;\n        private System.Windows.Forms.Button btn_resume;\n\n    }\n}\n"
  },
  {
    "path": "WinFormAnimation.Samples/Demo1.cs",
    "content": "﻿using System;\nusing System.Windows.Forms;\n\nnamespace WinFormAnimation.Samples\n{\n    internal partial class Demo1 : UserControl\n    {\n        private readonly Animator _animator = new Animator();\n\n        public Demo1()\n        {\n            InitializeComponent();\n            _animator.Paths = new Path(0, 100, 5000).ToArray();\n        }\n\n        private void PlayButton(object sender, EventArgs e)\n        {\n            _animator.Play(lbl_res, Animator.KnownProperties.Text);\n        }\n\n        private void StopButton(object sender, EventArgs e)\n        {\n            _animator.Stop();\n        }\n\n        private void ResumeButton(object sender, EventArgs e)\n        {\n            _animator.Resume();\n        }\n\n        private void PauseButton(object sender, EventArgs e)\n        {\n            _animator.Pause();\n        }\n    }\n}"
  },
  {
    "path": "WinFormAnimation.Samples/Demo1.resx",
    "content": "﻿<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<root>\n  <!-- \n    Microsoft ResX Schema \n    \n    Version 2.0\n    \n    The primary goals of this format is to allow a simple XML format \n    that is mostly human readable. The generation and parsing of the \n    various data types are done through the TypeConverter classes \n    associated with the data types.\n    \n    Example:\n    \n    ... ado.net/XML headers & schema ...\n    <resheader name=\"resmimetype\">text/microsoft-resx</resheader>\n    <resheader name=\"version\">2.0</resheader>\n    <resheader name=\"reader\">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>\n    <resheader name=\"writer\">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>\n    <data name=\"Name1\"><value>this is my long string</value><comment>this is a comment</comment></data>\n    <data name=\"Color1\" type=\"System.Drawing.Color, System.Drawing\">Blue</data>\n    <data name=\"Bitmap1\" mimetype=\"application/x-microsoft.net.object.binary.base64\">\n        <value>[base64 mime encoded serialized .NET Framework object]</value>\n    </data>\n    <data name=\"Icon1\" type=\"System.Drawing.Icon, System.Drawing\" mimetype=\"application/x-microsoft.net.object.bytearray.base64\">\n        <value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>\n        <comment>This is a comment</comment>\n    </data>\n                \n    There are any number of \"resheader\" rows that contain simple \n    name/value pairs.\n    \n    Each data row contains a name, and value. The row also contains a \n    type or mimetype. Type corresponds to a .NET class that support \n    text/value conversion through the TypeConverter architecture. \n    Classes that don't support this are serialized and stored with the \n    mimetype set.\n    \n    The mimetype is used for serialized objects, and tells the \n    ResXResourceReader how to depersist the object. This is currently not \n    extensible. For a given mimetype the value must be set accordingly:\n    \n    Note - application/x-microsoft.net.object.binary.base64 is the format \n    that the ResXResourceWriter will generate, however the reader can \n    read any of the formats listed below.\n    \n    mimetype: application/x-microsoft.net.object.binary.base64\n    value   : The object must be serialized with \n            : System.Runtime.Serialization.Formatters.Binary.BinaryFormatter\n            : and then encoded with base64 encoding.\n    \n    mimetype: application/x-microsoft.net.object.soap.base64\n    value   : The object must be serialized with \n            : System.Runtime.Serialization.Formatters.Soap.SoapFormatter\n            : and then encoded with base64 encoding.\n\n    mimetype: application/x-microsoft.net.object.bytearray.base64\n    value   : The object must be serialized into a byte array \n            : using a System.ComponentModel.TypeConverter\n            : and then encoded with base64 encoding.\n    -->\n  <xsd:schema id=\"root\" xmlns=\"\" xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\" xmlns:msdata=\"urn:schemas-microsoft-com:xml-msdata\">\n    <xsd:import namespace=\"http://www.w3.org/XML/1998/namespace\" />\n    <xsd:element name=\"root\" msdata:IsDataSet=\"true\">\n      <xsd:complexType>\n        <xsd:choice maxOccurs=\"unbounded\">\n          <xsd:element name=\"metadata\">\n            <xsd:complexType>\n              <xsd:sequence>\n                <xsd:element name=\"value\" type=\"xsd:string\" minOccurs=\"0\" />\n              </xsd:sequence>\n              <xsd:attribute name=\"name\" use=\"required\" type=\"xsd:string\" />\n              <xsd:attribute name=\"type\" type=\"xsd:string\" />\n              <xsd:attribute name=\"mimetype\" type=\"xsd:string\" />\n              <xsd:attribute ref=\"xml:space\" />\n            </xsd:complexType>\n          </xsd:element>\n          <xsd:element name=\"assembly\">\n            <xsd:complexType>\n              <xsd:attribute name=\"alias\" type=\"xsd:string\" />\n              <xsd:attribute name=\"name\" type=\"xsd:string\" />\n            </xsd:complexType>\n          </xsd:element>\n          <xsd:element name=\"data\">\n            <xsd:complexType>\n              <xsd:sequence>\n                <xsd:element name=\"value\" type=\"xsd:string\" minOccurs=\"0\" msdata:Ordinal=\"1\" />\n                <xsd:element name=\"comment\" type=\"xsd:string\" minOccurs=\"0\" msdata:Ordinal=\"2\" />\n              </xsd:sequence>\n              <xsd:attribute name=\"name\" type=\"xsd:string\" use=\"required\" msdata:Ordinal=\"1\" />\n              <xsd:attribute name=\"type\" type=\"xsd:string\" msdata:Ordinal=\"3\" />\n              <xsd:attribute name=\"mimetype\" type=\"xsd:string\" msdata:Ordinal=\"4\" />\n              <xsd:attribute ref=\"xml:space\" />\n            </xsd:complexType>\n          </xsd:element>\n          <xsd:element name=\"resheader\">\n            <xsd:complexType>\n              <xsd:sequence>\n                <xsd:element name=\"value\" type=\"xsd:string\" minOccurs=\"0\" msdata:Ordinal=\"1\" />\n              </xsd:sequence>\n              <xsd:attribute name=\"name\" type=\"xsd:string\" use=\"required\" />\n            </xsd:complexType>\n          </xsd:element>\n        </xsd:choice>\n      </xsd:complexType>\n    </xsd:element>\n  </xsd:schema>\n  <resheader name=\"resmimetype\">\n    <value>text/microsoft-resx</value>\n  </resheader>\n  <resheader name=\"version\">\n    <value>2.0</value>\n  </resheader>\n  <resheader name=\"reader\">\n    <value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>\n  </resheader>\n  <resheader name=\"writer\">\n    <value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>\n  </resheader>\n</root>"
  },
  {
    "path": "WinFormAnimation.Samples/Demo2.Designer.cs",
    "content": "﻿namespace WinFormAnimation.Samples\n{\n    partial class Demo2\n    {\n        /// <summary> \n        /// Required designer variable.\n        /// </summary>\n        private System.ComponentModel.IContainer components = null;\n\n        /// <summary> \n        /// Clean up any resources being used.\n        /// </summary>\n        /// <param name=\"disposing\">true if managed resources should be disposed; otherwise, false.</param>\n        protected override void Dispose(bool disposing)\n        {\n            if (disposing && (components != null))\n            {\n                components.Dispose();\n            }\n            base.Dispose(disposing);\n        }\n\n        /// <summary> \n        /// Required method for Designer support - do not modify \n        /// the contents of this method with the code editor.\n        /// </summary>\n        private void InitializeComponent()\n        {\n            this.btn_play = new System.Windows.Forms.Button();\n            this.btn_stop = new System.Windows.Forms.Button();\n            this.btn_pause = new System.Windows.Forms.Button();\n            this.btn_resume = new System.Windows.Forms.Button();\n            this.pb_image = new System.Windows.Forms.PictureBox();\n            this.cb_repeat = new System.Windows.Forms.CheckBox();\n            this.cb_reverse = new System.Windows.Forms.CheckBox();\n            ((System.ComponentModel.ISupportInitialize)(this.pb_image)).BeginInit();\n            this.SuspendLayout();\n            // \n            // btn_play\n            // \n            this.btn_play.Location = new System.Drawing.Point(36, 3);\n            this.btn_play.Name = \"btn_play\";\n            this.btn_play.Size = new System.Drawing.Size(27, 24);\n            this.btn_play.TabIndex = 1;\n            this.btn_play.Text = \">\";\n            this.btn_play.UseVisualStyleBackColor = true;\n            this.btn_play.Click += new System.EventHandler(this.PlayButton);\n            // \n            // btn_stop\n            // \n            this.btn_stop.Font = new System.Drawing.Font(\"Microsoft Sans Serif\", 9F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, ((byte)(178)));\n            this.btn_stop.Location = new System.Drawing.Point(3, 3);\n            this.btn_stop.Name = \"btn_stop\";\n            this.btn_stop.Size = new System.Drawing.Size(27, 24);\n            this.btn_stop.TabIndex = 0;\n            this.btn_stop.Text = \"□\";\n            this.btn_stop.UseVisualStyleBackColor = true;\n            this.btn_stop.Click += new System.EventHandler(this.StopButton);\n            // \n            // btn_pause\n            // \n            this.btn_pause.Location = new System.Drawing.Point(3, 33);\n            this.btn_pause.Name = \"btn_pause\";\n            this.btn_pause.Size = new System.Drawing.Size(27, 24);\n            this.btn_pause.TabIndex = 2;\n            this.btn_pause.Text = \"| |\";\n            this.btn_pause.UseVisualStyleBackColor = true;\n            this.btn_pause.Click += new System.EventHandler(this.PauseButton);\n            // \n            // btn_resume\n            // \n            this.btn_resume.Location = new System.Drawing.Point(36, 33);\n            this.btn_resume.Name = \"btn_resume\";\n            this.btn_resume.Size = new System.Drawing.Size(27, 24);\n            this.btn_resume.TabIndex = 3;\n            this.btn_resume.Text = \">\";\n            this.btn_resume.UseVisualStyleBackColor = true;\n            this.btn_resume.Click += new System.EventHandler(this.ResumeButton);\n            // \n            // pb_image\n            // \n            this.pb_image.Image = global::WinFormAnimation.Samples.Properties.Resources.star_32;\n            this.pb_image.Location = new System.Drawing.Point(69, 3);\n            this.pb_image.Name = \"pb_image\";\n            this.pb_image.Size = new System.Drawing.Size(32, 32);\n            this.pb_image.SizeMode = System.Windows.Forms.PictureBoxSizeMode.AutoSize;\n            this.pb_image.TabIndex = 5;\n            this.pb_image.TabStop = false;\n            // \n            // cb_repeat\n            // \n            this.cb_repeat.AutoSize = true;\n            this.cb_repeat.Location = new System.Drawing.Point(3, 63);\n            this.cb_repeat.Name = \"cb_repeat\";\n            this.cb_repeat.Size = new System.Drawing.Size(61, 17);\n            this.cb_repeat.TabIndex = 6;\n            this.cb_repeat.Text = \"Repeat\";\n            this.cb_repeat.UseVisualStyleBackColor = true;\n            this.cb_repeat.CheckedChanged += new System.EventHandler(this.RepeatChecked);\n            // \n            // cb_reverse\n            // \n            this.cb_reverse.AutoSize = true;\n            this.cb_reverse.Enabled = false;\n            this.cb_reverse.Location = new System.Drawing.Point(3, 86);\n            this.cb_reverse.Name = \"cb_reverse\";\n            this.cb_reverse.Size = new System.Drawing.Size(66, 17);\n            this.cb_reverse.TabIndex = 7;\n            this.cb_reverse.Text = \"Reverse\";\n            this.cb_reverse.UseVisualStyleBackColor = true;\n            this.cb_reverse.CheckedChanged += new System.EventHandler(this.ReverseChecked);\n            // \n            // Demo2\n            // \n            this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);\n            this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;\n            this.Controls.Add(this.cb_reverse);\n            this.Controls.Add(this.cb_repeat);\n            this.Controls.Add(this.pb_image);\n            this.Controls.Add(this.btn_play);\n            this.Controls.Add(this.btn_stop);\n            this.Controls.Add(this.btn_pause);\n            this.Controls.Add(this.btn_resume);\n            this.DoubleBuffered = true;\n            this.Name = \"Demo2\";\n            this.Size = new System.Drawing.Size(362, 159);\n            ((System.ComponentModel.ISupportInitialize)(this.pb_image)).EndInit();\n            this.ResumeLayout(false);\n            this.PerformLayout();\n\n        }\n\n        private System.Windows.Forms.Button btn_play;\n        private System.Windows.Forms.Button btn_stop;\n        private System.Windows.Forms.Button btn_pause;\n        private System.Windows.Forms.Button btn_resume;\n        private System.Windows.Forms.PictureBox pb_image;\n        private System.Windows.Forms.CheckBox cb_repeat;\n        private System.Windows.Forms.CheckBox cb_reverse;\n    }\n}\n"
  },
  {
    "path": "WinFormAnimation.Samples/Demo2.cs",
    "content": "﻿using System;\nusing System.Windows.Forms;\n\nnamespace WinFormAnimation.Samples\n{\n    internal partial class Demo2 : UserControl\n    {\n        private readonly Animator2D _animator = new Animator2D();\n\n        public Demo2()\n        {\n            InitializeComponent();\n            _animator.Paths = new Path2D(\n                new Path(70, 320, 2000, AnimationFunctions.CubicEaseOut),\n                new Path(5, 100, 2000, AnimationFunctions.CubicEaseIn))\n                .ContinueTo(new Path2D(\n                    new Path(320, 70, 2000, 300, AnimationFunctions.ExponentialEaseInOut),\n                    new Path(100, 5, 1700, 600, AnimationFunctions.Linear)));\n        }\n\n        private void PlayButton(object sender, EventArgs e)\n        {\n            _animator.Play(pb_image, Animator2D.KnownProperties.Location);\n        }\n\n        private void StopButton(object sender, EventArgs e)\n        {\n            _animator.Stop();\n        }\n\n        private void ResumeButton(object sender, EventArgs e)\n        {\n            _animator.Resume();\n        }\n\n        private void PauseButton(object sender, EventArgs e)\n        {\n            _animator.Pause();\n        }\n\n        private void RepeatChecked(object sender, EventArgs e)\n        {\n            _animator.Repeat = cb_repeat.Checked;\n            cb_reverse.Enabled = cb_repeat.Checked;\n        }\n\n        private void ReverseChecked(object sender, EventArgs e)\n        {\n            _animator.ReverseRepeat = cb_reverse.Checked;\n        }\n    }\n}"
  },
  {
    "path": "WinFormAnimation.Samples/Demo2.resx",
    "content": "﻿<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<root>\n  <!-- \n    Microsoft ResX Schema \n    \n    Version 2.0\n    \n    The primary goals of this format is to allow a simple XML format \n    that is mostly human readable. The generation and parsing of the \n    various data types are done through the TypeConverter classes \n    associated with the data types.\n    \n    Example:\n    \n    ... ado.net/XML headers & schema ...\n    <resheader name=\"resmimetype\">text/microsoft-resx</resheader>\n    <resheader name=\"version\">2.0</resheader>\n    <resheader name=\"reader\">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>\n    <resheader name=\"writer\">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>\n    <data name=\"Name1\"><value>this is my long string</value><comment>this is a comment</comment></data>\n    <data name=\"Color1\" type=\"System.Drawing.Color, System.Drawing\">Blue</data>\n    <data name=\"Bitmap1\" mimetype=\"application/x-microsoft.net.object.binary.base64\">\n        <value>[base64 mime encoded serialized .NET Framework object]</value>\n    </data>\n    <data name=\"Icon1\" type=\"System.Drawing.Icon, System.Drawing\" mimetype=\"application/x-microsoft.net.object.bytearray.base64\">\n        <value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>\n        <comment>This is a comment</comment>\n    </data>\n                \n    There are any number of \"resheader\" rows that contain simple \n    name/value pairs.\n    \n    Each data row contains a name, and value. The row also contains a \n    type or mimetype. Type corresponds to a .NET class that support \n    text/value conversion through the TypeConverter architecture. \n    Classes that don't support this are serialized and stored with the \n    mimetype set.\n    \n    The mimetype is used for serialized objects, and tells the \n    ResXResourceReader how to depersist the object. This is currently not \n    extensible. For a given mimetype the value must be set accordingly:\n    \n    Note - application/x-microsoft.net.object.binary.base64 is the format \n    that the ResXResourceWriter will generate, however the reader can \n    read any of the formats listed below.\n    \n    mimetype: application/x-microsoft.net.object.binary.base64\n    value   : The object must be serialized with \n            : System.Runtime.Serialization.Formatters.Binary.BinaryFormatter\n            : and then encoded with base64 encoding.\n    \n    mimetype: application/x-microsoft.net.object.soap.base64\n    value   : The object must be serialized with \n            : System.Runtime.Serialization.Formatters.Soap.SoapFormatter\n            : and then encoded with base64 encoding.\n\n    mimetype: application/x-microsoft.net.object.bytearray.base64\n    value   : The object must be serialized into a byte array \n            : using a System.ComponentModel.TypeConverter\n            : and then encoded with base64 encoding.\n    -->\n  <xsd:schema id=\"root\" xmlns=\"\" xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\" xmlns:msdata=\"urn:schemas-microsoft-com:xml-msdata\">\n    <xsd:import namespace=\"http://www.w3.org/XML/1998/namespace\" />\n    <xsd:element name=\"root\" msdata:IsDataSet=\"true\">\n      <xsd:complexType>\n        <xsd:choice maxOccurs=\"unbounded\">\n          <xsd:element name=\"metadata\">\n            <xsd:complexType>\n              <xsd:sequence>\n                <xsd:element name=\"value\" type=\"xsd:string\" minOccurs=\"0\" />\n              </xsd:sequence>\n              <xsd:attribute name=\"name\" use=\"required\" type=\"xsd:string\" />\n              <xsd:attribute name=\"type\" type=\"xsd:string\" />\n              <xsd:attribute name=\"mimetype\" type=\"xsd:string\" />\n              <xsd:attribute ref=\"xml:space\" />\n            </xsd:complexType>\n          </xsd:element>\n          <xsd:element name=\"assembly\">\n            <xsd:complexType>\n              <xsd:attribute name=\"alias\" type=\"xsd:string\" />\n              <xsd:attribute name=\"name\" type=\"xsd:string\" />\n            </xsd:complexType>\n          </xsd:element>\n          <xsd:element name=\"data\">\n            <xsd:complexType>\n              <xsd:sequence>\n                <xsd:element name=\"value\" type=\"xsd:string\" minOccurs=\"0\" msdata:Ordinal=\"1\" />\n                <xsd:element name=\"comment\" type=\"xsd:string\" minOccurs=\"0\" msdata:Ordinal=\"2\" />\n              </xsd:sequence>\n              <xsd:attribute name=\"name\" type=\"xsd:string\" use=\"required\" msdata:Ordinal=\"1\" />\n              <xsd:attribute name=\"type\" type=\"xsd:string\" msdata:Ordinal=\"3\" />\n              <xsd:attribute name=\"mimetype\" type=\"xsd:string\" msdata:Ordinal=\"4\" />\n              <xsd:attribute ref=\"xml:space\" />\n            </xsd:complexType>\n          </xsd:element>\n          <xsd:element name=\"resheader\">\n            <xsd:complexType>\n              <xsd:sequence>\n                <xsd:element name=\"value\" type=\"xsd:string\" minOccurs=\"0\" msdata:Ordinal=\"1\" />\n              </xsd:sequence>\n              <xsd:attribute name=\"name\" type=\"xsd:string\" use=\"required\" />\n            </xsd:complexType>\n          </xsd:element>\n        </xsd:choice>\n      </xsd:complexType>\n    </xsd:element>\n  </xsd:schema>\n  <resheader name=\"resmimetype\">\n    <value>text/microsoft-resx</value>\n  </resheader>\n  <resheader name=\"version\">\n    <value>2.0</value>\n  </resheader>\n  <resheader name=\"reader\">\n    <value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>\n  </resheader>\n  <resheader name=\"writer\">\n    <value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>\n  </resheader>\n</root>"
  },
  {
    "path": "WinFormAnimation.Samples/Demo3.Designer.cs",
    "content": "﻿namespace WinFormAnimation.Samples\n{\n    partial class Demo3\n    {\n        /// <summary> \n        /// Required designer variable.\n        /// </summary>\n        private System.ComponentModel.IContainer components = null;\n\n        /// <summary> \n        /// Clean up any resources being used.\n        /// </summary>\n        /// <param name=\"disposing\">true if managed resources should be disposed; otherwise, false.</param>\n        protected override void Dispose(bool disposing)\n        {\n            if (disposing && (components != null))\n            {\n                components.Dispose();\n            }\n            base.Dispose(disposing);\n        }\n\n        /// <summary> \n        /// Required method for Designer support - do not modify \n        /// the contents of this method with the code editor.\n        /// </summary>\n        private void InitializeComponent()\n        {\n            this.btn_play = new System.Windows.Forms.Button();\n            this.btn_stop = new System.Windows.Forms.Button();\n            this.btn_pause = new System.Windows.Forms.Button();\n            this.btn_resume = new System.Windows.Forms.Button();\n            this.p_color = new System.Windows.Forms.Panel();\n            this.SuspendLayout();\n            // \n            // btn_play\n            // \n            this.btn_play.Location = new System.Drawing.Point(36, 3);\n            this.btn_play.Name = \"btn_play\";\n            this.btn_play.Size = new System.Drawing.Size(27, 24);\n            this.btn_play.TabIndex = 5;\n            this.btn_play.Text = \">\";\n            this.btn_play.UseVisualStyleBackColor = true;\n            this.btn_play.Click += new System.EventHandler(this.PlayButton);\n            // \n            // btn_stop\n            // \n            this.btn_stop.Font = new System.Drawing.Font(\"Microsoft Sans Serif\", 9F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, ((byte)(178)));\n            this.btn_stop.Location = new System.Drawing.Point(3, 3);\n            this.btn_stop.Name = \"btn_stop\";\n            this.btn_stop.Size = new System.Drawing.Size(27, 24);\n            this.btn_stop.TabIndex = 4;\n            this.btn_stop.Text = \"□\";\n            this.btn_stop.UseVisualStyleBackColor = true;\n            this.btn_stop.Click += new System.EventHandler(this.StopButton);\n            // \n            // btn_pause\n            // \n            this.btn_pause.Location = new System.Drawing.Point(3, 33);\n            this.btn_pause.Name = \"btn_pause\";\n            this.btn_pause.Size = new System.Drawing.Size(27, 24);\n            this.btn_pause.TabIndex = 6;\n            this.btn_pause.Text = \"| |\";\n            this.btn_pause.UseVisualStyleBackColor = true;\n            this.btn_pause.Click += new System.EventHandler(this.PauseButton);\n            // \n            // btn_resume\n            // \n            this.btn_resume.Location = new System.Drawing.Point(36, 33);\n            this.btn_resume.Name = \"btn_resume\";\n            this.btn_resume.Size = new System.Drawing.Size(27, 24);\n            this.btn_resume.TabIndex = 7;\n            this.btn_resume.Text = \">\";\n            this.btn_resume.UseVisualStyleBackColor = true;\n            this.btn_resume.Click += new System.EventHandler(this.ResumeButton);\n            // \n            // p_color\n            // \n            this.p_color.BackColor = System.Drawing.Color.Aqua;\n            this.p_color.BorderStyle = System.Windows.Forms.BorderStyle.FixedSingle;\n            this.p_color.Location = new System.Drawing.Point(70, 4);\n            this.p_color.Name = \"p_color\";\n            this.p_color.Size = new System.Drawing.Size(168, 53);\n            this.p_color.TabIndex = 8;\n            // \n            // Demo3\n            // \n            this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);\n            this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;\n            this.Controls.Add(this.p_color);\n            this.Controls.Add(this.btn_play);\n            this.Controls.Add(this.btn_stop);\n            this.Controls.Add(this.btn_pause);\n            this.Controls.Add(this.btn_resume);\n            this.DoubleBuffered = true;\n            this.Name = \"Demo3\";\n            this.Size = new System.Drawing.Size(241, 63);\n            this.ResumeLayout(false);\n\n        }\n\n        private System.Windows.Forms.Button btn_play;\n        private System.Windows.Forms.Button btn_stop;\n        private System.Windows.Forms.Button btn_pause;\n        private System.Windows.Forms.Button btn_resume;\n        private System.Windows.Forms.Panel p_color;\n    }\n}\n"
  },
  {
    "path": "WinFormAnimation.Samples/Demo3.cs",
    "content": "﻿using System;\nusing System.Drawing;\nusing System.Linq;\nusing System.Windows.Forms;\n\nnamespace WinFormAnimation.Samples\n{\n    internal partial class Demo3 : UserControl\n    {\n        private readonly Animator3D _animator = new Animator3D();\n\n        public Demo3()\n        {\n            InitializeComponent();\n        }\n\n        private void PlayButton(object sender, EventArgs e)\n        {\n            _animator.Stop();\n            _animator.Paths =\n                new Path3D(Color.Aqua.ToFloat3D(), Color.FromArgb(255, 128, 0).ToFloat3D(), 3000).ToArray();\n            _animator.Play(p_color, Animator3D.KnownProperties.BackColor, new SafeInvoker(() =>\n            {\n                _animator.Paths = _animator.Paths.Last().Reverse().ToArray();\n                _animator.Play(p_color, Animator3D.KnownProperties.BackColor);\n            }));\n        }\n\n        private void StopButton(object sender, EventArgs e)\n        {\n            _animator.Stop();\n        }\n\n        private void ResumeButton(object sender, EventArgs e)\n        {\n            _animator.Resume();\n        }\n\n        private void PauseButton(object sender, EventArgs e)\n        {\n            _animator.Pause();\n        }\n    }\n}"
  },
  {
    "path": "WinFormAnimation.Samples/Demo3.resx",
    "content": "﻿<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<root>\n  <!-- \n    Microsoft ResX Schema \n    \n    Version 2.0\n    \n    The primary goals of this format is to allow a simple XML format \n    that is mostly human readable. The generation and parsing of the \n    various data types are done through the TypeConverter classes \n    associated with the data types.\n    \n    Example:\n    \n    ... ado.net/XML headers & schema ...\n    <resheader name=\"resmimetype\">text/microsoft-resx</resheader>\n    <resheader name=\"version\">2.0</resheader>\n    <resheader name=\"reader\">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>\n    <resheader name=\"writer\">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>\n    <data name=\"Name1\"><value>this is my long string</value><comment>this is a comment</comment></data>\n    <data name=\"Color1\" type=\"System.Drawing.Color, System.Drawing\">Blue</data>\n    <data name=\"Bitmap1\" mimetype=\"application/x-microsoft.net.object.binary.base64\">\n        <value>[base64 mime encoded serialized .NET Framework object]</value>\n    </data>\n    <data name=\"Icon1\" type=\"System.Drawing.Icon, System.Drawing\" mimetype=\"application/x-microsoft.net.object.bytearray.base64\">\n        <value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>\n        <comment>This is a comment</comment>\n    </data>\n                \n    There are any number of \"resheader\" rows that contain simple \n    name/value pairs.\n    \n    Each data row contains a name, and value. The row also contains a \n    type or mimetype. Type corresponds to a .NET class that support \n    text/value conversion through the TypeConverter architecture. \n    Classes that don't support this are serialized and stored with the \n    mimetype set.\n    \n    The mimetype is used for serialized objects, and tells the \n    ResXResourceReader how to depersist the object. This is currently not \n    extensible. For a given mimetype the value must be set accordingly:\n    \n    Note - application/x-microsoft.net.object.binary.base64 is the format \n    that the ResXResourceWriter will generate, however the reader can \n    read any of the formats listed below.\n    \n    mimetype: application/x-microsoft.net.object.binary.base64\n    value   : The object must be serialized with \n            : System.Runtime.Serialization.Formatters.Binary.BinaryFormatter\n            : and then encoded with base64 encoding.\n    \n    mimetype: application/x-microsoft.net.object.soap.base64\n    value   : The object must be serialized with \n            : System.Runtime.Serialization.Formatters.Soap.SoapFormatter\n            : and then encoded with base64 encoding.\n\n    mimetype: application/x-microsoft.net.object.bytearray.base64\n    value   : The object must be serialized into a byte array \n            : using a System.ComponentModel.TypeConverter\n            : and then encoded with base64 encoding.\n    -->\n  <xsd:schema id=\"root\" xmlns=\"\" xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\" xmlns:msdata=\"urn:schemas-microsoft-com:xml-msdata\">\n    <xsd:import namespace=\"http://www.w3.org/XML/1998/namespace\" />\n    <xsd:element name=\"root\" msdata:IsDataSet=\"true\">\n      <xsd:complexType>\n        <xsd:choice maxOccurs=\"unbounded\">\n          <xsd:element name=\"metadata\">\n            <xsd:complexType>\n              <xsd:sequence>\n                <xsd:element name=\"value\" type=\"xsd:string\" minOccurs=\"0\" />\n              </xsd:sequence>\n              <xsd:attribute name=\"name\" use=\"required\" type=\"xsd:string\" />\n              <xsd:attribute name=\"type\" type=\"xsd:string\" />\n              <xsd:attribute name=\"mimetype\" type=\"xsd:string\" />\n              <xsd:attribute ref=\"xml:space\" />\n            </xsd:complexType>\n          </xsd:element>\n          <xsd:element name=\"assembly\">\n            <xsd:complexType>\n              <xsd:attribute name=\"alias\" type=\"xsd:string\" />\n              <xsd:attribute name=\"name\" type=\"xsd:string\" />\n            </xsd:complexType>\n          </xsd:element>\n          <xsd:element name=\"data\">\n            <xsd:complexType>\n              <xsd:sequence>\n                <xsd:element name=\"value\" type=\"xsd:string\" minOccurs=\"0\" msdata:Ordinal=\"1\" />\n                <xsd:element name=\"comment\" type=\"xsd:string\" minOccurs=\"0\" msdata:Ordinal=\"2\" />\n              </xsd:sequence>\n              <xsd:attribute name=\"name\" type=\"xsd:string\" use=\"required\" msdata:Ordinal=\"1\" />\n              <xsd:attribute name=\"type\" type=\"xsd:string\" msdata:Ordinal=\"3\" />\n              <xsd:attribute name=\"mimetype\" type=\"xsd:string\" msdata:Ordinal=\"4\" />\n              <xsd:attribute ref=\"xml:space\" />\n            </xsd:complexType>\n          </xsd:element>\n          <xsd:element name=\"resheader\">\n            <xsd:complexType>\n              <xsd:sequence>\n                <xsd:element name=\"value\" type=\"xsd:string\" minOccurs=\"0\" msdata:Ordinal=\"1\" />\n              </xsd:sequence>\n              <xsd:attribute name=\"name\" type=\"xsd:string\" use=\"required\" />\n            </xsd:complexType>\n          </xsd:element>\n        </xsd:choice>\n      </xsd:complexType>\n    </xsd:element>\n  </xsd:schema>\n  <resheader name=\"resmimetype\">\n    <value>text/microsoft-resx</value>\n  </resheader>\n  <resheader name=\"version\">\n    <value>2.0</value>\n  </resheader>\n  <resheader name=\"reader\">\n    <value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>\n  </resheader>\n  <resheader name=\"writer\">\n    <value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>\n  </resheader>\n</root>"
  },
  {
    "path": "WinFormAnimation.Samples/Demo4.Designer.cs",
    "content": "﻿namespace WinFormAnimation.Samples\n{\n    partial class Demo4\n    {\n        /// <summary> \n        /// Required designer variable.\n        /// </summary>\n        private System.ComponentModel.IContainer components = null;\n\n        /// <summary> \n        /// Clean up any resources being used.\n        /// </summary>\n        /// <param name=\"disposing\">true if managed resources should be disposed; otherwise, false.</param>\n        protected override void Dispose(bool disposing)\n        {\n            if (disposing && (components != null))\n            {\n                components.Dispose();\n            }\n            base.Dispose(disposing);\n        }\n\n        /// <summary> \n        /// Required method for Designer support - do not modify \n        /// the contents of this method with the code editor.\n        /// </summary>\n        private void InitializeComponent()\n        {\n            this.components = new System.ComponentModel.Container();\n            this.nud_fps = new System.Windows.Forms.NumericUpDown();\n            this.label1 = new System.Windows.Forms.Label();\n            this.label2 = new System.Windows.Forms.Label();\n            this.nud_num = new System.Windows.Forms.NumericUpDown();\n            this.label3 = new System.Windows.Forms.Label();\n            this.nud_dur = new System.Windows.Forms.NumericUpDown();\n            this.label4 = new System.Windows.Forms.Label();\n            this.lbl_fps = new System.Windows.Forms.Label();\n            this.lbl_cpu = new System.Windows.Forms.Label();\n            this.label7 = new System.Windows.Forms.Label();\n            this.btn_run = new System.Windows.Forms.Button();\n            this.lbl_time = new System.Windows.Forms.Label();\n            this.label6 = new System.Windows.Forms.Label();\n            this.cpu_timer = new System.Windows.Forms.Timer(this.components);\n            ((System.ComponentModel.ISupportInitialize)(this.nud_fps)).BeginInit();\n            ((System.ComponentModel.ISupportInitialize)(this.nud_num)).BeginInit();\n            ((System.ComponentModel.ISupportInitialize)(this.nud_dur)).BeginInit();\n            this.SuspendLayout();\n            // \n            // nud_fps\n            // \n            this.nud_fps.Location = new System.Drawing.Point(69, 3);\n            this.nud_fps.Maximum = new decimal(new int[] {\n            1000,\n            0,\n            0,\n            0});\n            this.nud_fps.Minimum = new decimal(new int[] {\n            1,\n            0,\n            0,\n            0});\n            this.nud_fps.Name = \"nud_fps\";\n            this.nud_fps.Size = new System.Drawing.Size(120, 20);\n            this.nud_fps.TabIndex = 1;\n            this.nud_fps.Value = new decimal(new int[] {\n            30,\n            0,\n            0,\n            0});\n            // \n            // label1\n            // \n            this.label1.AutoSize = true;\n            this.label1.Location = new System.Drawing.Point(3, 5);\n            this.label1.Name = \"label1\";\n            this.label1.Size = new System.Drawing.Size(60, 13);\n            this.label1.TabIndex = 0;\n            this.label1.Text = \"FPS Limiter\";\n            // \n            // label2\n            // \n            this.label2.AutoSize = true;\n            this.label2.Location = new System.Drawing.Point(3, 31);\n            this.label2.Name = \"label2\";\n            this.label2.Size = new System.Drawing.Size(58, 13);\n            this.label2.TabIndex = 2;\n            this.label2.Text = \"Animations\";\n            // \n            // nud_num\n            // \n            this.nud_num.Location = new System.Drawing.Point(69, 29);\n            this.nud_num.Maximum = new decimal(new int[] {\n            5000,\n            0,\n            0,\n            0});\n            this.nud_num.Minimum = new decimal(new int[] {\n            1,\n            0,\n            0,\n            0});\n            this.nud_num.Name = \"nud_num\";\n            this.nud_num.Size = new System.Drawing.Size(120, 20);\n            this.nud_num.TabIndex = 3;\n            this.nud_num.Value = new decimal(new int[] {\n            100,\n            0,\n            0,\n            0});\n            // \n            // label3\n            // \n            this.label3.AutoSize = true;\n            this.label3.Location = new System.Drawing.Point(3, 57);\n            this.label3.Name = \"label3\";\n            this.label3.Size = new System.Drawing.Size(47, 13);\n            this.label3.TabIndex = 4;\n            this.label3.Text = \"Duration\";\n            // \n            // nud_dur\n            // \n            this.nud_dur.Location = new System.Drawing.Point(69, 55);\n            this.nud_dur.Maximum = new decimal(new int[] {\n            100000,\n            0,\n            0,\n            0});\n            this.nud_dur.Minimum = new decimal(new int[] {\n            1000,\n            0,\n            0,\n            0});\n            this.nud_dur.Name = \"nud_dur\";\n            this.nud_dur.Size = new System.Drawing.Size(120, 20);\n            this.nud_dur.TabIndex = 5;\n            this.nud_dur.Value = new decimal(new int[] {\n            3000,\n            0,\n            0,\n            0});\n            // \n            // label4\n            // \n            this.label4.AutoSize = true;\n            this.label4.Location = new System.Drawing.Point(279, 5);\n            this.label4.Name = \"label4\";\n            this.label4.Size = new System.Drawing.Size(73, 13);\n            this.label4.TabIndex = 6;\n            this.label4.Text = \"Average FPS:\";\n            // \n            // lbl_fps\n            // \n            this.lbl_fps.AutoSize = true;\n            this.lbl_fps.Location = new System.Drawing.Point(358, 5);\n            this.lbl_fps.Name = \"lbl_fps\";\n            this.lbl_fps.Size = new System.Drawing.Size(10, 13);\n            this.lbl_fps.TabIndex = 7;\n            this.lbl_fps.Text = \"-\";\n            // \n            // lbl_cpu\n            // \n            this.lbl_cpu.AutoSize = true;\n            this.lbl_cpu.Location = new System.Drawing.Point(358, 31);\n            this.lbl_cpu.Name = \"lbl_cpu\";\n            this.lbl_cpu.Size = new System.Drawing.Size(10, 13);\n            this.lbl_cpu.TabIndex = 9;\n            this.lbl_cpu.Text = \"-\";\n            // \n            // label7\n            // \n            this.label7.AutoSize = true;\n            this.label7.Location = new System.Drawing.Point(279, 31);\n            this.label7.Name = \"label7\";\n            this.label7.Size = new System.Drawing.Size(75, 13);\n            this.label7.TabIndex = 8;\n            this.label7.Text = \"Average CPU:\";\n            // \n            // btn_run\n            // \n            this.btn_run.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right)));\n            this.btn_run.Location = new System.Drawing.Point(464, 51);\n            this.btn_run.Name = \"btn_run\";\n            this.btn_run.Size = new System.Drawing.Size(160, 24);\n            this.btn_run.TabIndex = 10;\n            this.btn_run.Text = \"RUN\";\n            this.btn_run.UseVisualStyleBackColor = true;\n            this.btn_run.Click += new System.EventHandler(this.RunButton);\n            // \n            // lbl_time\n            // \n            this.lbl_time.AutoSize = true;\n            this.lbl_time.Location = new System.Drawing.Point(358, 57);\n            this.lbl_time.Name = \"lbl_time\";\n            this.lbl_time.Size = new System.Drawing.Size(10, 13);\n            this.lbl_time.TabIndex = 12;\n            this.lbl_time.Text = \"-\";\n            // \n            // label6\n            // \n            this.label6.AutoSize = true;\n            this.label6.Location = new System.Drawing.Point(279, 57);\n            this.label6.Name = \"label6\";\n            this.label6.Size = new System.Drawing.Size(33, 13);\n            this.label6.TabIndex = 11;\n            this.label6.Text = \"Time:\";\n            // \n            // Demo4\n            // \n            this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);\n            this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;\n            this.Controls.Add(this.lbl_time);\n            this.Controls.Add(this.label6);\n            this.Controls.Add(this.btn_run);\n            this.Controls.Add(this.lbl_cpu);\n            this.Controls.Add(this.label7);\n            this.Controls.Add(this.lbl_fps);\n            this.Controls.Add(this.label4);\n            this.Controls.Add(this.label3);\n            this.Controls.Add(this.nud_dur);\n            this.Controls.Add(this.label2);\n            this.Controls.Add(this.nud_num);\n            this.Controls.Add(this.label1);\n            this.Controls.Add(this.nud_fps);\n            this.Name = \"Demo4\";\n            this.Size = new System.Drawing.Size(627, 89);\n            ((System.ComponentModel.ISupportInitialize)(this.nud_fps)).EndInit();\n            ((System.ComponentModel.ISupportInitialize)(this.nud_num)).EndInit();\n            ((System.ComponentModel.ISupportInitialize)(this.nud_dur)).EndInit();\n            this.ResumeLayout(false);\n            this.PerformLayout();\n\n        }\n\n        private System.Windows.Forms.NumericUpDown nud_fps;\n        private System.Windows.Forms.Label label1;\n        private System.Windows.Forms.Label label2;\n        private System.Windows.Forms.NumericUpDown nud_num;\n        private System.Windows.Forms.Label label3;\n        private System.Windows.Forms.NumericUpDown nud_dur;\n        private System.Windows.Forms.Label label4;\n        private System.Windows.Forms.Label lbl_fps;\n        private System.Windows.Forms.Label lbl_cpu;\n        private System.Windows.Forms.Label label7;\n        private System.Windows.Forms.Button btn_run;\n        private System.Windows.Forms.Label lbl_time;\n        private System.Windows.Forms.Label label6;\n        private System.Windows.Forms.Timer cpu_timer;\n    }\n}\n"
  },
  {
    "path": "WinFormAnimation.Samples/Demo4.cs",
    "content": "﻿using System;\nusing System.Collections.Generic;\nusing System.Diagnostics;\nusing System.Windows.Forms;\n\nnamespace WinFormAnimation.Samples\n{\n    internal partial class Demo4 : UserControl\n    {\n        private readonly List<Animator> _animators = new List<Animator>();\n        private readonly Process _currentProcess = Process.GetCurrentProcess();\n        private readonly Stopwatch _stopWatch = new Stopwatch();\n        private int _cpuUsage;\n        private int _endedAnimations;\n        private int _frameHits;\n\n        public Demo4()\n        {\n            InitializeComponent();\n        }\n\n        private void RunButton(object sender, EventArgs e)\n        {\n            Enabled = false;\n            _animators.Clear();\n            _frameHits = 0;\n            _endedAnimations = 0;\n            var rnd = new Random();\n            for (var i = 0; i < nud_num.Value; i++)\n            {\n                _animators.Add(new Animator((FPSLimiterKnownValues) nud_fps.Value)\n                {\n                    Paths = new[] {new Path(rnd.Next(1000), rnd.Next(1000), (ulong) nud_dur.Value)}\n                });\n            }\n            _cpuUsage = (int) _currentProcess.TotalProcessorTime.TotalMilliseconds;\n            _stopWatch.Reset();\n            _stopWatch.Start();\n            _animators.ForEach(a => { a.Play(new SafeInvoker<float>(Hit, this), new SafeInvoker(End, this)); });\n        }\n\n        private void Hit(float value)\n        {\n            _frameHits += 1;\n        }\n\n        private void End()\n        {\n            _endedAnimations += 1;\n            if (_endedAnimations == nud_num.Value)\n            {\n                _stopWatch.Stop();\n                lbl_fps.Text =\n                    $\"{Round((decimal) (_frameHits/((_stopWatch.ElapsedMilliseconds/1000f)*(double) nud_num.Value)))} fps\";\n                lbl_time.Text = $\"{_stopWatch.ElapsedMilliseconds} ms\";\n                lbl_cpu.Text =\n                    $\"{Round((decimal) ((_currentProcess.TotalProcessorTime.TotalMilliseconds - _cpuUsage)/_stopWatch.ElapsedMilliseconds)*(decimal) (100f/Environment.ProcessorCount))} % - {Environment.ProcessorCount} Cores\";\n                Enabled = true;\n            }\n        }\n\n\n        private float Round(decimal n)\n        {\n            return (float) Math.Round(n, 2);\n        }\n    }\n}"
  },
  {
    "path": "WinFormAnimation.Samples/Demo4.resx",
    "content": "﻿<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<root>\n  <!-- \n    Microsoft ResX Schema \n    \n    Version 2.0\n    \n    The primary goals of this format is to allow a simple XML format \n    that is mostly human readable. The generation and parsing of the \n    various data types are done through the TypeConverter classes \n    associated with the data types.\n    \n    Example:\n    \n    ... ado.net/XML headers & schema ...\n    <resheader name=\"resmimetype\">text/microsoft-resx</resheader>\n    <resheader name=\"version\">2.0</resheader>\n    <resheader name=\"reader\">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>\n    <resheader name=\"writer\">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>\n    <data name=\"Name1\"><value>this is my long string</value><comment>this is a comment</comment></data>\n    <data name=\"Color1\" type=\"System.Drawing.Color, System.Drawing\">Blue</data>\n    <data name=\"Bitmap1\" mimetype=\"application/x-microsoft.net.object.binary.base64\">\n        <value>[base64 mime encoded serialized .NET Framework object]</value>\n    </data>\n    <data name=\"Icon1\" type=\"System.Drawing.Icon, System.Drawing\" mimetype=\"application/x-microsoft.net.object.bytearray.base64\">\n        <value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>\n        <comment>This is a comment</comment>\n    </data>\n                \n    There are any number of \"resheader\" rows that contain simple \n    name/value pairs.\n    \n    Each data row contains a name, and value. The row also contains a \n    type or mimetype. Type corresponds to a .NET class that support \n    text/value conversion through the TypeConverter architecture. \n    Classes that don't support this are serialized and stored with the \n    mimetype set.\n    \n    The mimetype is used for serialized objects, and tells the \n    ResXResourceReader how to depersist the object. This is currently not \n    extensible. For a given mimetype the value must be set accordingly:\n    \n    Note - application/x-microsoft.net.object.binary.base64 is the format \n    that the ResXResourceWriter will generate, however the reader can \n    read any of the formats listed below.\n    \n    mimetype: application/x-microsoft.net.object.binary.base64\n    value   : The object must be serialized with \n            : System.Runtime.Serialization.Formatters.Binary.BinaryFormatter\n            : and then encoded with base64 encoding.\n    \n    mimetype: application/x-microsoft.net.object.soap.base64\n    value   : The object must be serialized with \n            : System.Runtime.Serialization.Formatters.Soap.SoapFormatter\n            : and then encoded with base64 encoding.\n\n    mimetype: application/x-microsoft.net.object.bytearray.base64\n    value   : The object must be serialized into a byte array \n            : using a System.ComponentModel.TypeConverter\n            : and then encoded with base64 encoding.\n    -->\n  <xsd:schema id=\"root\" xmlns=\"\" xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\" xmlns:msdata=\"urn:schemas-microsoft-com:xml-msdata\">\n    <xsd:import namespace=\"http://www.w3.org/XML/1998/namespace\" />\n    <xsd:element name=\"root\" msdata:IsDataSet=\"true\">\n      <xsd:complexType>\n        <xsd:choice maxOccurs=\"unbounded\">\n          <xsd:element name=\"metadata\">\n            <xsd:complexType>\n              <xsd:sequence>\n                <xsd:element name=\"value\" type=\"xsd:string\" minOccurs=\"0\" />\n              </xsd:sequence>\n              <xsd:attribute name=\"name\" use=\"required\" type=\"xsd:string\" />\n              <xsd:attribute name=\"type\" type=\"xsd:string\" />\n              <xsd:attribute name=\"mimetype\" type=\"xsd:string\" />\n              <xsd:attribute ref=\"xml:space\" />\n            </xsd:complexType>\n          </xsd:element>\n          <xsd:element name=\"assembly\">\n            <xsd:complexType>\n              <xsd:attribute name=\"alias\" type=\"xsd:string\" />\n              <xsd:attribute name=\"name\" type=\"xsd:string\" />\n            </xsd:complexType>\n          </xsd:element>\n          <xsd:element name=\"data\">\n            <xsd:complexType>\n              <xsd:sequence>\n                <xsd:element name=\"value\" type=\"xsd:string\" minOccurs=\"0\" msdata:Ordinal=\"1\" />\n                <xsd:element name=\"comment\" type=\"xsd:string\" minOccurs=\"0\" msdata:Ordinal=\"2\" />\n              </xsd:sequence>\n              <xsd:attribute name=\"name\" type=\"xsd:string\" use=\"required\" msdata:Ordinal=\"1\" />\n              <xsd:attribute name=\"type\" type=\"xsd:string\" msdata:Ordinal=\"3\" />\n              <xsd:attribute name=\"mimetype\" type=\"xsd:string\" msdata:Ordinal=\"4\" />\n              <xsd:attribute ref=\"xml:space\" />\n            </xsd:complexType>\n          </xsd:element>\n          <xsd:element name=\"resheader\">\n            <xsd:complexType>\n              <xsd:sequence>\n                <xsd:element name=\"value\" type=\"xsd:string\" minOccurs=\"0\" msdata:Ordinal=\"1\" />\n              </xsd:sequence>\n              <xsd:attribute name=\"name\" type=\"xsd:string\" use=\"required\" />\n            </xsd:complexType>\n          </xsd:element>\n        </xsd:choice>\n      </xsd:complexType>\n    </xsd:element>\n  </xsd:schema>\n  <resheader name=\"resmimetype\">\n    <value>text/microsoft-resx</value>\n  </resheader>\n  <resheader name=\"version\">\n    <value>2.0</value>\n  </resheader>\n  <resheader name=\"reader\">\n    <value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>\n  </resheader>\n  <resheader name=\"writer\">\n    <value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>\n  </resheader>\n  <metadata name=\"cpu_timer.TrayLocation\" type=\"System.Drawing.Point, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a\">\n    <value>17, 17</value>\n  </metadata>\n</root>"
  },
  {
    "path": "WinFormAnimation.Samples/MainForm.Designer.cs",
    "content": "﻿namespace WinFormAnimation.Samples\n{\n    partial class MainForm\n    {\n        /// <summary>\n        /// Required designer variable.\n        /// </summary>\n        private System.ComponentModel.IContainer components = null;\n\n        /// <summary>\n        /// Clean up any resources being used.\n        /// </summary>\n        /// <param name=\"disposing\">true if managed resources should be disposed; otherwise, false.</param>\n        protected override void Dispose(bool disposing)\n        {\n            if (disposing && (components != null))\n            {\n                components.Dispose();\n            }\n            base.Dispose(disposing);\n        }\n\n        /// <summary>\n        /// Required method for Designer support - do not modify\n        /// the contents of this method with the code editor.\n        /// </summary>\n        private void InitializeComponent()\n        {\n            this.label1 = new System.Windows.Forms.Label();\n            this.label2 = new System.Windows.Forms.Label();\n            this.label4 = new System.Windows.Forms.Label();\n            this.demo41 = new WinFormAnimation.Samples.Demo4();\n            this.demo31 = new WinFormAnimation.Samples.Demo3();\n            this.demo21 = new WinFormAnimation.Samples.Demo2();\n            this.demo11 = new WinFormAnimation.Samples.Demo1();\n            this.SuspendLayout();\n            // \n            // label1\n            // \n            this.label1.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom) \n            | System.Windows.Forms.AnchorStyles.Left) \n            | System.Windows.Forms.AnchorStyles.Right)));\n            this.label1.AutoSize = true;\n            this.label1.Location = new System.Drawing.Point(12, 12);\n            this.label1.Name = \"label1\";\n            this.label1.Size = new System.Drawing.Size(70, 13);\n            this.label1.TabIndex = 3;\n            this.label1.Text = \"1D Animation\";\n            // \n            // label2\n            // \n            this.label2.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom) \n            | System.Windows.Forms.AnchorStyles.Left) \n            | System.Windows.Forms.AnchorStyles.Right)));\n            this.label2.AutoSize = true;\n            this.label2.Location = new System.Drawing.Point(12, 92);\n            this.label2.Name = \"label2\";\n            this.label2.Size = new System.Drawing.Size(70, 13);\n            this.label2.TabIndex = 4;\n            this.label2.Text = \"3D Animation\";\n            // \n            // label4\n            // \n            this.label4.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom) \n            | System.Windows.Forms.AnchorStyles.Left) \n            | System.Windows.Forms.AnchorStyles.Right)));\n            this.label4.AutoSize = true;\n            this.label4.Location = new System.Drawing.Point(12, 174);\n            this.label4.Name = \"label4\";\n            this.label4.Size = new System.Drawing.Size(61, 13);\n            this.label4.TabIndex = 7;\n            this.label4.Text = \"Benchmark\";\n            // \n            // demo41\n            // \n            this.demo41.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom) \n            | System.Windows.Forms.AnchorStyles.Left) \n            | System.Windows.Forms.AnchorStyles.Right)));\n            this.demo41.BorderStyle = System.Windows.Forms.BorderStyle.FixedSingle;\n            this.demo41.Location = new System.Drawing.Point(12, 190);\n            this.demo41.Name = \"demo41\";\n            this.demo41.Size = new System.Drawing.Size(613, 82);\n            this.demo41.TabIndex = 6;\n            // \n            // demo31\n            // \n            this.demo31.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom) \n            | System.Windows.Forms.AnchorStyles.Left) \n            | System.Windows.Forms.AnchorStyles.Right)));\n            this.demo31.BorderStyle = System.Windows.Forms.BorderStyle.FixedSingle;\n            this.demo31.Location = new System.Drawing.Point(12, 108);\n            this.demo31.Name = \"demo31\";\n            this.demo31.Size = new System.Drawing.Size(245, 63);\n            this.demo31.TabIndex = 2;\n            // \n            // demo21\n            // \n            this.demo21.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom) \n            | System.Windows.Forms.AnchorStyles.Left) \n            | System.Windows.Forms.AnchorStyles.Right)));\n            this.demo21.BorderStyle = System.Windows.Forms.BorderStyle.FixedSingle;\n            this.demo21.Location = new System.Drawing.Point(263, 12);\n            this.demo21.Name = \"demo21\";\n            this.demo21.Size = new System.Drawing.Size(362, 159);\n            this.demo21.TabIndex = 1;\n            // \n            // demo11\n            // \n            this.demo11.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom) \n            | System.Windows.Forms.AnchorStyles.Left) \n            | System.Windows.Forms.AnchorStyles.Right)));\n            this.demo11.BorderStyle = System.Windows.Forms.BorderStyle.FixedSingle;\n            this.demo11.Location = new System.Drawing.Point(12, 28);\n            this.demo11.Name = \"demo11\";\n            this.demo11.Size = new System.Drawing.Size(245, 61);\n            this.demo11.TabIndex = 0;\n            // \n            // frm_Main\n            // \n            this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);\n            this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;\n            this.ClientSize = new System.Drawing.Size(639, 283);\n            this.Controls.Add(this.label4);\n            this.Controls.Add(this.demo41);\n            this.Controls.Add(this.label2);\n            this.Controls.Add(this.label1);\n            this.Controls.Add(this.demo31);\n            this.Controls.Add(this.demo21);\n            this.Controls.Add(this.demo11);\n            this.DoubleBuffered = true;\n            this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedSingle;\n            this.MaximizeBox = false;\n            this.MinimizeBox = false;\n            this.Name = \"frm_Main\";\n            this.Opacity = 0D;\n            this.StartPosition = System.Windows.Forms.FormStartPosition.CenterScreen;\n            this.Text = \"WinForm Animation Library Samples\";\n            this.Shown += new System.EventHandler(this.FormShown);\n            this.ResumeLayout(false);\n            this.PerformLayout();\n\n        }\n\n        private Demo1 demo11;\n        private Demo2 demo21;\n        private Demo3 demo31;\n        private System.Windows.Forms.Label label1;\n        private System.Windows.Forms.Label label2;\n        private Demo4 demo41;\n        private System.Windows.Forms.Label label4;\n\n\n    }\n}\n\n"
  },
  {
    "path": "WinFormAnimation.Samples/MainForm.cs",
    "content": "﻿using System;\nusing System.Windows.Forms;\n\nnamespace WinFormAnimation.Samples\n{\n    internal partial class MainForm : Form\n    {\n        public MainForm()\n        {\n            InitializeComponent();\n        }\n\n        private void FormShown(object sender, EventArgs e)\n        {\n            new Animator(new Path(0, 1, 400, 100)).Play(this, Animator.KnownProperties.Opacity);\n        }\n    }\n}"
  },
  {
    "path": "WinFormAnimation.Samples/MainForm.resx",
    "content": "﻿<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<root>\n  <!-- \n    Microsoft ResX Schema \n    \n    Version 2.0\n    \n    The primary goals of this format is to allow a simple XML format \n    that is mostly human readable. The generation and parsing of the \n    various data types are done through the TypeConverter classes \n    associated with the data types.\n    \n    Example:\n    \n    ... ado.net/XML headers & schema ...\n    <resheader name=\"resmimetype\">text/microsoft-resx</resheader>\n    <resheader name=\"version\">2.0</resheader>\n    <resheader name=\"reader\">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>\n    <resheader name=\"writer\">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>\n    <data name=\"Name1\"><value>this is my long string</value><comment>this is a comment</comment></data>\n    <data name=\"Color1\" type=\"System.Drawing.Color, System.Drawing\">Blue</data>\n    <data name=\"Bitmap1\" mimetype=\"application/x-microsoft.net.object.binary.base64\">\n        <value>[base64 mime encoded serialized .NET Framework object]</value>\n    </data>\n    <data name=\"Icon1\" type=\"System.Drawing.Icon, System.Drawing\" mimetype=\"application/x-microsoft.net.object.bytearray.base64\">\n        <value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>\n        <comment>This is a comment</comment>\n    </data>\n                \n    There are any number of \"resheader\" rows that contain simple \n    name/value pairs.\n    \n    Each data row contains a name, and value. The row also contains a \n    type or mimetype. Type corresponds to a .NET class that support \n    text/value conversion through the TypeConverter architecture. \n    Classes that don't support this are serialized and stored with the \n    mimetype set.\n    \n    The mimetype is used for serialized objects, and tells the \n    ResXResourceReader how to depersist the object. This is currently not \n    extensible. For a given mimetype the value must be set accordingly:\n    \n    Note - application/x-microsoft.net.object.binary.base64 is the format \n    that the ResXResourceWriter will generate, however the reader can \n    read any of the formats listed below.\n    \n    mimetype: application/x-microsoft.net.object.binary.base64\n    value   : The object must be serialized with \n            : System.Runtime.Serialization.Formatters.Binary.BinaryFormatter\n            : and then encoded with base64 encoding.\n    \n    mimetype: application/x-microsoft.net.object.soap.base64\n    value   : The object must be serialized with \n            : System.Runtime.Serialization.Formatters.Soap.SoapFormatter\n            : and then encoded with base64 encoding.\n\n    mimetype: application/x-microsoft.net.object.bytearray.base64\n    value   : The object must be serialized into a byte array \n            : using a System.ComponentModel.TypeConverter\n            : and then encoded with base64 encoding.\n    -->\n  <xsd:schema id=\"root\" xmlns=\"\" xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\" xmlns:msdata=\"urn:schemas-microsoft-com:xml-msdata\">\n    <xsd:import namespace=\"http://www.w3.org/XML/1998/namespace\" />\n    <xsd:element name=\"root\" msdata:IsDataSet=\"true\">\n      <xsd:complexType>\n        <xsd:choice maxOccurs=\"unbounded\">\n          <xsd:element name=\"metadata\">\n            <xsd:complexType>\n              <xsd:sequence>\n                <xsd:element name=\"value\" type=\"xsd:string\" minOccurs=\"0\" />\n              </xsd:sequence>\n              <xsd:attribute name=\"name\" use=\"required\" type=\"xsd:string\" />\n              <xsd:attribute name=\"type\" type=\"xsd:string\" />\n              <xsd:attribute name=\"mimetype\" type=\"xsd:string\" />\n              <xsd:attribute ref=\"xml:space\" />\n            </xsd:complexType>\n          </xsd:element>\n          <xsd:element name=\"assembly\">\n            <xsd:complexType>\n              <xsd:attribute name=\"alias\" type=\"xsd:string\" />\n              <xsd:attribute name=\"name\" type=\"xsd:string\" />\n            </xsd:complexType>\n          </xsd:element>\n          <xsd:element name=\"data\">\n            <xsd:complexType>\n              <xsd:sequence>\n                <xsd:element name=\"value\" type=\"xsd:string\" minOccurs=\"0\" msdata:Ordinal=\"1\" />\n                <xsd:element name=\"comment\" type=\"xsd:string\" minOccurs=\"0\" msdata:Ordinal=\"2\" />\n              </xsd:sequence>\n              <xsd:attribute name=\"name\" type=\"xsd:string\" use=\"required\" msdata:Ordinal=\"1\" />\n              <xsd:attribute name=\"type\" type=\"xsd:string\" msdata:Ordinal=\"3\" />\n              <xsd:attribute name=\"mimetype\" type=\"xsd:string\" msdata:Ordinal=\"4\" />\n              <xsd:attribute ref=\"xml:space\" />\n            </xsd:complexType>\n          </xsd:element>\n          <xsd:element name=\"resheader\">\n            <xsd:complexType>\n              <xsd:sequence>\n                <xsd:element name=\"value\" type=\"xsd:string\" minOccurs=\"0\" msdata:Ordinal=\"1\" />\n              </xsd:sequence>\n              <xsd:attribute name=\"name\" type=\"xsd:string\" use=\"required\" />\n            </xsd:complexType>\n          </xsd:element>\n        </xsd:choice>\n      </xsd:complexType>\n    </xsd:element>\n  </xsd:schema>\n  <resheader name=\"resmimetype\">\n    <value>text/microsoft-resx</value>\n  </resheader>\n  <resheader name=\"version\">\n    <value>2.0</value>\n  </resheader>\n  <resheader name=\"reader\">\n    <value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>\n  </resheader>\n  <resheader name=\"writer\">\n    <value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>\n  </resheader>\n</root>"
  },
  {
    "path": "WinFormAnimation.Samples/Program.cs",
    "content": "﻿using System;\nusing System.Windows.Forms;\n\nnamespace WinFormAnimation.Samples\n{\n    internal static class Program\n    {\n        /// <summary>\n        ///     The main entry point for the application.\n        /// </summary>\n        [STAThread]\n        private static void Main()\n        {\n            Application.EnableVisualStyles();\n            Application.SetCompatibleTextRenderingDefault(false);\n            Application.Run(new MainForm());\n        }\n    }\n}"
  },
  {
    "path": "WinFormAnimation.Samples/Properties/AssemblyInfo.cs",
    "content": "﻿using System.Reflection;\nusing System.Runtime.InteropServices;\n\n// General Information about an assembly is controlled through the following \n// set of attributes. Change these attribute values to modify the information\n// associated with an assembly.\n\n[assembly: AssemblyTitle(\"Demo\")]\n[assembly: AssemblyDescription(\"\")]\n[assembly: AssemblyConfiguration(\"\")]\n[assembly: AssemblyCompany(\"\")]\n[assembly: AssemblyProduct(\"Demo\")]\n[assembly: AssemblyCopyright(\"Copyright ©  2013\")]\n[assembly: AssemblyTrademark(\"\")]\n[assembly: AssemblyCulture(\"\")]\n\n// Setting ComVisible to false makes the types in this assembly not visible \n// to COM components.  If you need to access a type in this assembly from \n// COM, set the ComVisible attribute to true on that type.\n\n[assembly: ComVisible(false)]\n\n// The following GUID is for the ID of the typelib if this project is exposed to COM\n\n[assembly: Guid(\"071459e3-8a65-47e6-9d8b-ccff86732fe2\")]\n\n// Version information for an assembly consists of the following four values:\n//\n//      Major Version\n//      Minor Version \n//      Build Number\n//      Revision\n//\n// You can specify all the values or you can default the Build and Revision Numbers \n// by using the '*' as shown below:\n// [assembly: AssemblyVersion(\"1.0.*\")]\n\n[assembly: AssemblyVersion(\"1.0.0.0\")]\n[assembly: AssemblyFileVersion(\"1.0.0.0\")]"
  },
  {
    "path": "WinFormAnimation.Samples/Properties/Resources.Designer.cs",
    "content": "﻿//------------------------------------------------------------------------------\n// <auto-generated>\n//     This code was generated by a tool.\n//     Runtime Version:4.0.30319.42000\n//\n//     Changes to this file may cause incorrect behavior and will be lost if\n//     the code is regenerated.\n// </auto-generated>\n//------------------------------------------------------------------------------\n\nnamespace WinFormAnimation.Samples.Properties {\n    using System;\n    \n    \n    /// <summary>\n    ///   A strongly-typed resource class, for looking up localized strings, etc.\n    /// </summary>\n    // This class was auto-generated by the StronglyTypedResourceBuilder\n    // class via a tool like ResGen or Visual Studio.\n    // To add or remove a member, edit your .ResX file then rerun ResGen\n    // with the /str option, or rebuild your VS project.\n    [global::System.CodeDom.Compiler.GeneratedCodeAttribute(\"System.Resources.Tools.StronglyTypedResourceBuilder\", \"15.0.0.0\")]\n    [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]\n    [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]\n    internal class Resources {\n        \n        private static global::System.Resources.ResourceManager resourceMan;\n        \n        private static global::System.Globalization.CultureInfo resourceCulture;\n        \n        [global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute(\"Microsoft.Performance\", \"CA1811:AvoidUncalledPrivateCode\")]\n        internal Resources() {\n        }\n        \n        /// <summary>\n        ///   Returns the cached ResourceManager instance used by this class.\n        /// </summary>\n        [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]\n        internal static global::System.Resources.ResourceManager ResourceManager {\n            get {\n                if (object.ReferenceEquals(resourceMan, null)) {\n                    global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager(\"WinFormAnimation.Samples.Properties.Resources\", typeof(Resources).Assembly);\n                    resourceMan = temp;\n                }\n                return resourceMan;\n            }\n        }\n        \n        /// <summary>\n        ///   Overrides the current thread's CurrentUICulture property for all\n        ///   resource lookups using this strongly typed resource class.\n        /// </summary>\n        [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]\n        internal static global::System.Globalization.CultureInfo Culture {\n            get {\n                return resourceCulture;\n            }\n            set {\n                resourceCulture = value;\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized resource of type System.Drawing.Bitmap.\n        /// </summary>\n        internal static System.Drawing.Bitmap star_32 {\n            get {\n                object obj = ResourceManager.GetObject(\"star-32\", resourceCulture);\n                return ((System.Drawing.Bitmap)(obj));\n            }\n        }\n    }\n}\n"
  },
  {
    "path": "WinFormAnimation.Samples/Properties/Resources.resx",
    "content": "﻿<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<root>\n  <!-- \n    Microsoft ResX Schema \n    \n    Version 2.0\n    \n    The primary goals of this format is to allow a simple XML format \n    that is mostly human readable. The generation and parsing of the \n    various data types are done through the TypeConverter classes \n    associated with the data types.\n    \n    Example:\n    \n    ... ado.net/XML headers & schema ...\n    <resheader name=\"resmimetype\">text/microsoft-resx</resheader>\n    <resheader name=\"version\">2.0</resheader>\n    <resheader name=\"reader\">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>\n    <resheader name=\"writer\">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>\n    <data name=\"Name1\"><value>this is my long string</value><comment>this is a comment</comment></data>\n    <data name=\"Color1\" type=\"System.Drawing.Color, System.Drawing\">Blue</data>\n    <data name=\"Bitmap1\" mimetype=\"application/x-microsoft.net.object.binary.base64\">\n        <value>[base64 mime encoded serialized .NET Framework object]</value>\n    </data>\n    <data name=\"Icon1\" type=\"System.Drawing.Icon, System.Drawing\" mimetype=\"application/x-microsoft.net.object.bytearray.base64\">\n        <value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>\n        <comment>This is a comment</comment>\n    </data>\n                \n    There are any number of \"resheader\" rows that contain simple \n    name/value pairs.\n    \n    Each data row contains a name, and value. The row also contains a \n    type or mimetype. Type corresponds to a .NET class that support \n    text/value conversion through the TypeConverter architecture. \n    Classes that don't support this are serialized and stored with the \n    mimetype set.\n    \n    The mimetype is used for serialized objects, and tells the \n    ResXResourceReader how to depersist the object. This is currently not \n    extensible. For a given mimetype the value must be set accordingly:\n    \n    Note - application/x-microsoft.net.object.binary.base64 is the format \n    that the ResXResourceWriter will generate, however the reader can \n    read any of the formats listed below.\n    \n    mimetype: application/x-microsoft.net.object.binary.base64\n    value   : The object must be serialized with \n            : System.Runtime.Serialization.Formatters.Binary.BinaryFormatter\n            : and then encoded with base64 encoding.\n    \n    mimetype: application/x-microsoft.net.object.soap.base64\n    value   : The object must be serialized with \n            : System.Runtime.Serialization.Formatters.Soap.SoapFormatter\n            : and then encoded with base64 encoding.\n\n    mimetype: application/x-microsoft.net.object.bytearray.base64\n    value   : The object must be serialized into a byte array \n            : using a System.ComponentModel.TypeConverter\n            : and then encoded with base64 encoding.\n    -->\n  <xsd:schema id=\"root\" xmlns=\"\" xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\" xmlns:msdata=\"urn:schemas-microsoft-com:xml-msdata\">\n    <xsd:import namespace=\"http://www.w3.org/XML/1998/namespace\" />\n    <xsd:element name=\"root\" msdata:IsDataSet=\"true\">\n      <xsd:complexType>\n        <xsd:choice maxOccurs=\"unbounded\">\n          <xsd:element name=\"metadata\">\n            <xsd:complexType>\n              <xsd:sequence>\n                <xsd:element name=\"value\" type=\"xsd:string\" minOccurs=\"0\" />\n              </xsd:sequence>\n              <xsd:attribute name=\"name\" use=\"required\" type=\"xsd:string\" />\n              <xsd:attribute name=\"type\" type=\"xsd:string\" />\n              <xsd:attribute name=\"mimetype\" type=\"xsd:string\" />\n              <xsd:attribute ref=\"xml:space\" />\n            </xsd:complexType>\n          </xsd:element>\n          <xsd:element name=\"assembly\">\n            <xsd:complexType>\n              <xsd:attribute name=\"alias\" type=\"xsd:string\" />\n              <xsd:attribute name=\"name\" type=\"xsd:string\" />\n            </xsd:complexType>\n          </xsd:element>\n          <xsd:element name=\"data\">\n            <xsd:complexType>\n              <xsd:sequence>\n                <xsd:element name=\"value\" type=\"xsd:string\" minOccurs=\"0\" msdata:Ordinal=\"1\" />\n                <xsd:element name=\"comment\" type=\"xsd:string\" minOccurs=\"0\" msdata:Ordinal=\"2\" />\n              </xsd:sequence>\n              <xsd:attribute name=\"name\" type=\"xsd:string\" use=\"required\" msdata:Ordinal=\"1\" />\n              <xsd:attribute name=\"type\" type=\"xsd:string\" msdata:Ordinal=\"3\" />\n              <xsd:attribute name=\"mimetype\" type=\"xsd:string\" msdata:Ordinal=\"4\" />\n              <xsd:attribute ref=\"xml:space\" />\n            </xsd:complexType>\n          </xsd:element>\n          <xsd:element name=\"resheader\">\n            <xsd:complexType>\n              <xsd:sequence>\n                <xsd:element name=\"value\" type=\"xsd:string\" minOccurs=\"0\" msdata:Ordinal=\"1\" />\n              </xsd:sequence>\n              <xsd:attribute name=\"name\" type=\"xsd:string\" use=\"required\" />\n            </xsd:complexType>\n          </xsd:element>\n        </xsd:choice>\n      </xsd:complexType>\n    </xsd:element>\n  </xsd:schema>\n  <resheader name=\"resmimetype\">\n    <value>text/microsoft-resx</value>\n  </resheader>\n  <resheader name=\"version\">\n    <value>2.0</value>\n  </resheader>\n  <resheader name=\"reader\">\n    <value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>\n  </resheader>\n  <resheader name=\"writer\">\n    <value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>\n  </resheader>\n  <assembly alias=\"System.Windows.Forms\" name=\"System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089\" />\n  <data name=\"star-32\" type=\"System.Resources.ResXFileRef, System.Windows.Forms\">\n    <value>..\\Resources\\star-32.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</value>\n  </data>\n</root>"
  },
  {
    "path": "WinFormAnimation.Samples/Properties/Settings.Designer.cs",
    "content": "﻿//------------------------------------------------------------------------------\n// <auto-generated>\n//     This code was generated by a tool.\n//     Runtime Version:4.0.30319.42000\n//\n//     Changes to this file may cause incorrect behavior and will be lost if\n//     the code is regenerated.\n// </auto-generated>\n//------------------------------------------------------------------------------\n\nnamespace WinFormAnimation.Samples.Properties {\n    \n    \n    [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]\n    [global::System.CodeDom.Compiler.GeneratedCodeAttribute(\"Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator\", \"15.9.0.0\")]\n    internal sealed partial class Settings : global::System.Configuration.ApplicationSettingsBase {\n        \n        private static Settings defaultInstance = ((Settings)(global::System.Configuration.ApplicationSettingsBase.Synchronized(new Settings())));\n        \n        public static Settings Default {\n            get {\n                return defaultInstance;\n            }\n        }\n    }\n}\n"
  },
  {
    "path": "WinFormAnimation.Samples/Properties/Settings.settings",
    "content": "﻿<?xml version='1.0' encoding='utf-8'?>\n<SettingsFile xmlns=\"http://schemas.microsoft.com/VisualStudio/2004/01/settings\" CurrentProfile=\"(Default)\">\n  <Profiles>\n    <Profile Name=\"(Default)\" />\n  </Profiles>\n  <Settings />\n</SettingsFile>\n"
  },
  {
    "path": "WinFormAnimation.Samples/WinFormAnimation.Samples.csproj",
    "content": "﻿<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<Project ToolsVersion=\"4.0\" DefaultTargets=\"Build\" xmlns=\"http://schemas.microsoft.com/developer/msbuild/2003\">\n  <Import Project=\"$(MSBuildExtensionsPath)\\$(MSBuildToolsVersion)\\Microsoft.Common.props\" Condition=\"Exists('$(MSBuildExtensionsPath)\\$(MSBuildToolsVersion)\\Microsoft.Common.props')\" />\n  <PropertyGroup>\n    <Configuration Condition=\" '$(Configuration)' == '' \">Debug</Configuration>\n    <Platform Condition=\" '$(Platform)' == '' \">AnyCPU</Platform>\n    <ProjectGuid>{EF38FA05-26F0-49DB-A18F-4C5B6303C77A}</ProjectGuid>\n    <OutputType>WinExe</OutputType>\n    <AppDesignerFolder>Properties</AppDesignerFolder>\n    <RootNamespace>WinFormAnimation.Samples</RootNamespace>\n    <AssemblyName>WinFormAnimation.Samples</AssemblyName>\n    <TargetFrameworkVersion>v4.0</TargetFrameworkVersion>\n    <FileAlignment>512</FileAlignment>\n    <TargetFrameworkProfile>\n    </TargetFrameworkProfile>\n  </PropertyGroup>\n  <PropertyGroup Condition=\" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' \">\n    <PlatformTarget>AnyCPU</PlatformTarget>\n    <DebugSymbols>true</DebugSymbols>\n    <DebugType>full</DebugType>\n    <Optimize>false</Optimize>\n    <OutputPath>bin\\Debug\\</OutputPath>\n    <DefineConstants>DEBUG;TRACE</DefineConstants>\n    <ErrorReport>prompt</ErrorReport>\n    <WarningLevel>4</WarningLevel>\n    <Prefer32Bit>false</Prefer32Bit>\n  </PropertyGroup>\n  <PropertyGroup Condition=\" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' \">\n    <PlatformTarget>AnyCPU</PlatformTarget>\n    <DebugType>pdbonly</DebugType>\n    <Optimize>true</Optimize>\n    <OutputPath>bin\\Release\\</OutputPath>\n    <DefineConstants>TRACE</DefineConstants>\n    <ErrorReport>prompt</ErrorReport>\n    <WarningLevel>4</WarningLevel>\n    <Prefer32Bit>false</Prefer32Bit>\n  </PropertyGroup>\n  <ItemGroup>\n    <Reference Include=\"System\" />\n    <Reference Include=\"System.Core\" />\n    <Reference Include=\"System.Drawing\" />\n    <Reference Include=\"System.Windows.Forms\" />\n  </ItemGroup>\n  <ItemGroup>\n    <Compile Include=\"Demo2.cs\">\n      <SubType>UserControl</SubType>\n    </Compile>\n    <Compile Include=\"Demo2.Designer.cs\">\n      <DependentUpon>Demo2.cs</DependentUpon>\n    </Compile>\n    <Compile Include=\"Demo1.cs\">\n      <SubType>UserControl</SubType>\n    </Compile>\n    <Compile Include=\"Demo1.Designer.cs\">\n      <DependentUpon>Demo1.cs</DependentUpon>\n    </Compile>\n    <Compile Include=\"Demo3.cs\">\n      <SubType>UserControl</SubType>\n    </Compile>\n    <Compile Include=\"Demo3.Designer.cs\">\n      <DependentUpon>Demo3.cs</DependentUpon>\n    </Compile>\n    <Compile Include=\"Demo4.cs\">\n      <SubType>UserControl</SubType>\n    </Compile>\n    <Compile Include=\"Demo4.Designer.cs\">\n      <DependentUpon>Demo4.cs</DependentUpon>\n    </Compile>\n    <Compile Include=\"MainForm.cs\">\n      <SubType>Form</SubType>\n    </Compile>\n    <Compile Include=\"MainForm.Designer.cs\">\n      <DependentUpon>MainForm.cs</DependentUpon>\n    </Compile>\n    <Compile Include=\"Program.cs\" />\n    <Compile Include=\"Properties\\AssemblyInfo.cs\" />\n    <EmbeddedResource Include=\"Demo2.resx\">\n      <DependentUpon>Demo2.cs</DependentUpon>\n      <SubType>Designer</SubType>\n    </EmbeddedResource>\n    <EmbeddedResource Include=\"Demo1.resx\">\n      <DependentUpon>Demo1.cs</DependentUpon>\n      <SubType>Designer</SubType>\n    </EmbeddedResource>\n    <EmbeddedResource Include=\"Demo3.resx\">\n      <DependentUpon>Demo3.cs</DependentUpon>\n      <SubType>Designer</SubType>\n    </EmbeddedResource>\n    <EmbeddedResource Include=\"Demo4.resx\">\n      <DependentUpon>Demo4.cs</DependentUpon>\n    </EmbeddedResource>\n    <EmbeddedResource Include=\"MainForm.resx\">\n      <DependentUpon>MainForm.cs</DependentUpon>\n      <SubType>Designer</SubType>\n    </EmbeddedResource>\n    <EmbeddedResource Include=\"Properties\\Resources.resx\">\n      <Generator>ResXFileCodeGenerator</Generator>\n      <LastGenOutput>Resources.Designer.cs</LastGenOutput>\n      <SubType>Designer</SubType>\n    </EmbeddedResource>\n    <Compile Include=\"Properties\\Resources.Designer.cs\">\n      <AutoGen>True</AutoGen>\n      <DependentUpon>Resources.resx</DependentUpon>\n      <DesignTime>True</DesignTime>\n    </Compile>\n    <None Include=\"app.config\" />\n    <None Include=\"Properties\\Settings.settings\">\n      <Generator>SettingsSingleFileGenerator</Generator>\n      <LastGenOutput>Settings.Designer.cs</LastGenOutput>\n    </None>\n    <Compile Include=\"Properties\\Settings.Designer.cs\">\n      <AutoGen>True</AutoGen>\n      <DependentUpon>Settings.settings</DependentUpon>\n      <DesignTimeSharedInput>True</DesignTimeSharedInput>\n    </Compile>\n  </ItemGroup>\n  <ItemGroup>\n    <ProjectReference Include=\"..\\WinFormAnimation\\WinFormAnimation.csproj\">\n      <Project>{4fe3eb4d-c3f1-4715-aac5-c8671f646414}</Project>\n      <Name>WinFormAnimation</Name>\n    </ProjectReference>\n  </ItemGroup>\n  <ItemGroup>\n    <None Include=\"Resources\\star-32.png\" />\n  </ItemGroup>\n  <Import Project=\"$(MSBuildToolsPath)\\Microsoft.CSharp.targets\" />\n  <!-- To modify your build process, add your task inside one of the targets below and uncomment it. \n       Other similar extension points exist, see Microsoft.Common.targets.\n  <Target Name=\"BeforeBuild\">\n  </Target>\n  <Target Name=\"AfterBuild\">\n  </Target>\n  -->\n</Project>"
  },
  {
    "path": "WinFormAnimation.Samples/app.config",
    "content": "<?xml version=\"1.0\"?>\n<configuration>\n<startup><supportedRuntime version=\"v4.0\" sku=\".NETFramework,Version=v4.0\"/></startup></configuration>\n"
  },
  {
    "path": "WinFormAnimation.sln",
    "content": "﻿\nMicrosoft Visual Studio Solution File, Format Version 12.00\n# Visual Studio 14\nVisualStudioVersion = 14.0.24720.0\nMinimumVisualStudioVersion = 10.0.40219.1\nProject(\"{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}\") = \"WinFormAnimation\", \"WinFormAnimation\\WinFormAnimation.csproj\", \"{4FE3EB4D-C3F1-4715-AAC5-C8671F646414}\"\nEndProject\nProject(\"{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}\") = \"WinFormAnimation.Samples\", \"WinFormAnimation.Samples\\WinFormAnimation.Samples.csproj\", \"{EF38FA05-26F0-49DB-A18F-4C5B6303C77A}\"\nEndProject\nGlobal\n\tGlobalSection(SolutionConfigurationPlatforms) = preSolution\n\t\tDebug|Any CPU = Debug|Any CPU\n\t\tRelease|Any CPU = Release|Any CPU\n\tEndGlobalSection\n\tGlobalSection(ProjectConfigurationPlatforms) = postSolution\n\t\t{4FE3EB4D-C3F1-4715-AAC5-C8671F646414}.Debug|Any CPU.ActiveCfg = Debug|Any CPU\n\t\t{4FE3EB4D-C3F1-4715-AAC5-C8671F646414}.Debug|Any CPU.Build.0 = Debug|Any CPU\n\t\t{4FE3EB4D-C3F1-4715-AAC5-C8671F646414}.Release|Any CPU.ActiveCfg = Release|Any CPU\n\t\t{4FE3EB4D-C3F1-4715-AAC5-C8671F646414}.Release|Any CPU.Build.0 = Release|Any CPU\n\t\t{EF38FA05-26F0-49DB-A18F-4C5B6303C77A}.Debug|Any CPU.ActiveCfg = Debug|Any CPU\n\t\t{EF38FA05-26F0-49DB-A18F-4C5B6303C77A}.Debug|Any CPU.Build.0 = Debug|Any CPU\n\t\t{EF38FA05-26F0-49DB-A18F-4C5B6303C77A}.Release|Any CPU.ActiveCfg = Release|Any CPU\n\t\t{EF38FA05-26F0-49DB-A18F-4C5B6303C77A}.Release|Any CPU.Build.0 = Release|Any CPU\n\tEndGlobalSection\n\tGlobalSection(SolutionProperties) = preSolution\n\t\tHideSolutionNode = FALSE\n\tEndGlobalSection\nEndGlobal\n"
  },
  {
    "path": "WinFormAnimation.sln.DotSettings",
    "content": "﻿<wpf:ResourceDictionary xml:space=\"preserve\" xmlns:x=\"http://schemas.microsoft.com/winfx/2006/xaml\" xmlns:s=\"clr-namespace:System;assembly=mscorlib\" xmlns:ss=\"urn:shemas-jetbrains-com:settings-storage-xaml\" xmlns:wpf=\"http://schemas.microsoft.com/winfx/2006/xaml/presentation\">\n\t<s:String x:Key=\"/Default/CodeStyle/Naming/CSharpNaming/Abbreviations/=FPS/@EntryIndexedValue\">FPS</s:String></wpf:ResourceDictionary>"
  }
]