Rystem 5.0.5

There is a newer version of this package available.
See the version list below for details.
dotnet add package Rystem --version 5.0.5
NuGet\Install-Package Rystem -Version 5.0.5
This command is intended to be used within the Package Manager Console in Visual Studio, as it uses the NuGet module's version of Install-Package.
<PackageReference Include="Rystem" Version="5.0.5" />
For projects that support PackageReference, copy this XML node into the project file to reference the package.
paket add Rystem --version 5.0.5
#r "nuget: Rystem, 5.0.5"
#r directive can be used in F# Interactive and Polyglot Notebooks. Copy this into the interactive tool or source code of the script to reference the package.
// Install Rystem as a Cake Addin
#addin nuget:?package=Rystem&version=5.0.5

// Install Rystem as a Cake Tool
#tool nuget:?package=Rystem&version=5.0.5

What is Rystem?

Get Started

Extension methods

Stopwatch

You can monitor the time spent on an action, task or in a method. Some examples from Unit test.

var started = Stopwatch.Start();
//do something
await Task.Delay(2000);
var result = started.Stop();

or

var result = await Stopwatch.MonitorAsync(async () =>
{
    await Task.Delay(2000);
});

or with a return value

 var result = await Stopwatch.MonitorAsync(async () =>
{
    await Task.Delay(2000);
    return 3;
});

Linq expression serializer

Usually a linq expression is not serializable as string. With this method you can serialize your expression with some limits. Only primitives are allowed in the expression body. An example from Unit test.

Expression<Func<MakeIt, bool>> expression = ƒ => ƒ.X == q && ƒ.Samules.Any(x => x == k) && ƒ.Sol && (ƒ.X.Contains(q) || ƒ.Sol.Equals(IsOk)) && (ƒ.E == id | ƒ.Id == V) && (ƒ.Type == MakeType.Yes || ƒ.Type == qq);
var serialized = expression.Serialize();

with result

"ƒ => ((((((ƒ.X == \"dasda\") AndAlso ƒ.Samules.Any(x => (x == \"ccccde\"))) AndAlso ƒ.Sol) AndAlso (ƒ.X.Contains(\"dasda\") OrElse ƒ.Sol.Equals(True))) AndAlso ((ƒ.E == Guid.Parse(\"bf46510b-b7e6-4ba2-88da-cef208aa81f2\")) Or (ƒ.Id == 32))) AndAlso ((ƒ.Type == 1) OrElse (ƒ.Type == 2)))"

with deserialization

var newExpression = expressionAsString.Deserialize<MakeIt, bool>();

and usage, for instance, with Linq

var result = makes.Where(newExpression.Compile()).ToList();

you can deserialize and compile at the same time with

var newExpression = expressionAsString.DeserializeAndCompile<MakeIt, bool>();

you can deserialize as dynamic and use the linq dynamic methods

Expression<Func<MakeIt, int>> expression = x => x.Id;
string value = expression.Serialize();
LambdaExpression newLambda = value.DeserializeAsDynamic<MakeIt>();
var got = makes.AsQueryable();
var cut = got.OrderByDescending(newLambda).ThenByDescending(newLambda).ToList();

please see the unit test here to understand better how it works You may deal with return type of your lambda expression:

 LambdaExpression newLambda = value.DeserializeAsDynamic<MakeIt>();
 newLambda =  newLambda.ChangeReturnType<bool>();

or

 newLambda =  newLambda.ChangeReturnType(typeof(bool));

Reflection helper

Name of calling class

You can find the name of the calling class from your method, with deep = 1 the calling class of your method, with deep = 2 the calling class that calls the class that calls your method, and so on, with fullName set to true you obtain the complete name of the discovered class.

ReflectionHelper.NameOfCallingClass(deep, fullName);
Extensions for Type class

You can get the properties, fields and constructors for your class (and singleton them to save time during new requests)

Type.FetchProperties();
Type.FecthConstructors();
Type.FetchFields();

You can check if a Type is a son or a father or both of other type (in the example Zalo and Folli are Sulo). You may find more information in unit test here

