I-Synergy.Framework.Mvvm 2025.11207.11553-preview

Prefix Reserved
This is a prerelease version of I-Synergy.Framework.Mvvm.
dotnet add package I-Synergy.Framework.Mvvm --version 2025.11207.11553-preview
                    
NuGet\Install-Package I-Synergy.Framework.Mvvm -Version 2025.11207.11553-preview
                    
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="I-Synergy.Framework.Mvvm" Version="2025.11207.11553-preview" />
                    
For projects that support PackageReference, copy this XML node into the project file to reference the package.
<PackageVersion Include="I-Synergy.Framework.Mvvm" Version="2025.11207.11553-preview" />
                    
Directory.Packages.props
<PackageReference Include="I-Synergy.Framework.Mvvm" />
                    
Project file
For projects that support Central Package Management (CPM), copy this XML node into the solution Directory.Packages.props file to version the package.
paket add I-Synergy.Framework.Mvvm --version 2025.11207.11553-preview
                    
#r "nuget: I-Synergy.Framework.Mvvm, 2025.11207.11553-preview"
                    
#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.
#:package I-Synergy.Framework.Mvvm@2025.11207.11553-preview
                    
#:package directive can be used in C# file-based apps starting in .NET 10 preview 4. Copy this into a .cs file before any lines of code to reference the package.
#addin nuget:?package=I-Synergy.Framework.Mvvm&version=2025.11207.11553-preview&prerelease
                    
Install as a Cake Addin
#tool nuget:?package=I-Synergy.Framework.Mvvm&version=2025.11207.11553-preview&prerelease
                    
Install as a Cake Tool

I-Synergy Framework MVVM

A comprehensive MVVM (Model-View-ViewModel) framework for building modern .NET 10.0 applications. This package provides a complete set of base classes, commands, and services for implementing the MVVM pattern with built-in support for validation, navigation, dialogs, and asynchronous operations.

NuGet License .NET

Features

  • Base ViewModel classes with lifecycle management and validation
  • Async command support with cancellation, timeout, and execution tracking
  • Dialog service for showing messages, errors, and custom dialogs
  • Navigation service for managing application navigation
  • Specialized ViewModels for common scenarios (Dialog, Blade, Selection, Wizard)
  • Built-in validation using DataAnnotations
  • Automatic busy state management integration
  • Clean separation of UI and business logic
  • Fully testable ViewModels and commands
  • Command cancellation and concurrent execution control
  • Event aggregation through messenger service integration

Installation

Install the package via NuGet:

dotnet add package I-Synergy.Framework.Mvvm

Quick Start

1. Create a Basic ViewModel

using ISynergy.Framework.Core.Abstractions.Services;
using ISynergy.Framework.Mvvm.ViewModels;
using ISynergy.Framework.Mvvm.Commands;
using Microsoft.Extensions.Logging;

public class CustomerViewModel : ViewModel
{
    private readonly ICustomerService _customerService;

    public string Name
    {
        get => GetValue<string>();
        set => SetValue(value);
    }

    public string Email
    {
        get => GetValue<string>();
        set => SetValue(value);
    }

    public AsyncRelayCommand SaveCommand { get; }
    public AsyncRelayCommand LoadCustomersCommand { get; }

    public CustomerViewModel(
        ICommonServices commonServices,
        ICustomerService customerService,
        ILogger<CustomerViewModel> logger)
        : base(commonServices, logger)
    {
        _customerService = customerService;

        Title = "Customer Management";

        SaveCommand = new AsyncRelayCommand(SaveAsync, CanSave);
        LoadCustomersCommand = new AsyncRelayCommand(LoadCustomersAsync);
    }

    public override async Task InitializeAsync()
    {
        await base.InitializeAsync();
        await LoadCustomersCommand.ExecuteAsync(null);
        IsInitialized = true;
    }

    private bool CanSave() => !string.IsNullOrEmpty(Name) && !string.IsNullOrEmpty(Email);

    private async Task SaveAsync()
    {
        try
        {
            CommonServices.BusyService.StartBusy("Saving customer...");

            var customer = new Customer
            {
                Name = Name,
                Email = Email
            };

            await _customerService.SaveAsync(customer);

            await CommonServices.DialogService.ShowInformationAsync(
                "Customer saved successfully",
                "Success");
        }
        catch (Exception ex)
        {
            await CommonServices.DialogService.ShowErrorAsync(ex, "Error");
        }
        finally
        {
            CommonServices.BusyService.StopBusy();
        }
    }

    private async Task LoadCustomersAsync()
    {
        // Load customers logic
    }
}

2. Using Async Commands

using ISynergy.Framework.Mvvm.Commands;
using ISynergy.Framework.Mvvm.Enumerations;

public class DataViewModel : ViewModel
{
    public AsyncRelayCommand<string> SearchCommand { get; }
    public AsyncRelayCommand RefreshCommand { get; }
    public AsyncRelayCommand LongRunningCommand { get; }

