Ecng.Net.SocketIO 1.0.507

There is a newer version of this package available.
See the version list below for details.
dotnet add package Ecng.Net.SocketIO --version 1.0.507
                    
NuGet\Install-Package Ecng.Net.SocketIO -Version 1.0.507
                    
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="Ecng.Net.SocketIO" Version="1.0.507" />
                    
For projects that support PackageReference, copy this XML node into the project file to reference the package.
<PackageVersion Include="Ecng.Net.SocketIO" Version="1.0.507" />
                    
Directory.Packages.props
<PackageReference Include="Ecng.Net.SocketIO" />
                    
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 Ecng.Net.SocketIO --version 1.0.507
                    
#r "nuget: Ecng.Net.SocketIO, 1.0.507"
                    
#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 Ecng.Net.SocketIO@1.0.507
                    
#: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=Ecng.Net.SocketIO&version=1.0.507
                    
Install as a Cake Addin
#tool nuget:?package=Ecng.Net.SocketIO&version=1.0.507
                    
Install as a Cake Tool

Ecng.Net.SocketIO

A high-performance .NET client library for WebSocket communication with automatic reconnection, message resending, and comprehensive connection state management.

Features

  • WebSocket Client Implementation - Full-featured WebSocket client with async/await support
  • Automatic Reconnection - Configurable reconnection attempts with exponential backoff
  • Command Resending - Automatic resend of commands after reconnection
  • Connection State Tracking - Track and aggregate connection states across multiple connections
  • JSON Serialization - Built-in JSON serialization for object messages
  • Flexible Logging - Customizable logging hooks for info, error, and verbose messages
  • RestSharp Integration - Helper methods for REST API calls with authentication
  • Thread-Safe - Safe to use in multi-threaded environments

Installation

Add the package reference to your project:

<PackageReference Include="Ecng.Net.SocketIO" Version="x.x.x" />

Quick Start

Basic WebSocket Connection

using Ecng.Net;

var socket = new WebSocketClient(
    url: "wss://example.com/socket",
    stateChanged: state => Console.WriteLine($"State: {state}"),
    error: ex => Console.WriteLine($"Error: {ex.Message}"),
    process: (msg, ct) =>
    {
        Console.WriteLine($"Received: {msg.AsString()}");
        return ValueTask.CompletedTask;
    },
    infoLog: (fmt, args) => Console.WriteLine(fmt, args),
    errorLog: (fmt, args) => Console.Error.WriteLine(fmt, args),
    verboseLog: (fmt, args) => Console.WriteLine($"[VERBOSE] {fmt}", args)
);

await socket.ConnectAsync(CancellationToken.None);

Sending Messages

// Send JSON object
await socket.SendAsync(new { type = "subscribe", channel = "trades" });

// Send string
await socket.SendAsync("Hello, WebSocket!");

// Send raw bytes
byte[] data = Encoding.UTF8.GetBytes("Raw message");
await socket.SendAsync(data, WebSocketMessageType.Text);

Core Components

WebSocketClient

The main class for WebSocket communication.

Constructor Parameters
public WebSocketClient(
    string url,                              // WebSocket URL (ws:// or wss://)
    Action<ConnectionStates> stateChanged,   // Connection state change callback
    Action<Exception> error,                 // Error handler
    Func<WebSocketMessage, CancellationToken, ValueTask> process,  // Message processor
    Action<string, object> infoLog,          // Info log handler
    Action<string, object> errorLog,         // Error log handler
    Action<string, object> verboseLog        // Verbose log handler (can be null)
)
Configuration Properties
// Reconnection settings
socket.ReconnectAttempts = 10;              // -1 for infinite, 0 for no reconnect
socket.ReconnectInterval = TimeSpan.FromSeconds(5);
socket.ResendInterval = TimeSpan.FromSeconds(2);
socket.ResendTimeout = TimeSpan.FromMilliseconds(500);

// Message encoding
socket.Encoding = Encoding.UTF8;

// Buffer sizes
socket.BufferSize = 1024 * 1024;            // 1MB for compressed data
socket.BufferSizeUncompress = 10 * 1024 * 1024; // 10MB for uncompressed

// JSON serialization
socket.Indent = true;
socket.SendSettings = new JsonSerializerSettings { ... };

// Auto-resend control
socket.DisableAutoResend = false;
Connection Management
// Connect
await socket.ConnectAsync(cancellationToken);
socket.Connect(); // Synchronous version

// Disconnect
socket.Disconnect();

// Check connection state
bool isConnected = socket.IsConnected;
ConnectionStates currentState = socket.State;

// Abort connection immediately
socket.Abort();
Sending Messages with Subscription Tracking
// Send with subscription ID for automatic resend after reconnect
long subscriptionId = 12345;
await socket.SendAsync(
    obj: new { action = "subscribe", symbol = "BTCUSD" },
    subId: subscriptionId
);

// Unsubscribe (negative ID removes from resend queue)
await socket.SendAsync(
    obj: new { action = "unsubscribe", symbol = "BTCUSD" },
    subId: -subscriptionId
);