Zalo zalo = new();
Zalo zalo2 = new();
Folli folli = new();
Sulo sulo = new();
object quo = new();
int x = 2;
decimal y = 3;
Assert.True(zalo.IsTheSameTypeOrASon(sulo));
Assert.True(folli.IsTheSameTypeOrASon(sulo));
Assert.True(zalo.IsTheSameTypeOrASon(zalo2));
Assert.True(zalo.IsTheSameTypeOrASon(quo));
Assert.False(sulo.IsTheSameTypeOrASon(zalo));
Assert.True(sulo.IsTheSameTypeOrAParent(zalo));
Assert.False(y.IsTheSameTypeOrAParent(x));
Mock a Type

If you need to create a type over an abstract class or interface you may use the mocking system of Rystem. For example, if you have an abstract class like this one down below.

public abstract class Alzio
{
    private protected string X { get; }
    public string O => X;
    public string A { get; set; }
    public Alzio(string x)
    {
        X = x;
    }
}

you can create an instace of it or simply mock it with

var mocked = typeof(Alzio).CreateInstance("AAA") as Alzio;
mocked.A = "rrrr";

and you can use the class like a real class. You also may do it with

Alzio alzio = null!;
var mocked = alzio.CreateInstance("AAA");
mocked.A = "rrrr";

or

Mocking.CreateInstance<Alzio>("AAA");

you may see "AAA" as argument for your constructor in abstract class.

Text extensions

You may convert as fast as possible byte[] to string or stream to byte[] or byte[] to stream or stream to string or string to stream. For example, string to byte array and viceversa.

string olfa = "daskemnlandxioasndslam dasmdpoasmdnasndaslkdmlasmv asmdsa";
var bytes = olfa.ToByteArray();
string value = bytes.ConvertToString();

For example, string to stream and viceversa.

string olfa = "daskemnlandxioasndslam dasmdpoasmdnasndaslkdmlasmv asmdsa";
var stream = olfa.ToStream();
string value = stream.ConvertToString();

You may read a string with break lines as an enumerable of string

string olfa = "daskemnlandxioasndslam\ndasmdpoasmdnasndaslkdmlasmv\nasmdsa";
var stream = olfa.ToStream();
var strings = new List<string>();
await foreach (var x in stream.ReadLinesAsync())
{
    strings.Add(x);
}

A simple method to make uppercase the first character.

string olfa = "dasda";
var olfa2 = olfa.ToUpperCaseFirst();

A simple method to check if a char is contained at least X times.

string value = "abcderfa";
bool containsAtLeastTwoAChar = value.ContainsAtLeast(2, 'a');

Character separated-value (CSV)

Transform any kind of IEnumerable data in a CSV string.

string value = _models.ToCsv();

Minimization of a model (based on CSV concept)

It's a brand new idea to serialize any kind of objects (with lesser occupied space of json), the idea comes from Command separated-value standard. To serialize

string value = _models.ToMinimize();

To deserialize (for instance in a List of a class named CsvModel)

value.FromMinimization<List<CsvModel>>();

Extensions for json

I don't know if you are fed up to write JsonSerializer.Serialize, I do, and so, you may use the extension method to serialize faster. To serialize

var text = value.ToJson();

To deserialize in a class (for instance a class named User)

var value = text.FromJson<User>();

Extensions for Task

I don't know if you still are fed up to write .ConfigureAwait(false) to eliminate the context waiting for a task. I do. Why should I set the configure await to false? To set configure await to false

await {your async task}.NoContext();

Instead, to get the result as synchronous result but with a configure await set to false.

{your async task}.ToResult();

You may change the behavior of your NoContext() or ToResult(), setting (in the bootstrap of your application for example)

RystemTask.WaitYourStartingThread = true;

When do I need a true? In windows application for example you have to return after a button clicked to the same thread that started the request.

TaskManager

When you need to run a list of tasks concurrently you may use this static method.

In the next example with TaskManager.WhenAll you may run a method ExecuteAsync {times} times with {concurrentTasks} times in concurrency, and running them when a time slot is free. For example if you run this function with 8 times and 3 concurrentsTasks and true in runEverytimeASlotIsFree You will have this behavior: first 3 tasks starts and since the fourth the implementation waits the end of one of the 3 started before. As soon as one of the 3 started is finished the implementation starts to run the fourth.