    public DataViewModel(ICommonServices commonServices, ILogger<DataViewModel> logger)
        : base(commonServices, logger)
    {
        // Basic async command
        SearchCommand = new AsyncRelayCommand<string>(SearchAsync);

        // Command with CanExecute
        RefreshCommand = new AsyncRelayCommand(RefreshAsync, CanRefresh);

        // Command with timeout (30 seconds)
        LongRunningCommand = new AsyncRelayCommand(
            LongRunningOperationAsync,
            TimeSpan.FromSeconds(30));

        // Command with options
        var downloadCommand = new AsyncRelayCommand(
            DownloadAsync,
            AsyncRelayCommandOptions.AllowConcurrentExecutions);
    }

    private async Task SearchAsync(string query, CancellationToken cancellationToken)
    {
        // Search with cancellation support
        var results = await _service.SearchAsync(query, cancellationToken);
        // Update UI
    }

    private bool CanRefresh() => IsInitialized && !string.IsNullOrEmpty(SomeProperty);

    private async Task RefreshAsync()
    {
        await Task.Delay(1000);
        RefreshCommand.NotifyCanExecuteChanged();
    }

    private async Task LongRunningOperationAsync(CancellationToken cancellationToken)
    {
        // Long running operation with cancellation
        for (int i = 0; i < 100; i++)
        {
            cancellationToken.ThrowIfCancellationRequested();
            await Task.Delay(100, cancellationToken);
        }
    }

    private async Task DownloadAsync()
    {
        // Can be called multiple times concurrently
        await _service.DownloadFileAsync();
    }
}

3. Dialog ViewModel

using ISynergy.Framework.Mvvm.ViewModels;

public class EditCustomerViewModel : ViewModelDialog<Customer>
{
    public string Name
    {
        get => GetValue<string>();
        set => SetValue(value);
    }

    public AsyncRelayCommand SubmitCommand { get; }

    public EditCustomerViewModel(
        ICommonServices commonServices,
        ILogger<EditCustomerViewModel> logger)
        : base(commonServices, logger)
    {
        Title = "Edit Customer";
        SubmitCommand = new AsyncRelayCommand(SubmitAsync);
    }

    public override async Task InitializeAsync()
    {
        await base.InitializeAsync();

        // Load data from SelectedItem
        if (SelectedItem is not null)
        {
            Name = SelectedItem.Name;
        }

        IsInitialized = true;
    }

    private async Task SubmitAsync()
    {
        if (!IsValid)
        {
            await CommonServices.DialogService.ShowWarningAsync(
                "Please fix validation errors",
                "Validation");
            return;
        }

        // Update the selected item
        SelectedItem.Name = Name;

        // Close the dialog with the result
        OnSubmit(SelectedItem);
        await CloseAsync();
    }
}

// Usage in another ViewModel
public async Task EditCustomerAsync(Customer customer)
{
    await CommonServices.DialogService.ShowDialogAsync<EditCustomerWindow, EditCustomerViewModel, Customer>(customer);
}

4. Navigation ViewModel

public class ProductListViewModel : ViewModelNavigation<Product>
{
    private readonly IProductService _productService;

    public ObservableCollection<Product> Products { get; } = new();

    public AsyncRelayCommand<Product> SelectProductCommand { get; }
    public AsyncRelayCommand AddProductCommand { get; }

    public ProductListViewModel(
        ICommonServices commonServices,
        IProductService productService,
        ILogger<ProductListViewModel> logger)
        : base(commonServices, logger)
    {
        _productService = productService;

        Title = "Products";

        SelectProductCommand = new AsyncRelayCommand<Product>(SelectProductAsync);
        AddProductCommand = new AsyncRelayCommand(AddProductAsync);
    }

    public override async Task InitializeAsync()
    {
        await base.InitializeAsync();

        var products = await _productService.GetAllAsync();
        Products.Clear();
        foreach (var product in products)
        {
            Products.Add(product);
        }

        IsInitialized = true;
    }

    private async Task SelectProductAsync(Product product)
    {
        // Navigate to detail view
        await CommonServices.NavigationService.NavigateToAsync<ProductDetailViewModel>(product);
    }

    private async Task AddProductAsync()
    {
        var newProduct = await CommonServices.DialogService
            .ShowDialogAsync<AddProductWindow, AddProductViewModel, Product>();

        if (newProduct is not null)
        {
            Products.Add(newProduct);
        }
    }
}

Architecture

ViewModel Hierarchy

ViewModel (base)
├── ViewModelDialog<TModel>          # For dialog windows with submit/cancel
├── ViewModelNavigation<TModel>      # For navigation views with selection
├── ViewModelBlade<TModel>           # For blade/panel patterns
├── ViewModelBladeView<TModel>       # For blade child views
├── ViewModelSummary<TModel>         # For summary/read-only views
└── ViewModelWizard<TModel>          # For multi-step wizards

Command Types

IRelayCommand
├── RelayCommand                     # Synchronous command without parameter
├── RelayCommand<T>                  # Synchronous command with parameter
├── AsyncRelayCommand                # Async command without parameter
├── AsyncRelayCommand<T>             # Async command with parameter
└── CancelCommand                    # Command for cancellation

Core Services

Dialog Service