// Manual resend management
socket.RemoveResend(subscriptionId);  // Remove specific subscription
socket.RemoveResend();                 // Remove all subscriptions
Advanced Features
// Custom initialization
socket.Init += ws =>
{
    ws.Options.SetRequestHeader("X-Custom-Header", "value");
    ws.Options.KeepAliveInterval = TimeSpan.FromSeconds(30);
};

// Post-connect hook
socket.PostConnect += async (isReconnect, ct) =>
{
    if (isReconnect)
        Console.WriteLine("Reconnected! Resubscribing...");

    await Task.CompletedTask;
};

// Pre-process received data (e.g., decompression)
socket.PreProcess2 = (input, output) =>
{
    // Decompress or transform data
    input.CopyTo(output);
    return input.Length;
};

// Send ping frame
await socket.SendOpCode(0x9);

WebSocketMessage

Represents an incoming message from the WebSocket.

// In your message processor
Func<WebSocketMessage, CancellationToken, ValueTask> process = (msg, ct) =>
{
    // Get as string
    string text = msg.AsString();

    // Deserialize to object
    var trade = msg.AsObject<TradeData>();

    // Deserialize to dynamic
    dynamic data = msg.AsObject();

    // Get JSON reader for streaming
    using var reader = msg.AsReader();

    // Access raw bytes
    ReadOnlyMemory<byte> bytes = msg.Memory;

    return ValueTask.CompletedTask;
};

Connection States

The ConnectionStates enum represents the current state of the connection:

public enum ConnectionStates
{
    Disconnected,   // Not connected
    Disconnecting,  // In process of disconnecting
    Connecting,     // In process of connecting
    Connected,      // Successfully connected
    Reconnecting,   // Attempting to reconnect
    Restored,       // Connection restored after reconnect
    Failed          // Connection failed
}

ConnectionStateTracker

Track and aggregate states across multiple connections.

var tracker = new ConnectionStateTracker();

// Add connections
tracker.Add(socket1);
tracker.Add(socket2);

// Monitor overall state
tracker.StateChanged += state =>
    Console.WriteLine($"Overall state: {state}");

// Connect all
await tracker.ConnectAsync(CancellationToken.None);

// Disconnect all
tracker.Disconnect();

// Remove connections
tracker.Remove(socket1);

The tracker aggregates states with the following logic:

  • Connected: All connections are connected
  • Reconnecting: Any connection is reconnecting
  • Restored: All connections are connected or restored
  • Failed: All connections have failed
  • Disconnected: All connections are disconnected or failed

IConnection Interface

Standard interface for connection management:

public interface IConnection
{
    event Action<ConnectionStates> StateChanged;
    ValueTask ConnectAsync(CancellationToken cancellationToken);
    void Disconnect();
}

Both WebSocketClient and ConnectionStateTracker implement this interface.

RestSharp Integration

The library includes helper methods for REST API calls, often used alongside WebSocket connections.

Basic REST Request

using Ecng.Net;
using RestSharp;

var request = new RestRequest(Method.Get);
request.AddQueryParameter("symbol", "BTCUSD");

var response = await request.InvokeAsync<PriceData>(
    url: new Uri("https://api.example.com/price"),
    caller: this,
    logVerbose: (fmt, args) => Console.WriteLine(fmt, args),
    token: CancellationToken.None
);

Console.WriteLine($"Price: {response.Price}");

Authentication

// Bearer token authentication
request.SetBearer(secureToken);

// Custom authenticator
var authenticator = new MyCustomAuthenticator();
var response = await request.InvokeAsync2<Data>(
    url: apiUrl,
    caller: this,
    logVerbose: logger,
    token: cancellationToken,
    auth: authenticator
);

Error Handling

try
{
    var response = await request.InvokeAsync<Data>(url, this, logger, token);
}
catch (RestSharpException ex)
{
    Console.WriteLine($"HTTP {ex.Response.StatusCode}: {ex.Response.Content}");
    Console.WriteLine($"Error: {ex.Message}");
}

Advanced REST Features

// Custom content converter
var response = await request.InvokeAsync<Data>(
    url: apiUrl,
    caller: this,
    logVerbose: logger,
    token: cancellationToken,
    contentConverter: content => content.Replace("null", "\"\"")
);

// Handle specific error status codes
var response = await request.InvokeAsync3<Data>(
    url: apiUrl,
    caller: this,
    logVerbose: logger,
    token: cancellationToken,
    handleErrorStatus: statusCode =>
    {
        if (statusCode == HttpStatusCode.TooManyRequests)
        {
            // Custom handling
            return true; // Handled
        }
        return false; // Not handled, will throw
    }
);

// Add body as string
request.AddBodyAsStr("{\"key\": \"value\"}");

// Remove parameters
request.RemoveWhere(p => p.Name == "old_param");

// Convert parameters to query string
string queryString = request.Parameters.ToQueryString();

JWT Decoding

string token = "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...";
var parts = token.DecodeJWT();

foreach (var part in parts)
{
    Console.WriteLine(part);
}

Complete Examples