var bag = new ConcurrentBag<int>();
await TaskManager.WhenAll(ExecuteAsync, times, concurrentTasks, runEverytimeASlotIsFree).NoContext();

Assert.Equal(times, bag.Count);

async Task ExecuteAsync(int i, CancellationToken cancellationToken)
{
    await Task.Delay(i * 20, cancellationToken).NoContext();
    bag.Add(i);
}

You may run a {atLeast} times of tasks and stopping to wait the remaining tasks with TaskManager.WhenAtLeast

var bag = new ConcurrentBag<int>();
await TaskManager.WhenAtLeast(ExecuteAsync, times, atLeast, concurrentTasks).NoContext();

Assert.True(bag.Count < times);
Assert.True(bag.Count >= atLeast);

async Task ExecuteAsync(int i, CancellationToken cancellationToken)
{
    await Task.Delay(i * 20, cancellationToken).NoContext();
    bag.Add(i);
}

Concurrency

ConcurrentList

You can use the ConcurrentList implementation to have the List behavior with lock operations.

var items = new ConcurrentList<ItemClass>();

Dependency injection extensions

Warm up

When you use the DI pattern in your .Net application you could need a warm up after the build of your services. And with Rystem you can simply do it.

builder.Services.AddWarmUp(() => somethingToDo());

and after the build use the warm up

var app = builder.Build();
await app.Services.WarmUpAsync();

Population service

You can use the population service to create a list of random value of a specific Type. An example from unit test explains how to use the service.

IServiceCollection services = new ServiceCollection();
services.AddPopulationService();
var serviceProvider = services.BuildServiceProvider().CreateScope().ServiceProvider;
var populatedModel = serviceProvider.GetService<IPopulation<PopulationModelTest>>();
IPopulation<PopulationModelTest> allPrepopulation = populatedModel!
    .Setup()
    .WithPattern(x => x.J!.First().A, "[a-z]{4,5}")
        .WithPattern(x => x.Y!.First().Value.A, "[a-z]{4,5}")
        .WithImplementation(x => x.I, typeof(MyInnerInterfaceImplementation))
        .WithPattern(x => x.I!.A!, "[a-z]{4,5}")
        .WithPattern(x => x.II!.A!, "[a-z]{4,5}")
        .WithImplementation<IInnerInterface, MyInnerInterfaceImplementation>(x => x.I!);
var all = allPrepopulation.Populate();

Abstract factory

You can use this abstract factory solution when you need to setup more than one service of the same kind and you need to distinguish them by a name.

I have an interface

public interface IMyService
{
    string GetName();
}

Some options for every service

public class SingletonOption
{
    public string ServiceName { get; set; }
}
public class TransientOption
{
    public string ServiceName { get; set; }
}
public class ScopedOption
{
    public string ServiceName { get; set; }
}

with built options which is a IServiceOptions, a options class that ends up with another class. Used for example when you have to add a settings like a connection string but you want to use a service like a client that uses that connection string.

public class BuiltScopedOptions : IServiceOptions<ScopedOption>
{
    public string ServiceName { get; set; }

    public Task<Func<ScopedOption>> BuildAsync()
    {
        return Task.FromResult(() => new ScopedOption
        {
            ServiceName = ServiceName
        });
    }
}

And six different services

public class SingletonService : IMyService, IServiceWithOptions<SingletonOption>
{
    public SingletonOption Options { get; set; }
    public string Id { get; } = Guid.NewGuid().ToString();
    public string GetName()
    {
        return $"{Options.ServiceName} with id {Id}";
    }
}
public class TransientService : IMyService, IServiceWithOptions<TransientOption>
{
    public TransientOption Options { get; set; }
    public string Id { get; } = Guid.NewGuid().ToString();
    public string GetName()
    {
        return $"{Options.ServiceName} with id {Id}";
    }
}
public class ScopedService : IMyService, IServiceWithOptions<ScopedOption>
{
    public ScopedOption Options { get; set; }
    public string Id { get; } = Guid.NewGuid().ToString();
    public string GetName()
    {
        return $"{Options.ServiceName} with id {Id}";
    }
}
public class ScopedService2 : IMyService, IServiceWithOptions<ScopedOption>
{
    public ScopedOption Options { get; set; }
    public string Id { get; } = Guid.NewGuid().ToString();