public class MyViewModel : ViewModel
{
    public async Task ShowMessagesAsync()
    {
        // Show information
        await CommonServices.DialogService.ShowInformationAsync(
            "Operation completed successfully",
            "Success");

        // Show warning
        await CommonServices.DialogService.ShowWarningAsync(
            "This action cannot be undone",
            "Warning");

        // Show error
        await CommonServices.DialogService.ShowErrorAsync(
            new Exception("Something went wrong"),
            "Error");

        // Show confirmation
        var result = await CommonServices.DialogService.ShowMessageAsync(
            "Are you sure you want to delete this item?",
            "Confirm",
            MessageBoxButtons.YesNo);

        if (result == MessageBoxResult.Yes)
        {
            // Delete item
        }

        // Show custom dialog
        var customer = await CommonServices.DialogService
            .ShowDialogAsync<CustomerDialog, CustomerViewModel, Customer>();
    }
}
public class NavigationExample : ViewModel
{
    public async Task NavigationExamplesAsync()
    {
        // Navigate to view
        await CommonServices.NavigationService.NavigateToAsync<ProductListViewModel>();

        // Navigate with parameter
        await CommonServices.NavigationService.NavigateToAsync<ProductDetailViewModel>(product);

        // Navigate back
        await CommonServices.NavigationService.GoBackAsync();

        // Check if can go back
        bool canGoBack = CommonServices.NavigationService.CanGoBack;
    }
}

Busy Service

public async Task LoadDataAsync()
{
    try
    {
        CommonServices.BusyService.StartBusy("Loading data...");

        var data = await _service.LoadDataAsync();

        CommonServices.BusyService.UpdateMessage("Processing data...");
        ProcessData(data);
    }
    finally
    {
        CommonServices.BusyService.StopBusy();
    }
}

Advanced Features

Command Cancellation

public class CancellationExample : ViewModel
{
    public AsyncRelayCommand LongOperationCommand { get; }

    public CancellationExample(ICommonServices commonServices, ILogger<CancellationExample> logger)
        : base(commonServices, logger)
    {
        LongOperationCommand = new AsyncRelayCommand(LongOperationAsync);
    }

    private async Task LongOperationAsync(CancellationToken cancellationToken)
    {
        for (int i = 0; i < 100; i++)
        {
            // Check cancellation
            cancellationToken.ThrowIfCancellationRequested();

            await Task.Delay(100, cancellationToken);

            // Update progress
            CommonServices.BusyService.UpdateMessage($"Processing {i + 1}/100...");
        }
    }

    public void CancelOperation()
    {
        // Cancel the running command
        LongOperationCommand.Cancel();
    }

    protected override void OnNavigatedFrom()
    {
        // Automatically cancel running commands when navigating away
        base.OnNavigatedFrom();
    }
}

Command Options

// Allow concurrent executions (default: false)
var command1 = new AsyncRelayCommand(
    ExecuteAsync,
    AsyncRelayCommandOptions.AllowConcurrentExecutions);

// Flow exceptions to TaskScheduler (for global error handling)
var command2 = new AsyncRelayCommand(
    ExecuteAsync,
    AsyncRelayCommandOptions.FlowExceptionsToTaskScheduler);

// Combine options
var command3 = new AsyncRelayCommand(
    ExecuteAsync,
    AsyncRelayCommandOptions.AllowConcurrentExecutions |
    AsyncRelayCommandOptions.FlowExceptionsToTaskScheduler);

ViewModel Validation

using System.ComponentModel.DataAnnotations;

public class ValidatedViewModel : ViewModel
{
    [Required(ErrorMessage = "Name is required")]
    [StringLength(100, ErrorMessage = "Name must be less than 100 characters")]
    public string Name
    {
        get => GetValue<string>();
        set => SetValue(value);
    }

    [Required(ErrorMessage = "Email is required")]
    [EmailAddress(ErrorMessage = "Invalid email address")]
    public string Email
    {
        get => GetValue<string>();
        set => SetValue(value);
    }

    [Range(18, 120, ErrorMessage = "Age must be between 18 and 120")]
    public int Age
    {
        get => GetValue<int>();
        set => SetValue(value);
    }

    private async Task SaveAsync()
    {
        // Validate before saving
        if (!IsValid)
        {
            var errors = GetErrors().Select(e => e.ErrorMessage);
            await CommonServices.DialogService.ShowWarningAsync(
                string.Join(Environment.NewLine, errors),
                "Validation Errors");
            return;
        }

        // Save data
    }
}

Wizard ViewModel

public class CustomerWizardViewModel : ViewModelDialogWizard<Customer>
{
    public AsyncRelayCommand NextCommand { get; }
    public AsyncRelayCommand PreviousCommand { get; }

    public int CurrentStep
    {
        get => GetValue<int>();
        set => SetValue(value);
    }

    public CustomerWizardViewModel(
        ICommonServices commonServices,
        ILogger<CustomerWizardViewModel> logger)
        : base(commonServices, logger)
    {
        Title = "New Customer Wizard";
        CurrentStep = 1;

        NextCommand = new AsyncRelayCommand(NextStepAsync, CanGoNext);
        PreviousCommand = new AsyncRelayCommand(PreviousStepAsync, CanGoPrevious);
    }

    private bool CanGoNext() => CurrentStep < 3 && IsValid;
    private bool CanGoPrevious() => CurrentStep > 1;