Crypto Exchange WebSocket Client

public class CryptoExchangeClient : IDisposable
{
    private readonly WebSocketClient _socket;
    private long _subscriptionCounter;

    public CryptoExchangeClient(string wsUrl)
    {
        _socket = new WebSocketClient(
            url: wsUrl,
            stateChanged: OnStateChanged,
            error: OnError,
            process: ProcessMessage,
            infoLog: (fmt, args) => Console.WriteLine($"[INFO] {fmt}", args),
            errorLog: (fmt, args) => Console.Error.WriteLine($"[ERROR] {fmt}", args),
            verboseLog: null
        )
        {
            ReconnectAttempts = -1,  // Infinite reconnection
            ReconnectInterval = TimeSpan.FromSeconds(5),
            ResendTimeout = TimeSpan.FromSeconds(1)
        };

        _socket.Init += ws =>
        {
            ws.Options.KeepAliveInterval = TimeSpan.FromSeconds(20);
        };

        _socket.PostConnect += async (isReconnect, ct) =>
        {
            if (isReconnect)
            {
                Console.WriteLine("Reconnected! Subscriptions will be restored automatically.");
            }
        };
    }

    public async Task ConnectAsync()
    {
        await _socket.ConnectAsync(CancellationToken.None);
    }

    public async Task SubscribeToTradesAsync(string symbol)
    {
        var subId = ++_subscriptionCounter;

        await _socket.SendAsync(
            obj: new
            {
                type = "subscribe",
                channel = "trades",
                symbol = symbol
            },
            subId: subId
        );

        Console.WriteLine($"Subscribed to {symbol} trades (ID: {subId})");
    }

    public async Task UnsubscribeFromTradesAsync(long subscriptionId, string symbol)
    {
        await _socket.SendAsync(
            obj: new
            {
                type = "unsubscribe",
                channel = "trades",
                symbol = symbol
            },
            subId: -subscriptionId  // Negative to remove from resend queue
        );
    }

    private void OnStateChanged(ConnectionStates state)
    {
        Console.WriteLine($"Connection state: {state}");

        if (state == ConnectionStates.Connected)
        {
            // Connection established
        }
        else if (state == ConnectionStates.Restored)
        {
            // Connection restored after disconnect
        }
        else if (state == ConnectionStates.Failed)
        {
            // Connection failed after all retry attempts
        }
    }

    private void OnError(Exception ex)
    {
        Console.Error.WriteLine($"WebSocket error: {ex}");
    }

    private async ValueTask ProcessMessage(WebSocketMessage msg, CancellationToken ct)
    {
        try
        {
            var message = msg.AsObject<dynamic>();

            if (message.type == "trade")
            {
                Console.WriteLine($"Trade: {message.symbol} @ {message.price}");
            }
            else if (message.type == "error")
            {
                Console.Error.WriteLine($"Server error: {message.message}");
            }
        }
        catch (Exception ex)
        {
            Console.Error.WriteLine($"Error processing message: {ex.Message}");
        }

        await ValueTask.CompletedTask;
    }

    public void Dispose()
    {
        _socket?.Disconnect();
        _socket?.Dispose();
    }
}

// Usage
await using var client = new CryptoExchangeClient("wss://api.exchange.com/ws");
await client.ConnectAsync();
await client.SubscribeToTradesAsync("BTCUSD");

// Keep running
await Task.Delay(Timeout.Infinite);

Multi-Connection Manager

public class MultiExchangeClient
{
    private readonly ConnectionStateTracker _tracker;
    private readonly WebSocketClient _exchangeA;
    private readonly WebSocketClient _exchangeB;

    public MultiExchangeClient()
    {
        _tracker = new ConnectionStateTracker();

        _exchangeA = CreateClient("wss://exchange-a.com/ws", "Exchange A");
        _exchangeB = CreateClient("wss://exchange-b.com/ws", "Exchange B");

        _tracker.Add(_exchangeA);
        _tracker.Add(_exchangeB);

        _tracker.StateChanged += state =>
        {
            Console.WriteLine($"Overall connection state: {state}");

            if (state == ConnectionStates.Connected)
            {
                Console.WriteLine("All exchanges connected!");
            }
        };
    }

    private WebSocketClient CreateClient(string url, string name)
    {
        return new WebSocketClient(
            url: url,
            stateChanged: state => Console.WriteLine($"{name}: {state}"),
            error: ex => Console.Error.WriteLine($"{name} error: {ex.Message}"),
            process: (msg, ct) =>
            {
                Console.WriteLine($"{name}: {msg.AsString()}");
                return ValueTask.CompletedTask;
            },
            infoLog: (fmt, args) => Console.WriteLine($"[{name}] {fmt}", args),
            errorLog: (fmt, args) => Console.Error.WriteLine($"[{name}] {fmt}", args),
            verboseLog: null
        )
        {
            ReconnectAttempts = 5,
            ReconnectInterval = TimeSpan.FromSeconds(3)
        };
    }

    public async Task ConnectAllAsync()
    {
        await _tracker.ConnectAsync(CancellationToken.None);
    }