    public string GetName()
    {
        return $"{Options.ServiceName} with id {Id}";
    }
}
public class ScopedService3 : IMyService, IServiceWithOptions<ScopedOption>
{
    public ScopedOption Options { get; set; }
    public string Id { get; } = Guid.NewGuid().ToString();

    public string GetName()
    {
        return $"{Options.ServiceName} with id {Id}";
    }
}
public class ScopedService4 : IMyService, IServiceWithOptions<ScopedOption>
{
    public ScopedOption Options { get; set; }
    public string Id { get; } = Guid.NewGuid().ToString();

    public string GetName()
    {
        return $"{Options.ServiceName} with id {Id}";
    }
}

I can setup them in this way

var services = new ServiceCollection();
services.AddFactory<IMyService, SingletonService, SingletonOption>(x =>
{
    x.ServiceName = "singleton";
},
"singleton",
ServiceLifetime.Singleton);

services.AddFactory<IMyService, TransientService, TransientOption>(x =>
{
    x.ServiceName = "transient";
},
"transient",
ServiceLifetime.Transient);

services.AddFactory<IMyService, ScopedService, ScopedOption>(x =>
{
    x.ServiceName = "scoped";
},
"scoped",
ServiceLifetime.Scoped);

services.AddFactory<IMyService, ScopedService2, ScopedOption>(x =>
{
    x.ServiceName = "scoped2";
},
"scoped2",
ServiceLifetime.Scoped);

await services.AddFactoryAsync<IMyService, ScopedService3, BuiltScopedOptions, ScopedOption>(
    x =>
    {
        x.ServiceName = "scoped3";
    },
    "scoped3"
);

await services.AddFactoryAsync<IMyService, ScopedService3, BuiltScopedOptions, ScopedOption>(
    x =>
    {
        x.ServiceName = "scoped3_2";
    },
    "scoped3_2"
);

await services.AddFactoryAsync<IMyService, ScopedService4, BuiltScopedOptions, ScopedOption>(
    x =>
    {
        x.ServiceName = "scoped4";
    },
    "scoped4"
);

and use them in this way

var serviceProvider = services.BuildServiceProvider().CreateScope().ServiceProvider;
var factory = serviceProvider.GetService<IFactory<IMyService>>()!;
var factory2 = serviceProvider.GetService<IFactory<IMyService>>()!;

var singletonFromFactory = factory.Create("singleton").Id;
var singletonFromFactory2 = factory2.Create("singleton").Id;
var transientFromFactory = factory.Create("transient").Id;
var transientFromFactory2 = factory2.Create("transient").Id;
var scopedFromFactory = factory.Create("scoped").Id;
var scopedFromFactory2 = factory2.Create("scoped").Id;
var scoped2FromFactory = factory.Create("scoped2").Id;
var scoped2FromFactory2 = factory2.Create("scoped2").Id;
var scoped3FromFactory = factory.Create("scoped3").Id;
var scoped3FromFactory2 = factory2.Create("scoped3").Id;
var scoped3_2FromFactory = factory.Create("scoped3_2").Id;
var scoped3_2FromFactory2 = factory2.Create("scoped3_2").Id;
var scoped4FromFactory = factory.Create("scoped4").Id;
var scoped4FromFactory2 = factory2.Create("scoped4").Id;

Assert.Equal(singletonFromFactory, singletonFromFactory2);
Assert.NotEqual(transientFromFactory, transientFromFactory2);
Assert.Equal(scopedFromFactory, scopedFromFactory2);
Assert.Equal(scoped2FromFactory, scoped2FromFactory2);
Assert.NotEqual(scoped3FromFactory, scoped3FromFactory2);
Assert.NotEqual(scoped3_2FromFactory, scoped3_2FromFactory2);
Assert.NotEqual(scoped4FromFactory, scoped4FromFactory2);

Decorator

You may add a decoration for your services, based on the abstract factory integration. The decorator service replaces the previous version and receives it during the injection.