    private async Task NextStepAsync()
    {
        CurrentStep++;
        NextCommand.NotifyCanExecuteChanged();
        PreviousCommand.NotifyCanExecuteChanged();
    }

    private async Task PreviousStepAsync()
    {
        CurrentStep--;
        NextCommand.NotifyCanExecuteChanged();
        PreviousCommand.NotifyCanExecuteChanged();
    }
}

Best Practices

Use AsyncRelayCommand for all asynchronous operations to get automatic busy state management and cancellation support.

Always call base.InitializeAsync() when overriding InitializeAsync() in derived ViewModels.

Commands automatically handle exceptions when using the default options. Set FlowExceptionsToTaskScheduler to handle exceptions globally.

ViewModel Lifecycle

  • Override InitializeAsync() for async initialization
  • Override Cleanup() for resource cleanup
  • Override OnNavigatedFrom() to cancel running commands
  • Override OnNavigatedTo() to reset command states
  • Call MarkAsClean() after saving changes
  • Use IsDirty to track unsaved changes

Command Usage

  • Use AsyncRelayCommand for async operations
  • Use RelayCommand for simple synchronous operations
  • Pass CancellationToken to support cancellation
  • Call NotifyCanExecuteChanged() when CanExecute state changes
  • Use timeout constructors for long-running operations
  • Set AllowConcurrentExecutions for independent operations

Dialog Patterns

  • Inherit from ViewModelDialog<T> for CRUD dialogs
  • Call OnSubmit(result) to return data
  • Call OnCancelled() for cancel operations
  • Check IsValid before submitting
  • Use SelectedItem for editing existing items
  • Inherit from ViewModelNavigation<T> for list views
  • Use NavigationService for view transitions
  • Pass data through navigation parameters
  • Clean up resources in OnNavigatedFrom()
  • Restore state in OnNavigatedTo()

Testing

The MVVM framework is designed for testability:

[Fact]
public async Task SaveCommand_ValidData_SavesCustomer()
{
    // Arrange
    var commonServices = CreateMockCommonServices();
    var customerService = new Mock<ICustomerService>();
    var logger = Mock.Of<ILogger<CustomerViewModel>>();

    var viewModel = new CustomerViewModel(commonServices.Object, customerService.Object, logger);
    viewModel.Name = "John Doe";
    viewModel.Email = "john@example.com";

    // Act
    await viewModel.SaveCommand.ExecuteAsync(null);

    // Assert
    customerService.Verify(s => s.SaveAsync(It.Is<Customer>(c =>
        c.Name == "John Doe" &&
        c.Email == "john@example.com")), Times.Once);
}

[Fact]
public void SaveCommand_InvalidData_CannotExecute()
{
    // Arrange
    var viewModel = new CustomerViewModel(/*...*/);
    viewModel.Name = ""; // Invalid

    // Act
    bool canExecute = viewModel.SaveCommand.CanExecute(null);

    // Assert
    Assert.False(canExecute);
}

[Fact]
public async Task LongOperationCommand_WhenCancelled_StopsExecution()
{
    // Arrange
    var viewModel = new MyViewModel(/*...*/);
    var task = viewModel.LongOperationCommand.ExecuteAsync(null);

    // Act
    await Task.Delay(100);
    viewModel.LongOperationCommand.Cancel();

    // Assert
    await Assert.ThrowsAsync<OperationCanceledException>(() => task);
}

Dependencies

  • I-Synergy.Framework.Core - Core abstractions and services
  • Microsoft.Extensions.Logging - Logging infrastructure

Documentation

For more information about the I-Synergy Framework:

  • I-Synergy.Framework.Core - Core framework components
  • I-Synergy.Framework.UI - Base UI components
  • I-Synergy.Framework.UI.Maui - MAUI UI implementation
  • I-Synergy.Framework.UI.WPF - WPF UI implementation
  • I-Synergy.Framework.UI.Blazor - Blazor UI implementation
  • I-Synergy.Framework.CQRS - CQRS pattern integration

Support

For issues, questions, or contributions, please visit the GitHub repository.

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

NuGet packages (13)

Showing the top 5 NuGet packages that depend on I-Synergy.Framework.Mvvm:

Package Downloads
I-Synergy.Framework.UI

I-Synergy UI Framework for Windows, Linux, Android and WebAssembly

I-Synergy.Framework.Update.WPF

I-Synergy Update Framework for WPF

I-Synergy.Framework.Update.WinUI

I-Synergy Update Framework for Windows

I-Synergy.Framework.Monitoring.Client

I-Synergy Framework SignalR Monitoring Client for .Net 7.0

I-Synergy.Framework.UI.Maui

I-Synergy UI Framework for .Net Maui

GitHub repositories

This package is not used by any popular GitHub repositories.