    public void DisconnectAll()
    {
        _tracker.Disconnect();
    }
}

WebSocket with REST API Integration

public class TradingClient
{
    private readonly WebSocketClient _wsClient;
    private readonly Uri _restApiUrl;

    public TradingClient(string wsUrl, string restUrl)
    {
        _restApiUrl = new Uri(restUrl);
        _wsClient = new WebSocketClient(
            url: wsUrl,
            stateChanged: state => Console.WriteLine($"WS State: {state}"),
            error: ex => Console.Error.WriteLine($"WS Error: {ex}"),
            process: ProcessWebSocketMessage,
            infoLog: (fmt, args) => Console.WriteLine(fmt, args),
            errorLog: (fmt, args) => Console.Error.WriteLine(fmt, args),
            verboseLog: null
        );
    }

    public async Task<AccountInfo> GetAccountInfoAsync()
    {
        var request = new RestRequest("/account", Method.Get);
        request.SetBearer(GetAuthToken());

        try
        {
            var account = await request.InvokeAsync<AccountInfo>(
                url: new Uri(_restApiUrl, request.Resource),
                caller: this,
                logVerbose: (fmt, args) => Console.WriteLine(fmt, args),
                token: CancellationToken.None
            );

            return account;
        }
        catch (RestSharpException ex)
        {
            Console.Error.WriteLine($"REST API Error: {ex.Message}");
            Console.Error.WriteLine($"Status: {ex.Response.StatusCode}");
            Console.Error.WriteLine($"Content: {ex.Response.Content}");
            throw;
        }
    }

    public async Task PlaceOrderAsync(string symbol, decimal price, decimal quantity)
    {
        var request = new RestRequest("/orders", Method.Post);
        request.SetBearer(GetAuthToken());
        request.AddBodyAsStr(new
        {
            symbol = symbol,
            price = price,
            quantity = quantity
        }.ToJson());

        var order = await request.InvokeAsync<Order>(
            url: new Uri(_restApiUrl, request.Resource),
            caller: this,
            logVerbose: (fmt, args) => Console.WriteLine(fmt, args),
            token: CancellationToken.None
        );

        Console.WriteLine($"Order placed: {order.Id}");
    }

    private async ValueTask ProcessWebSocketMessage(WebSocketMessage msg, CancellationToken ct)
    {
        var data = msg.AsObject<dynamic>();

        if (data.type == "order_update")
        {
            Console.WriteLine($"Order {data.orderId} status: {data.status}");
        }

        await ValueTask.CompletedTask;
    }

    private SecureString GetAuthToken()
    {
        // Return your authentication token
        throw new NotImplementedException();
    }
}

Best Practices

  1. Always handle errors: Provide error handlers to catch and log exceptions.

  2. Configure reconnection: Set appropriate reconnection attempts and intervals based on your use case.

  3. Use subscription IDs: Track subscriptions with IDs for automatic resend after reconnection.

  4. Monitor connection states: React to state changes to update your UI or trigger business logic.

  5. Dispose properly: Always dispose of WebSocketClient when done to clean up resources.

  6. Use async/await: Prefer async methods for better scalability.

  7. Implement backoff: Use increasing reconnection intervals to avoid overwhelming the server.

  8. Log appropriately: Use different log levels (info, error, verbose) for debugging and monitoring.

Thread Safety

The WebSocketClient class is designed to be thread-safe for the following operations:

  • Sending messages
  • Connection/disconnection
  • State management
  • Subscription tracking

However, you should not share a single WebSocketMessage instance across threads, as it contains read-only memory references.

Performance Considerations

  • Buffer Sizes: Adjust BufferSize and BufferSizeUncompress based on your message sizes.
  • Resend Interval: Lower intervals increase network traffic; higher intervals delay recovery.
  • Reconnect Attempts: Balance between reliability and resource usage.
  • Verbose Logging: Disable in production for better performance.

License

This library is part of the Ecng framework.

Support

For issues, questions, or contributions, please refer to the main StockSharp repository.

Product Compatible and additional computed target framework versions.
.NET net6.0 is compatible.  net6.0-android was computed.  net6.0-ios was computed.  net6.0-maccatalyst was computed.  net6.0-macos was computed.  net6.0-tvos was computed.  net6.0-windows was computed.  net7.0 was computed.  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.  net9.0 was computed.  net9.0-android was computed.  net9.0-browser was computed.  net9.0-ios was computed.  net9.0-maccatalyst was computed.  net9.0-macos was computed.  net9.0-tvos was computed.  net9.0-windows was computed.  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 (6)

Showing the top 5 NuGet packages that depend on Ecng.Net.SocketIO:

Package Downloads
StockSharp.AlphaVantage

AlphaVantage

StockSharp.IEX

Trading and algorithmic trading platform (stock markets, forex, bitcoins and options). .NET API for InteractiveBrokers, GainCapital, OANDA, FIX/FAST, Binance etc. More info on web site https://stocksharp.com/store/api/

StockSharp.Binance

Binance

StockSharp.Okex

OKX connector