Setup

services
    .AddService<ITestWithoutFactoryService, TestWithoutFactoryService>(lifetime);
services
    .AddDecoration<ITestWithoutFactoryService, TestWithoutFactoryServiceDecorator>(null, lifetime);

Usage

var decorator = provider.GetRequiredService<ITestWithoutFactoryService>();
var previousService = provider.GetRequiredService<IDecoratedService<ITestWithoutFactoryService>>();

In decorator you may find the previousService in the method SetDecoratedService which runs in injection

public class TestWithoutFactoryServiceDecorator : ITestWithoutFactoryService, IDecoratorService<ITestWithoutFactoryService>
{
    public string Id { get; } = Guid.NewGuid().ToString();
    public ITestWithoutFactoryService Test { get; private set; }
    public void SetDecoratedService(ITestWithoutFactoryService service)
    {
        Test = service;
    }

    public void SetFactoryName(string name)
    {
        return;
    }
}

Decorator with Abstract Factory integration

You may add a decoration only for one service of your factory integration.

Setup

services.AddFactory<ITestService, TestService, TestOptions>(x =>
{
    x.ClassicName = classicName;
},
factoryName,
lifetime);
services
    .AddDecoration<ITestService, DecoratorTestService>(factoryName, lifetime);

Usage

var decoratorFactory = provider.GetRequiredService<IFactory<ITestService>>();
var decorator = decoratorFactory.Create(factoryName);
var previousService = decoratorFactory.CreateWithoutDecoration(factoryName);

Scan dependency injection

You may scan your assemblies in search of types you need to add to dependency injection. For instance I have an interface IAnything and I need to add all classes which implements it.

public interface IAnything
{
}
internal class ScanModels : IAnything
{
}

and in service collection I can add it.

serviceCollection
    .Scan<IAnything>(ServiceLifetime.Scoped, typeof(IAnything).Assembly);

I can add to my class the interface IScannable of T to scan automatically. For instance.

public interface IAnything
{
}
internal class ScanModels : IAnything, IScannable<IAnything>
{
}

and in service collection I could add it in this way

serviceCollection
    .Scan(ServiceLifetime.Scoped, typeof(IAnything).Assembly);

Furthermore with ISingletonScannable, IScopedScannable and ITransientScannable I can override the service lifetime. For instance.

public interface IAnything
{
}
internal class ScanModels : IAnything, IScannable<IAnything>, ISingletonScannable
{
}

serviceCollection
    .Scan(ServiceLifetime.Scoped, typeof(IAnything).Assembly);

ScanModels will be installed as a Singleton service, overwriting the service lifetime from Scan method.

You also automatically use different assembly sources.

serviceCollection
    .ScanDependencyContext(ServiceLifetime.Scoped);

or

serviceCollection
    .ScanCallingAssembly(ServiceLifetime.Scoped);

or

serviceCollection
    .ScanCurrentDomain(ServiceLifetime.Scoped);

or

serviceCollection
    .ScanEntryAssembly(ServiceLifetime.Scoped);

or

serviceCollection
    .ScanExecutingAssembly(ServiceLifetime.Scoped);

or

serviceCollection
    .ScanFromType<T>(ServiceLifetime.Scoped);

or

serviceCollection
    .ScanFromTypes<T1, T2>(ServiceLifetime.Scoped);

Finally with ScanWithReferences you may call all the assemblies you want plus all referenced assemblies by them.

Product Compatible and additional computed target framework versions.
.NET net7.0 is compatible.  net7.0-android was computed.  net7.0-ios was computed.  net7.0-maccatalyst was computed.  net7.0-macos was computed.  net7.0-tvos was computed.  net7.0-windows was computed.  net8.0 was computed.  net8.0-android was computed.  net8.0-browser was computed.  net8.0-ios was computed.  net8.0-maccatalyst was computed.  net8.0-macos was computed.  net8.0-tvos was computed.  net8.0-windows was computed. 
Compatible target framework(s)
Included target framework(s) (in package)
Learn more about Target Frameworks and .NET Standard.

NuGet packages (1)

Showing the top 1 NuGet packages that depend on Rystem:

Package Downloads
Rystem.DependencyInjection

Rystem is a open-source framework to improve the System namespace in .Net

GitHub repositories

This package is not used by any popular GitHub repositories.

Version Downloads Last updated
6.0.4 213,245 4/3/2024
6.0.3 568 3/25/2024
6.0.2 378,819 3/11/2024
6.0.1 51,037 3/8/2024
6.0.0 1,171,305 11/21/2023
6.0.0-rc.6 166 10/25/2023
6.0.0-rc.5 119 10/25/2023
6.0.0-rc.4 89 10/23/2023
6.0.0-rc.3 89 10/19/2023
6.0.0-rc.2 158 10/18/2023
6.0.0-rc.1 184 10/16/2023
5.0.20 640,522 9/25/2023
5.0.19 2,757 9/10/2023
5.0.18 2,056 9/6/2023
5.0.17 1,895 9/6/2023
5.0.16 1,952 9/5/2023
5.0.15 1,919 9/5/2023
5.0.14 1,919 9/5/2023
5.0.13 2,028 9/1/2023
5.0.12 1,879 8/31/2023
5.0.11 1,873 8/30/2023
5.0.10 1,899 8/29/2023
5.0.9 1,934 8/24/2023
5.0.8 1,953 8/24/2023
5.0.7 451,423 8/23/2023
5.0.6 19,472 8/21/2023
5.0.5 6,148 8/21/2023
5.0.4 2,007 8/16/2023
5.0.3 214,718 8/2/2023
5.0.2 3,762 8/2/2023
5.0.1 13,575 8/1/2023
5.0.0 13,874 7/31/2023
4.1.26 142,958 7/20/2023
4.1.25 24,652 7/16/2023
4.1.24 401,914 6/13/2023
4.1.23 47,668 6/13/2023
4.1.22 131,509 5/30/2023
4.1.21 57,765 5/20/2023
4.1.20 407,028 4/19/2023
4.1.19 97,725 3/20/2023
4.1.18 2,368 3/20/2023
4.1.17 2,658 3/16/2023
4.1.16 2,419 3/16/2023
4.1.15 2,823 3/15/2023
4.1.14 12,219 3/9/2023
4.1.13 2,516 3/7/2023
4.1.12 2,885 2/9/2023
4.1.11 2,547 1/26/2023
4.1.10 2,780 1/22/2023
4.1.9 2,388 1/20/2023
4.1.8 2,593 1/18/2023
4.1.7 2,632 1/18/2023
4.1.6 2,493 1/17/2023
4.1.5 333 1/15/2023
4.1.4 331 1/15/2023
4.1.3 329 1/15/2023
4.1.2 346 1/15/2023
4.1.1 2,498 1/4/2023
4.1.0 2,666 12/30/2022
4.0.102 2,680 12/21/2022
4.0.101 757 12/20/2022
4.0.100 319 12/19/2022
4.0.99 345 12/18/2022
4.0.98 6,210 12/7/2022
4.0.97 330 12/7/2022
4.0.96 326 12/7/2022
4.0.95 326 12/7/2022
4.0.94 4,187 12/1/2022
4.0.93 358 12/1/2022
4.0.92 3,206 11/29/2022
4.0.91 7,523 11/22/2022
4.0.90 4,441 11/18/2022
4.0.89 4,167 11/18/2022
4.0.88 4,313 11/15/2022
4.0.87 4,268 11/14/2022
4.0.86 4,385 11/13/2022
4.0.85 4,702 11/2/2022
4.0.84 4,381 11/2/2022
4.0.83 4,555 10/29/2022
4.0.82 4,638 10/29/2022
4.0.81 1,658 10/29/2022
4.0.80 13,772 10/16/2022
4.0.79 4,194 10/9/2022
4.0.78 428 10/9/2022
4.0.77 416 10/8/2022
4.0.76 21,054 10/5/2022
4.0.75 42,853 9/20/2022
4.0.74 4,746 9/20/2022
4.0.73 4,377 9/20/2022
4.0.72 643 9/20/2022
4.0.71 3,875 9/20/2022
4.0.70 518 9/14/2022
4.0.69 486 9/14/2022
4.0.68 4,605 9/13/2022
4.0.67 460 9/1/2022
4.0.66 4,363 8/19/2022
4.0.65 439 8/19/2022
4.0.64 451 8/19/2022
4.0.63 474 8/16/2022
4.0.62 486 8/16/2022
4.0.61 431 8/16/2022
4.0.60 458 8/14/2022
4.0.59 483 8/13/2022
4.0.58 455 8/13/2022
4.0.57 477 8/13/2022
4.0.56 461 8/13/2022
4.0.54 486 8/13/2022
4.0.53 477 8/12/2022
4.0.52 447 8/11/2022
4.0.51 472 8/9/2022
4.0.50 475 8/8/2022
4.0.49 465 8/8/2022
4.0.48 460 8/8/2022
4.0.47 461 8/6/2022
4.0.46 449 8/6/2022
4.0.45 453 8/5/2022
4.0.44 441 8/5/2022
4.0.43 467 8/4/2022
4.0.42 473 8/4/2022
4.0.41 470 8/4/2022
4.0.40 458 8/3/2022
4.0.39 466 8/3/2022
4.0.38 4,701 7/30/2022
4.0.37 4,437 7/29/2022
4.0.36 3,919 7/29/2022
4.0.35 464 7/29/2022
4.0.34 761 7/29/2022
4.0.33 4,630 7/29/2022
4.0.32 4,446 7/29/2022
4.0.31 472 7/29/2022
4.0.30 476 7/29/2022
4.0.29 4,498 7/27/2022
4.0.28 517 7/27/2022
4.0.26 4,414 7/27/2022
4.0.25 4,063 7/26/2022
4.0.24 4,542 7/25/2022
4.0.23 4,468 7/25/2022
4.0.22 4,351 7/22/2022
4.0.21 4,397 7/19/2022
4.0.20 4,439 7/19/2022
4.0.19 487 7/19/2022
4.0.18 4,462 7/19/2022
4.0.17 4,479 7/19/2022
4.0.16 4,528 7/18/2022
4.0.15 4,401 7/18/2022
4.0.14 495 7/18/2022
4.0.13 4,452 7/18/2022
4.0.12 3,974 7/17/2022
4.0.11 1,444 7/17/2022
4.0.10 498 7/17/2022
4.0.9 1,121 7/17/2022
4.0.8 13,498 7/15/2022
4.0.7 5,635 7/15/2022
4.0.6 6,346 7/8/2022
4.0.5 6,071 7/6/2022
4.0.4 11,177 7/1/2022
4.0.3 1,277 6/29/2022
4.0.1 1,763 6/29/2022
4.0.0 1,236 6/27/2022
3.0.2 1,135 5/5/2022
3.0.1 1,414 11/30/2021
3.0.0 1,372 11/12/2021
2.0.12 2,430 10/14/2021
2.0.11 1,512 10/14/2021
2.0.8 2,314 10/6/2021
2.0.7 1,699 10/2/2021
2.0.6 443 9/30/2021
2.0.5 402 9/30/2021
2.0.4 1,512 9/29/2021
2.0.3 1,617 9/28/2021
2.0.2 1,324 9/26/2021
2.0.1 1,201 9/24/2021
2.0.0 1,279 9/22/2021
1.4.0 1,363 9/14/2021
1.3.18 1,274 9/10/2021
1.3.17 1,091 9/9/2021
1.3.16 1,400 8/28/2021
1.3.15 1,164 8/26/2021
1.3.14 1,140 8/19/2021
1.3.13 1,150 8/13/2021
1.3.12 1,202 8/12/2021
1.3.11 473 7/29/2021
1.3.10 1,258 7/27/2021
1.3.9 1,204 7/27/2021
1.3.1 1,278 7/25/2021
1.3.0 1,937 7/17/2021
1.2.4 1,221 7/14/2021
1.2.3 423 7/14/2021
1.2.2 402 7/14/2021
1.2.1 1,273 7/14/2021
1.2.0 2,526 7/13/2021
1.1.0 625 4/14/2021
1.0.3 383 4/13/2021
1.0.2 393 4/13/2021
1.0.1 387 4/13/2021
1.0.0 411 4/12/2021