Version Downloads Last Updated
2025.11207.11553-preview 23 12/7/2025
2025.11204.11448-preview 133 12/4/2025
2025.11130.12248 434 11/30/2025
2025.11130.12134-preview 356 11/30/2025
2025.11130.11725-preview 360 11/30/2025
2025.11130.11553-preview 356 11/30/2025
2025.11130.11515-preview 366 11/30/2025
2025.11130.11420.59-preview 374 11/30/2025
2025.11130.11323.56-preview 267 11/30/2025
2025.11129.10227.14-preview 116 11/29/2025
2025.11120.10114 427 11/20/2025
2025.11119.10110 433 11/19/2025
2025.11118.12340.33-preview 427 11/18/2025
2025.11117.12349.4-preview 399 11/17/2025
2025.11117.11937.47-preview 410 11/17/2025
2025.11113.11532.29-preview 290 11/13/2025
2025.11113.10128.57-preview 299 11/13/2025
2025.11110.10306.55-preview 181 11/10/2025
2025.11109.10018.48-preview 102 11/8/2025
2025.11108.10119.29-preview 81 11/8/2025
2025.11106.10037.1-preview 146 11/6/2025
2025.11105.10254.54-preview 159 11/5/2025
2025.11105.10141.16-preview 155 11/5/2025
2025.11104.12308.54-preview 147 11/4/2025
2025.11104.10144.47-preview 156 11/4/2025
2025.11102.12003.8-preview 148 11/2/2025
2025.11102.11228.52-preview 142 11/2/2025
2025.11102.10309.42-preview 89 11/2/2025
2025.11029.11433.38-preview 145 10/29/2025
2025.11029.10201.38-preview 145 10/29/2025
2025.11027.11947.55-preview 154 10/27/2025
2025.11022.12207.12-preview 129 10/22/2025
2025.11019.12053.37-preview 128 10/19/2025
2025.11016.11750.24-preview 121 10/16/2025
2025.11015.10219.44-preview 138 10/15/2025
2025.11014.10245.12-preview 133 10/14/2025
2025.11012.10130.11-preview 78 10/12/2025
2025.11010.10052.52-preview 142 10/9/2025
2025.11001.12118.13-preview 136 10/1/2025
2025.10925.10144.25-preview 155 9/25/2025
2025.10921.11353.29-preview 171 9/21/2025
2025.10913.11841.29-preview 113 9/13/2025
2025.10912.12351.59-preview 64 9/12/2025
2025.10912.10210.52-preview 128 9/12/2025
2025.10911.10131.43-preview 133 9/10/2025
2025.10910.12340.34-preview 132 9/10/2025
2025.10910.11327.15-preview 126 9/10/2025
2025.10910.11206.45-preview 130 9/10/2025
2025.10910.10230.58-preview 132 9/10/2025
2025.10908.12343.47-preview 208 9/8/2025
2025.10904.12337.35-preview 223 9/4/2025
2025.10904.12245.51-preview 222 9/4/2025
2025.10904.11425.5-preview 227 9/4/2025
2025.10904.10323.39-preview 221 9/4/2025
2025.10826.11425.3-preview 273 8/26/2025
2025.10825.12350.9-preview 226 8/25/2025
2025.10810.10248-preview 167 8/10/2025
2025.10809.10146.35-preview 198 8/9/2025
2025.10806.12031.49-preview 288 8/6/2025
2025.10806.11955.54-preview 287 8/6/2025
2025.10806.11433.24-preview 287 8/6/2025
2025.10709.10105.39-preview 212 7/8/2025
2025.10707.12320.3-preview 216 7/7/2025
2025.10706.11957.9-preview 210 7/6/2025
2025.10702.11752.47-preview 193 7/2/2025
2025.10702.11256.17-preview 226 7/2/2025
2025.10702.11119.10-preview 216 7/2/2025
2025.10702.10000.31-preview 213 7/1/2025
2025.10701.11524.1-preview 219 7/1/2025
2025.10701.11310.13-preview 201 7/1/2025
2025.10630.12022.58-preview 218 6/30/2025
2025.10612.12134.8-preview 378 6/12/2025
2025.10611.12313.53-preview 354 6/11/2025
2025.10603.10159.54-preview 227 6/3/2025
2025.10602.11908.9-preview 222 6/2/2025
2025.10601.10124.29-preview 186 5/31/2025
2025.10531.12235.29-preview 158 5/31/2025
2025.10530.10121.50-preview 189 5/29/2025
2025.10527.12202.4-preview 227 5/27/2025
2025.10526.12034.25-preview 200 5/26/2025
2025.10521.11828.30-preview 218 5/21/2025
2025.10520.11715.6-preview 228 5/20/2025
2025.10520.11515.16-preview 219 5/20/2025
2025.10518.12303.43-preview 203 5/18/2025
2025.10518.11257.36-preview 216 5/18/2025
2025.10517.12347.27-preview 189 5/17/2025
2025.10517.12003.6-preview 169 5/17/2025
2025.10516.11720.13-preview 229 5/16/2025
2025.10514.12334.2-preview 318 5/14/2025
2025.10514.10015.27-preview 308 5/13/2025
2025.10511.11032.32-preview 242 5/11/2025
2025.10413.11530 280 4/13/2025
2025.10413.11434.33-preview 259 4/13/2025
2025.10413.10205.50-preview 195 4/13/2025
2025.10412.11526.4-preview 180 4/12/2025
2025.10412.10141 198 4/12/2025
2025.10411.11811.23-preview 178 4/11/2025
2025.10411.11645.1-preview 198 4/11/2025
2025.10410.11458.35-preview 217 4/10/2025
2025.10405.10143.28-preview 179 4/5/2025
2025.10403.12208.1-preview 215 4/3/2025
2025.10403.11954.16-preview 215 4/3/2025
2025.10401.11908.24-preview 207 4/1/2025
2025.10401.11559.45-preview 228 4/1/2025
2025.10331.12215.59-preview 245 3/31/2025
2025.10331.12130.34-preview 238 3/31/2025
2025.10331.10056.40-preview 222 3/30/2025
2025.10328.10150.21-preview 241 3/28/2025
2025.10323.11359-preview 378 3/23/2025
2025.10320.11800 262 3/20/2025
2025.10320.11616.45-preview 218 3/20/2025
2025.10320.10000 248 3/19/2025
2025.10319.12311.26-preview 235 3/19/2025
2025.10319.12238.6-preview 235 3/19/2025
2025.10319.12057.59-preview 257 3/19/2025
2025.10318.10055 244 3/18/2025
2025.10317.11728.13-preview 249 3/17/2025
2025.10317.11201.3-preview 242 3/17/2025
2025.10315.11523.14-preview 164 3/15/2025
2025.10305.12342 389 3/5/2025
2025.10305.12321.9-preview 281 3/5/2025
2025.10301.12313 284 3/1/2025
2025.10301.12129.38-preview 188 3/1/2025
2025.10221.10043.29-preview 234 2/21/2025
2025.1051.1246 220 2/20/2025
2025.1051.44.54-preview 214 2/20/2025
2025.1044.1 278 2/13/2025
2025.1044.0.2-preview 200 2/13/2025
2025.1043.0.2-preview 204 2/12/2025
2025.1041.0.1-preview 197 2/10/2025
2025.1038.1 261 2/7/2025
2025.1038.0.1-preview 201 2/7/2025
2025.1035.1 295 2/4/2025
2025.1035.0.1-preview 204 2/4/2025
2025.1034.1 285 2/3/2025
2025.1034.0.1-preview 214 2/3/2025
2025.1033.0.5-preview 195 2/2/2025
2025.1033.0.3-preview 215 2/2/2025
2025.1033.0.2-preview 203 2/2/2025
2025.1033.0.1-preview 209 2/2/2025
2025.1025.1 237 1/25/2025
2025.1025.0.1-preview 197 1/25/2025
2025.1021.1 252 1/21/2025
2025.1021.0.1-preview 181 1/21/2025
2025.1020.1 241 1/20/2025
2025.1020.0.3-preview 188 1/20/2025
2025.1020.0.1-preview 182 1/20/2025
2025.1018.0.7-preview 185 1/18/2025
2025.1018.0.5-preview 192 1/18/2025
2025.1018.0.4-preview 185 1/18/2025
2025.1017.0.2-preview 188 1/17/2025
2025.1017.0.1-preview 188 1/17/2025
2025.1016.0.1-preview 200 1/16/2025
2025.1010.1 239 1/10/2025
2025.1010.0.1-preview 195 1/9/2025
2025.1009.0.3-preview 199 1/9/2025
2025.1007.1 260 1/7/2025
2025.1007.0.5-preview 186 1/7/2025
2025.1007.0.3-preview 217 1/7/2025
2025.1006.1 252 1/7/2025
2025.1005.1 268 1/5/2025
2025.1005.0.2-preview 205 1/5/2025
2025.1004.1 261 1/4/2025
2024.1366.1 224 12/31/2024
2024.1366.0.2-preview 251 12/31/2024
2024.1366.0.1-preview 220 12/31/2024
2024.1365.0.2-preview 222 12/30/2024
2024.1365.0.1-preview 228 12/30/2024
2024.1361.0.2-preview 207 12/26/2024
2024.1353.0.1-preview 214 12/18/2024
2024.1352.0.3-preview 212 12/17/2024
2024.1352.0.2-preview 219 12/17/2024
2024.1352.0.1-preview 197 12/17/2024
2024.1351.1 239 12/16/2024
2024.1351.0.3-preview 228 12/16/2024
2024.1350.1 240 12/15/2024
2024.1343.1 256 12/8/2024
2024.1339.1 248 12/4/2024
2024.1336.1 221 12/1/2024
2024.1332.1 220 11/27/2024
2024.1330.1 241 11/25/2024
2024.1328.1 247 11/23/2024
2024.1325.1 251 11/20/2024
2024.1323.1 257 11/18/2024
2024.1316.1 159 11/11/2024
2024.1307.1 111 11/2/2024
2024.1300.1 136 10/26/2024
2024.1294.1 163 10/20/2024
2024.1290.1 261 10/16/2024
2024.1283.1 354 10/8/2024
2024.1282.1 263 10/8/2024
2024.1278.1 328 10/4/2024
2024.1277.1 266 10/3/2024
2024.1275.2 242 10/1/2024
2024.1275.1 214 10/1/2024
2024.1274.1 240 9/30/2024
2024.1263.1 212 9/19/2024
2024.1261.1 283 9/17/2024
2024.1258.1 228 9/13/2024
2024.1257.1 244 9/13/2024
2024.1256.1 236 9/12/2024
2024.1254.1 244 9/10/2024
2024.1250.1 263 9/6/2024
2024.1249.1 242 9/5/2024
2024.1246.1 273 9/2/2024
2024.1245.1 222 9/1/2024
2024.1237.1 260 8/24/2024
2024.1235.0.1-preview 242 8/23/2024
2024.1230.1 253 8/18/2024
2024.1229.1 256 8/16/2024
2024.1228.1 268 8/15/2024
2024.1222.1 257 8/8/2024
2024.1221.1 252 8/7/2024
2024.1221.0.2-preview 194 8/8/2024
2024.1221.0.1-preview 215 8/8/2024
2024.1220.1 245 8/7/2024
2024.1219.0.2-preview 214 8/6/2024
2024.1219.0.1-preview 203 8/6/2024
2024.1217.0.2-preview 196 8/4/2024
2024.1217.0.1-preview 207 8/4/2024
2024.1216.0.2-preview 202 8/3/2024
2024.1216.0.1-preview 186 8/3/2024
2024.1208.0.1-preview 203 7/26/2024
2024.1207.0.7-preview 210 7/25/2024
2024.1207.0.5-preview 169 7/25/2024
2024.1166.1 238 6/14/2024
2024.1165.1 208 6/13/2024
2024.1164.1 202 6/12/2024
2024.1162.1 194 6/10/2024
2024.1158.1 243 6/6/2024
2024.1156.1 221 6/4/2024
2024.1152.1 289 5/31/2024
2024.1151.1 231 5/29/2024
2024.1150.2 228 5/29/2024
2024.1150.1 222 5/29/2024
2024.1149.1 210 5/28/2024
2024.1147.1 231 5/26/2024
2024.1146.2 230 5/25/2024
2024.1146.1 229 5/25/2024
2024.1145.1 246 5/24/2024
2024.1135.2 228 5/14/2024
2024.1135.1 229 5/14/2024
2024.1134.1 233 5/13/2024
2024.1130.1 235 5/9/2024
2024.1123.1 213 5/2/2024
2024.1121.1 228 4/30/2024
2024.1114.1 230 4/22/2024
2024.1113.0.5-preview 222 4/22/2024
2024.1113.0.3-preview 230 4/22/2024
2024.1113.0.2-preview 214 4/22/2024
2024.1113.0.1-preview 220 4/22/2024
2024.1108.0.1-preview 212 4/17/2024
2024.1107.0.1-preview 212 4/16/2024
2024.1094.2 241 4/3/2024
2024.1094.1 210 4/3/2024
2024.1092.1 262 4/1/2024
2024.1088.1 263 3/28/2024
2024.1085.1 263 3/25/2024
2024.1080.2 249 3/20/2024
2024.1080.1 279 3/20/2024
2024.1078.1 229 3/18/2024
2024.1077.1 270 3/17/2024
2024.1073.1 246 3/13/2024
2024.1070.1 267 3/10/2024
2024.1069.1 269 3/9/2024
2024.1068.1 284 3/8/2024
2024.1066.2 273 3/6/2024
2024.1066.1 268 3/6/2024
2024.1065.1 255 3/5/2024
2024.1065.0.1-preview 236 3/5/2024
2024.1063.2 246 3/3/2024
2024.1063.1 278 3/3/2024
2024.1062.1 293 3/2/2024
2024.1061.2 270 3/1/2024
2024.1061.1 250 3/1/2024
2024.1060.2 261 2/29/2024
2024.1060.1 267 2/29/2024
2024.1060.0.5-preview 209 2/29/2024
2024.1060.0.3-preview 235 2/29/2024
2024.1059.0.1-preview 217 2/28/2024
2024.1058.1 265 2/27/2024
2024.1056.1 286 2/25/2024
2024.1055.1 314 2/24/2024
2024.1052.1 292 2/21/2024
2024.1050.2 320 2/20/2024
2024.1050.1 294 2/19/2024
2024.1049.1 296 2/18/2024
2024.1048.1 284 2/17/2024
2024.1047.1 290 2/16/2024
2024.1035.1 381 2/4/2024
2024.1034.2 350 2/3/2024
2024.1029.1 733 1/29/2024
2024.1023.1 744 1/23/2024
2024.1022.1 671 1/22/2024
2024.1020.1 622 1/20/2024
2024.1019.1 634 1/19/2024
2024.1017.1 640 1/17/2024
2024.1012.1 668 1/12/2024
2024.1010.1 684 1/10/2024
2024.1008.1 722 1/8/2024
2024.1007.1 757 1/7/2024
2024.1005.1 697 1/5/2024
2024.1004.1 708 1/4/2024
2023.1365.1 774 12/31/2023
2023.1362.1 692 12/28/2023
2023.1361.1 744 12/27/2023
2023.1359.1 785 12/25/2023
2023.1358.1 801 12/24/2023
2023.1357.1 645 12/23/2023
2023.1342.1 863 12/8/2023
2023.1336.1 873 12/2/2023
2023.1332.1 839 11/28/2023
2023.1330.1 796 11/26/2023
2023.1325.1 872 11/21/2023
2023.1323.1 395 11/19/2023
2023.1320.1 369 11/17/2023
2023.1318.1 833 11/15/2023
2023.1317.1 119 11/13/2023
2023.1307.1 236 11/3/2023
2023.1305.1 158 11/1/2023
2023.1304.1 125 10/31/2023
2023.1294.1 155 10/21/2023
2023.1290.1 142 10/16/2023
2023.1289.1 154 10/16/2023
2023.1284.1 163 10/11/2023
2023.1276.1 147 10/3/2023
2023.1275.1 166 10/2/2023
2023.1272.1 173 9/29/2023
2023.1269.1 152 9/26/2023
2023.1242.1 974 8/30/2023
2023.1231.1 1,065 8/19/2023
2023.1229.1 1,103 8/17/2023
2023.1228.1 1,038 8/16/2023
2023.1227.1 1,016 8/15/2023
2023.1224.2 1,060 8/12/2023
2023.1224.1 1,118 8/12/2023
2023.1213.2 1,172 8/1/2023
2023.1213.1 1,122 8/1/2023
2023.1209.1 1,134 7/27/2023
2023.1201.1 1,162 7/20/2023
2023.1197.1 1,196 7/16/2023
2023.1178.1 1,141 6/27/2023
2023.1175.1 1,164 6/24/2023
2023.1174.1 1,155 6/22/2023
2023.1169.1 1,172 6/18/2023
2023.1165.1 1,123 6/14/2023
2023.1161.1 1,167 6/11/2023
2023.1159.1 1,136 6/7/2023
2023.1157.1 1,247 6/6/2023
2023.1146.1 1,196 5/27/2023
2023.1139.1 1,210 5/19/2023
2023.1137.1 1,193 5/17/2023
2023.1136.1 1,277 5/16/2023
2023.1118.1 1,313 4/28/2023
2023.1111.1 1,253 4/21/2023
2023.1110.1 1,287 4/20/2023
2023.1105.1 1,209 4/15/2023
2023.1103.1 1,181 4/13/2023
2023.1102.1 1,332 4/12/2023
2023.1101.1 1,328 4/11/2023
2023.1090.1 1,387 3/31/2023
2023.1089.1 1,340 3/30/2023
2023.1088.1 1,294 3/29/2023
2023.1082.1 1,289 3/23/2023
2023.1078.1 1,456 3/19/2023
2023.1070.1 1,403 3/11/2023
2023.1069.1 1,320 3/10/2023
2023.1064.1 1,403 3/5/2023
2023.1060.1 1,482 3/1/2023
2023.1057.1 1,392 2/26/2023
2023.1046.1 1,466 2/15/2023
2023.1043.2 1,537 2/12/2023
2023.1043.1 1,432 2/12/2023
2023.1042.1 1,530 2/11/2023
2023.1041.1 1,460 2/10/2023
2023.1039.1 1,497 2/8/2023
2023.1036.1 1,420 2/5/2023
2023.1035.1 1,453 2/4/2023
2023.1033.1 1,545 2/2/2023
2023.1030.1 1,502 1/30/2023
2023.1028.1 1,481 1/28/2023
2023.1026.1 1,497 1/26/2023
2023.1025.1 1,468 1/25/2023
2023.1024.1 1,551 1/24/2023
2023.1023.1 1,542 1/23/2023
2022.1319.1 1,827 11/15/2022
2022.1309.1 1,879 11/5/2022
2022.1307.1 1,871 11/3/2022
2022.1295.1 1,965 10/22/2022
2022.1290.1 2,129 10/17/2022
2022.1289.2 2,033 10/16/2022
2022.1289.1 2,052 10/16/2022
2022.1283.1 2,046 10/10/2022
2022.1282.1 2,087 10/9/2022
2022.1278.1 2,061 10/5/2022
2022.1272.2 2,137 9/29/2022
2022.1272.1 2,091 9/29/2022
2022.1271.1 2,207 9/28/2022
2022.1266.1 2,287 9/23/2022
2022.1259.1 2,231 9/16/2022
2022.1257.1 2,285 9/14/2022
2022.1250.1 2,220 9/7/2022
2022.1250.0.2-preview 983 9/7/2022
2022.1249.0.2-preview 1,003 9/6/2022
2022.1249.0.1-preview 1,025 9/6/2022
2022.1197.1 1,989 7/16/2022
2022.1196.1 1,975 7/15/2022
2022.1194.1 2,100 7/13/2022
2022.1182.1 2,012 7/1/2022
2022.1178.1 2,020 6/27/2022
2022.1166.1 1,977 6/15/2022
2022.1157.1 2,043 6/6/2022
2022.1150.1 1,957 5/30/2022
2022.1149.1 1,989 5/29/2022
2022.1144.1 1,993 5/24/2022
0.6.2 2,087 5/23/2022
0.6.1 2,063 5/23/2022
0.6.0 2,065 5/14/2022
0.5.3 2,109 5/8/2022
0.5.2 2,066 5/1/2022
0.5.1 2,085 5/1/2022
0.5.0 2,128 4/23/2022
0.4.1 2,079 4/15/2022
0.4.0 2,083 4/9/2022
0.3.3 2,086 4/8/2022
0.3.2 2,117 4/1/2022
0.3.1 2,139 3/29/2022
0.3.0 2,020 3/28/2022
0.2.3 2,070 3/28/2022
0.2.2 2,029 3/25/2022
0.2.1 2,039 3/21/2022
0.2.0 1,971 3/18/2022