StockSharp.Bitmex

Bitmex

GitHub repositories (1)

Showing the top 1 popular GitHub repositories that depend on Ecng.Net.SocketIO:

Repository Stars
StockSharp/StockSharp
Algorithmic trading and quantitative trading open source platform to develop trading robots (stock markets, forex, crypto, bitcoins, and options).
Version Downloads Last Updated
1.0.512 58 1/9/2026
1.0.511 53 1/9/2026
1.0.510 40 1/8/2026
1.0.509 43 1/8/2026
1.0.508 42 1/7/2026
1.0.507 84 1/6/2026
1.0.506 80 1/6/2026
1.0.505 92 1/5/2026
1.0.504 104 1/4/2026
1.0.503 107 1/1/2026
1.0.502 96 12/31/2025
1.0.501 97 12/30/2025
1.0.500 90 12/30/2025
1.0.499 100 12/29/2025
1.0.498 96 12/29/2025
1.0.497 100 12/26/2025
1.0.496 93 12/26/2025
1.0.495 90 12/26/2025
1.0.494 111 12/26/2025
1.0.493 182 12/25/2025
1.0.492 186 12/25/2025
1.0.491 194 12/24/2025
1.0.490 189 12/23/2025
1.0.489 179 12/22/2025
1.0.488 177 12/22/2025
1.0.487 185 12/22/2025
1.0.486 169 12/21/2025
1.0.485 226 12/19/2025
1.0.484 244 12/19/2025
1.0.483 290 12/18/2025
1.0.482 288 12/17/2025
1.0.481 289 12/15/2025
1.0.480 262 12/15/2025
1.0.479 242 12/14/2025
1.0.478 166 12/14/2025
1.0.477 166 12/13/2025
1.0.476 185 12/13/2025
1.0.475 152 12/12/2025
1.0.474 135 12/12/2025
1.0.473 125 12/12/2025
1.0.472 131 12/12/2025
1.0.471 125 12/12/2025
1.0.470 129 12/12/2025
1.0.469 129 12/12/2025
1.0.468 733 12/2/2025
1.0.467 688 12/2/2025
1.0.466 686 12/2/2025
1.0.465 286 11/30/2025
1.0.464 156 11/29/2025
1.0.463 149 11/28/2025
1.0.462 157 11/28/2025
1.0.461 201 11/27/2025
1.0.460 240 11/24/2025
1.0.459 212 11/24/2025
1.0.458 210 11/23/2025
1.0.457 181 11/23/2025
1.0.456 235 11/22/2025
1.0.455 447 11/20/2025
1.0.454 423 11/20/2025
1.0.453 420 11/20/2025
1.0.452 444 11/18/2025
1.0.451 422 11/18/2025
1.0.450 349 11/13/2025
1.0.449 289 11/10/2025
1.0.448 1,109 11/1/2025
1.0.447 217 10/31/2025
1.0.446 225 10/28/2025
1.0.445 343 10/27/2025
1.0.444 214 10/27/2025
1.0.443 143 10/25/2025
1.0.442 173 10/24/2025
1.0.441 281 10/20/2025
1.0.440 314 10/12/2025
1.0.439 164 10/11/2025
1.0.438 299 10/7/2025
1.0.437 241 10/6/2025
1.0.436 282 10/3/2025
1.0.435 252 10/1/2025
1.0.434 223 10/1/2025
1.0.433 222 9/30/2025
1.0.432 226 9/28/2025
1.0.431 244 9/25/2025
1.0.430 3,141 9/5/2025
1.0.429 256 9/2/2025
1.0.428 608 8/30/2025
1.0.427 279 8/30/2025
1.0.426 279 8/20/2025
1.0.425 224 8/20/2025
1.0.424 236 8/19/2025
1.0.423 245 8/15/2025
1.0.422 337 8/10/2025
1.0.421 1,060 7/16/2025
1.0.420 292 7/14/2025
1.0.419 265 7/13/2025
1.0.418 241 7/13/2025
1.0.417 215 7/12/2025
1.0.416 712 7/8/2025
1.0.415 275 7/4/2025
1.0.414 271 7/2/2025
1.0.413 434 6/24/2025
1.0.412 1,042 6/16/2025
1.0.411 424 6/9/2025
1.0.410 303 6/8/2025
1.0.409 626 5/21/2025
1.0.408 271 5/21/2025
1.0.407 261 5/17/2025
1.0.406 662 5/12/2025
1.0.405 360 5/12/2025
1.0.404 329 5/12/2025
1.0.403 252 5/11/2025
1.0.402 261 5/11/2025
1.0.401 216 5/10/2025
1.0.400 178 5/10/2025
1.0.399 305 5/6/2025
1.0.398 230 5/3/2025
1.0.397 394 4/17/2025
1.0.396 343 4/15/2025
1.0.395 243 4/12/2025
1.0.394 319 4/9/2025
1.0.393 279 4/6/2025
1.0.392 231 4/5/2025
1.0.391 1,106 3/22/2025
1.0.390 301 3/20/2025
1.0.389 293 3/20/2025
1.0.388 279 3/19/2025
1.0.387 850 2/26/2025
1.0.386 258 2/26/2025
1.0.385 780 2/8/2025
1.0.384 259 2/8/2025
1.0.383 237 2/8/2025
1.0.382 235 2/6/2025
1.0.381 224 2/6/2025
1.0.380 243 2/6/2025
1.0.379 251 2/6/2025
1.0.378 226 2/6/2025
1.0.377 228 2/5/2025
1.0.376 233 2/5/2025
1.0.375 251 2/5/2025
1.0.374 273 2/3/2025
1.0.373 256 2/2/2025
1.0.372 274 2/1/2025
1.0.371 256 1/31/2025
1.0.370 261 1/30/2025
1.0.369 245 1/26/2025
1.0.368 276 1/21/2025
1.0.367 262 1/20/2025
1.0.366 227 1/20/2025
1.0.365 243 1/19/2025
1.0.364 233 1/19/2025
1.0.363 257 1/15/2025
1.0.362 228 1/15/2025
1.0.361 221 1/14/2025
1.0.360 214 1/12/2025
1.0.359 205 1/12/2025
1.0.358 221 1/12/2025
1.0.357 188 1/12/2025
1.0.356 243 1/10/2025
1.0.355 1,076 12/30/2024
1.0.354 264 12/27/2024
1.0.353 286 12/19/2024
1.0.352 751 11/20/2024
1.0.351 262 11/19/2024
1.0.350 244 11/19/2024
1.0.349 806 11/18/2024
1.0.348 480 11/15/2024
1.0.347 230 11/14/2024
1.0.346 255 11/14/2024
1.0.345 259 11/14/2024
1.0.344 210 11/14/2024
1.0.343 236 11/14/2024
1.0.342 279 11/7/2024
1.0.341 289 10/31/2024
1.0.340 345 10/20/2024
1.0.339 269 10/20/2024
1.0.338 281 10/20/2024
1.0.337 273 10/19/2024
1.0.336 288 10/19/2024
1.0.335 287 10/19/2024
1.0.334 282 10/19/2024
1.0.333 281 10/19/2024
1.0.332 264 10/19/2024
1.0.331 291 10/19/2024
1.0.330 319 10/18/2024
1.0.329 276 10/17/2024
1.0.328 238 10/17/2024
1.0.327 260 10/17/2024
1.0.326 815 10/14/2024
1.0.325 240 10/13/2024
1.0.324 241 10/13/2024
1.0.323 259 10/12/2024
1.0.322 453 10/9/2024
1.0.321 260 10/9/2024
1.0.320 454 10/5/2024
1.0.319 783 9/18/2024
1.0.318 241 9/18/2024
1.0.317 261 9/18/2024
1.0.316 256 9/17/2024
1.0.315 753 9/3/2024
1.0.314 301 9/1/2024
1.0.313 969 8/9/2024
1.0.312 258 8/9/2024
1.0.311 278 8/8/2024
1.0.310 719 7/25/2024
1.0.309 278 7/23/2024
1.0.308 297 7/17/2024
1.0.307 568 7/4/2024
1.0.306 626 6/12/2024
1.0.305 267 6/12/2024
1.0.304 265 6/12/2024
1.0.303 458 5/28/2024
1.0.302 623 5/4/2024
1.0.301 417 4/23/2024
1.0.300 279 4/21/2024
1.0.299 306 4/14/2024
1.0.298 571 3/28/2024
1.0.297 345 3/17/2024
1.0.296 546 3/9/2024
1.0.295 362 2/23/2024
1.0.294 292 2/23/2024
1.0.293 502 2/18/2024
1.0.292 292 2/18/2024
1.0.291 267 2/17/2024
1.0.290 286 2/16/2024
1.0.289 407 2/14/2024
1.0.288 287 2/13/2024
1.0.287 357 2/8/2024
1.0.286 361 2/5/2024
1.0.285 278 2/4/2024
1.0.284 449 1/23/2024
1.0.283 269 1/23/2024
1.0.282 338 1/12/2024
1.0.281 705 1/2/2024
1.0.280 320 12/29/2023
1.0.279 372 12/17/2023
1.0.278 527 12/15/2023
1.0.277 295 12/15/2023
1.0.276 277 12/15/2023
1.0.275 310 12/13/2023
1.0.274 306 12/13/2023
1.0.273 311 12/10/2023
1.0.272 688 11/18/2023
1.0.271 232 11/18/2023
1.0.270 259 11/18/2023
1.0.269 241 11/17/2023
1.0.268 214 11/12/2023
1.0.267 216 11/12/2023
1.0.266 238 11/10/2023
1.0.265 201 11/10/2023
1.0.264 241 11/9/2023
1.0.263 201 11/9/2023
1.0.262 221 11/9/2023
1.0.261 247 11/3/2023
1.0.260 232 11/1/2023
1.0.259 217 11/1/2023
1.0.258 1,479 9/8/2023
1.0.257 273 9/8/2023
1.0.256 287 9/3/2023
1.0.255 353 8/27/2023
1.0.254 282 8/24/2023
1.0.253 248 8/21/2023
1.0.252 322 8/15/2023
1.0.251 291 8/14/2023
1.0.250 270 8/14/2023
1.0.249 303 8/10/2023
1.0.248 1,020 7/29/2023
1.0.247 1,098 7/1/2023
1.0.246 314 6/29/2023
1.0.245 806 5/27/2023
1.0.244 359 5/21/2023
1.0.243 301 5/19/2023
1.0.242 1,089 5/8/2023
1.0.241 359 5/7/2023
1.0.240 346 5/7/2023
1.0.239 326 5/7/2023
1.0.238 375 5/1/2023
1.0.237 419 4/22/2023
1.0.236 378 4/21/2023
1.0.235 345 4/21/2023
1.0.234 1,241 4/13/2023
1.0.233 1,139 4/3/2023
1.0.232 492 3/27/2023
1.0.231 438 3/21/2023
1.0.230 439 3/17/2023
1.0.229 435 3/13/2023
1.0.228 1,188 3/6/2023
1.0.227 502 2/26/2023
1.0.226 944 2/21/2023
1.0.225 460 2/20/2023
1.0.224 475 2/16/2023
1.0.223 462 2/15/2023
1.0.222 436 2/14/2023
1.0.221 433 2/14/2023
1.0.220 1,362 2/9/2023
1.0.219 837 2/7/2023
1.0.218 491 2/4/2023
1.0.217 476 2/4/2023
1.0.216 490 2/3/2023
1.0.215 449 2/3/2023
1.0.214 448 2/3/2023
1.0.213 891 2/2/2023
1.0.212 840 1/30/2023
1.0.211 473 1/30/2023
1.0.210 514 1/25/2023
1.0.209 508 1/23/2023
1.0.208 459 1/23/2023
1.0.207 494 1/18/2023
1.0.206 520 1/15/2023
1.0.205 520 1/6/2023
1.0.204 1,422 1/1/2023
1.0.203 488 12/31/2022
1.0.202 974 12/30/2022
1.0.201 506 12/29/2022
1.0.200 516 12/23/2022
1.0.199 1,396 12/12/2022
1.0.198 1,075 12/8/2022
1.0.197 492 12/4/2022
1.0.196 495 12/4/2022
1.0.195 500 12/2/2022
1.0.194 523 11/30/2022
1.0.193 485 11/29/2022
1.0.192 481 11/28/2022
1.0.191 526 11/26/2022
1.0.190 520 11/26/2022
1.0.189 520 11/25/2022
1.0.188 521 11/25/2022
1.0.187 534 11/18/2022
1.0.186 1,603 11/11/2022
1.0.185 557 11/11/2022
1.0.184 514 11/10/2022
1.0.183 576 11/5/2022
1.0.182 555 11/4/2022
1.0.181 536 11/2/2022
1.0.180 526 11/2/2022
1.0.179 1,438 11/1/2022
1.0.178 1,663 10/16/2022
1.0.177 748 9/25/2022
1.0.176 678 9/10/2022
1.0.175 2,987 9/8/2022
1.0.174 659 9/8/2022
1.0.173 664 9/8/2022
1.0.172 640 9/4/2022
1.0.171 639 9/4/2022
1.0.170 5,359 8/24/2022
1.0.169 722 8/8/2022
1.0.168 646 8/8/2022
1.0.167 1,274 7/31/2022
1.0.166 660 7/31/2022
1.0.165 671 7/26/2022
1.0.164 639 7/26/2022
1.0.163 3,207 7/21/2022
1.0.162 695 7/19/2022
1.0.161 3,164 7/18/2022
1.0.160 698 7/13/2022
1.0.159 680 7/8/2022
1.0.158 702 6/30/2022
1.0.157 713 6/20/2022
1.0.156 664 6/18/2022
1.0.155 706 6/6/2022
1.0.154 753 5/27/2022
1.0.153 5,219 4/30/2022
1.0.152 691 4/20/2022
1.0.151 722 4/10/2022
1.0.150 690 4/7/2022
1.0.149 669 4/7/2022
1.0.148 727 4/2/2022
1.0.147 684 3/29/2022
1.0.146 673 3/27/2022
1.0.145 674 3/27/2022
1.0.144 3,927 3/24/2022
1.0.143 2,691 2/20/2022
1.0.142 650 2/20/2022
1.0.141 660 2/20/2022
1.0.140 691 2/20/2022
1.0.139 711 2/20/2022
1.0.138 676 2/20/2022
1.0.137 667 2/20/2022
1.0.136 688 2/20/2022
1.0.135 690 2/20/2022
1.0.134 679 2/19/2022
1.0.133 4,573 2/10/2022
1.0.132 784 1/27/2022
1.0.131 713 1/27/2022
1.0.130 3,574 1/24/2022
1.0.129 661 1/24/2022
1.0.128 700 1/23/2022
1.0.127 7,025 12/29/2021
1.0.126 550 12/27/2021
1.0.125 491 12/27/2021
1.0.124 514 12/27/2021
1.0.123 1,771 12/20/2021
1.0.122 555 12/17/2021
1.0.121 545 12/16/2021
1.0.120 526 12/15/2021
1.0.119 516 12/14/2021
1.0.118 539 12/14/2021
1.0.117 500 12/13/2021
1.0.116 662 12/12/2021
1.0.115 1,637 12/10/2021
1.0.114 549 12/7/2021
1.0.113 547 12/7/2021
1.0.112 1,982 12/6/2021
1.0.111 544 12/6/2021
1.0.110 550 12/5/2021
1.0.109 1,242 12/3/2021
1.0.108 1,047 12/3/2021
1.0.107 582 12/2/2021
1.0.106 2,463 11/29/2021
1.0.105 5,273 11/23/2021
1.0.104 537 11/23/2021
1.0.103 1,621 11/22/2021
1.0.102 633 11/17/2021
1.0.101 587 11/14/2021
1.0.100 1,755 11/13/2021
1.0.99 602 11/11/2021
1.0.98 581 11/11/2021
1.0.97 566 11/10/2021
1.0.96 576 11/9/2021
1.0.95 2,609 11/6/2021
1.0.94 610 11/6/2021
1.0.93 2,175 11/5/2021
1.0.92 635 11/5/2021
1.0.91 593 11/4/2021
1.0.90 565 11/4/2021
1.0.89 626 11/3/2021
1.0.88 690 10/30/2021
1.0.87 2,054 10/21/2021
1.0.86 659 10/17/2021
1.0.85 670 10/17/2021
1.0.84 3,058 10/14/2021
1.0.83 597 10/13/2021
1.0.82 612 10/13/2021
1.0.81 593 10/12/2021
1.0.80 2,148 10/11/2021
1.0.79 575 10/9/2021
1.0.78 1,958 10/7/2021
1.0.77 2,158 10/7/2021
1.0.76 575 10/7/2021
1.0.75 607 10/6/2021
1.0.74 662 9/28/2021
1.0.73 2,372 9/23/2021
1.0.72 709 9/11/2021
1.0.71 612 9/10/2021
1.0.70 677 9/9/2021
1.0.69 578 9/8/2021
1.0.68 638 9/8/2021
1.0.67 2,165 9/6/2021
1.0.66 709 8/31/2021
1.0.65 569 8/30/2021
1.0.64 2,620 7/31/2021
1.0.63 3,050 7/30/2021
1.0.62 690 7/26/2021
1.0.61 4,488 7/5/2021
1.0.60 645 7/1/2021
1.0.59 3,830 6/4/2021
1.0.58 5,078 4/26/2021
1.0.57 2,188 4/19/2021
1.0.56 5,733 4/8/2021
1.0.55 1,812 4/7/2021
1.0.54 627 4/7/2021
1.0.53 1,893 4/3/2021
1.0.52 7,991 3/22/2021
1.0.51 5,780 3/4/2021
1.0.50 2,165 2/26/2021
1.0.49 8,284 2/2/2021
1.0.48 3,236 1/26/2021
1.0.47 3,005 1/24/2021
1.0.46 664 1/24/2021
1.0.45 719 1/23/2021
1.0.44 3,909 1/20/2021
1.0.43 721 1/20/2021
1.0.42 2,092 1/18/2021
1.0.41 637 1/18/2021
1.0.40 2,069 1/16/2021
1.0.39 6,321 12/17/2020
1.0.38 700 12/16/2020
1.0.37 3,222 12/14/2020
1.0.36 2,131 12/9/2020
1.0.35 681 12/9/2020
1.0.34 690 12/7/2020
1.0.33 796 12/6/2020
1.0.32 745 12/2/2020
1.0.31 714 12/2/2020
1.0.30 2,213 12/1/2020
1.0.29 7,373 11/12/2020
1.0.29-atestpub 570 11/11/2020
1.0.28 3,350 10/11/2020
1.0.27 8,622 9/9/2020
1.0.26 2,638 9/3/2020
1.0.25 2,695 8/20/2020
1.0.24 6,168 8/9/2020
1.0.23 2,711 7/28/2020
1.0.22 2,652 7/19/2020
1.0.21 4,465 7/6/2020
1.0.20 6,633 6/6/2020
1.0.19 2,624 6/4/2020
1.0.18 4,392 5/29/2020
1.0.17 4,430 5/21/2020
1.0.16 770 5/17/2020
1.0.15 4,526 5/12/2020
1.0.14 8,246 5/4/2020
1.0.13 794 4/24/2020
1.0.12 782 4/22/2020
1.0.11 761 4/22/2020
1.0.10 783 4/21/2020
1.0.9 3,232 4/18/2020
1.0.8 2,588 4/16/2020
1.0.7 792 4/16/2020
1.0.6 2,264 4/15/2020
1.0.5 2,675 4/11/2020
1.0.4 2,568 4/3/2020
1.0.3 785 4/1/2020
1.0.2 2,496 3/27/2020
1.0.1 2,610 3/22/2020
1.0.0 896 3/22/2020