Ecng.Net.SocketIO 1.0.509

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.509
                    
NuGet\Install-Package Ecng.Net.SocketIO -Version 1.0.509
                    
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.509" />
                    
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.509" />
                    
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.509
                    
#r "nuget: Ecng.Net.SocketIO, 1.0.509"
                    
#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.509
                    
#: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.509
                    
Install as a Cake Addin
#tool nuget:?package=Ecng.Net.SocketIO&version=1.0.509
                    
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.516 42 1/14/2026
1.0.515 48 1/13/2026
1.0.514 45 1/13/2026
1.0.513 57 1/12/2026
1.0.512 90 1/9/2026
1.0.511 71 1/9/2026
1.0.510 58 1/8/2026
1.0.509 61 1/8/2026
1.0.508 60 1/7/2026
1.0.507 92 1/6/2026
1.0.506 88 1/6/2026
1.0.505 94 1/5/2026
1.0.504 106 1/4/2026
1.0.503 109 1/1/2026
1.0.502 98 12/31/2025
1.0.501 99 12/30/2025
1.0.500 92 12/30/2025
1.0.499 102 12/29/2025
1.0.498 98 12/29/2025
1.0.497 102 12/26/2025
1.0.496 95 12/26/2025
1.0.495 92 12/26/2025
1.0.494 113 12/26/2025
1.0.493 184 12/25/2025
1.0.492 188 12/25/2025
1.0.491 196 12/24/2025
1.0.490 191 12/23/2025
1.0.489 181 12/22/2025
1.0.488 179 12/22/2025
1.0.487 187 12/22/2025
1.0.486 171 12/21/2025
1.0.485 228 12/19/2025
1.0.484 247 12/19/2025
1.0.483 292 12/18/2025
1.0.482 290 12/17/2025
1.0.481 291 12/15/2025
1.0.480 264 12/15/2025
1.0.479 245 12/14/2025
1.0.478 169 12/14/2025
1.0.477 168 12/13/2025
1.0.476 188 12/13/2025
1.0.475 155 12/12/2025
1.0.474 139 12/12/2025
1.0.473 128 12/12/2025
1.0.472 135 12/12/2025
1.0.471 128 12/12/2025
1.0.470 132 12/12/2025
1.0.469 132 12/12/2025
1.0.468 735 12/2/2025
1.0.467 691 12/2/2025
1.0.466 688 12/2/2025
1.0.465 288 11/30/2025
1.0.464 159 11/29/2025
1.0.463 152 11/28/2025
1.0.462 160 11/28/2025
1.0.461 204 11/27/2025
1.0.460 244 11/24/2025
1.0.459 214 11/24/2025
1.0.458 212 11/23/2025
1.0.457 184 11/23/2025
1.0.456 239 11/22/2025
1.0.455 449 11/20/2025
1.0.454 426 11/20/2025
1.0.453 423 11/20/2025
1.0.452 448 11/18/2025
1.0.451 424 11/18/2025
1.0.450 352 11/13/2025
1.0.449 292 11/10/2025
1.0.448 1,112 11/1/2025
1.0.447 221 10/31/2025
1.0.446 227 10/28/2025
1.0.445 347 10/27/2025
1.0.444 217 10/27/2025
1.0.443 145 10/25/2025
1.0.442 176 10/24/2025
1.0.441 284 10/20/2025
1.0.440 317 10/12/2025
1.0.439 166 10/11/2025
1.0.438 301 10/7/2025
1.0.437 243 10/6/2025
1.0.436 285 10/3/2025
1.0.435 255 10/1/2025
1.0.434 226 10/1/2025
1.0.433 225 9/30/2025
1.0.432 230 9/28/2025
1.0.431 246 9/25/2025
1.0.430 3,175 9/5/2025
1.0.429 258 9/2/2025
1.0.428 611 8/30/2025
1.0.427 282 8/30/2025
1.0.426 281 8/20/2025
1.0.425 227 8/20/2025
1.0.424 239 8/19/2025
1.0.423 249 8/15/2025
1.0.422 341 8/10/2025
1.0.421 1,062 7/16/2025
1.0.420 295 7/14/2025
1.0.419 267 7/13/2025
1.0.418 244 7/13/2025
1.0.417 219 7/12/2025
1.0.416 726 7/8/2025
1.0.415 278 7/4/2025
1.0.414 274 7/2/2025
1.0.413 437 6/24/2025
1.0.412 1,044 6/16/2025
1.0.411 428 6/9/2025
1.0.410 306 6/8/2025
1.0.409 629 5/21/2025
1.0.408 274 5/21/2025
1.0.407 263 5/17/2025
1.0.406 665 5/12/2025
1.0.405 363 5/12/2025
1.0.404 331 5/12/2025
1.0.403 254 5/11/2025
1.0.402 264 5/11/2025
1.0.401 219 5/10/2025
1.0.400 181 5/10/2025
1.0.399 307 5/6/2025
1.0.398 233 5/3/2025
1.0.397 397 4/17/2025
1.0.396 346 4/15/2025
1.0.395 246 4/12/2025
1.0.394 322 4/9/2025
1.0.393 281 4/6/2025
1.0.392 235 4/5/2025
1.0.391 1,110 3/22/2025
1.0.390 305 3/20/2025
1.0.389 295 3/20/2025
1.0.388 282 3/19/2025
1.0.387 852 2/26/2025
1.0.386 260 2/26/2025
1.0.385 782 2/8/2025
1.0.384 261 2/8/2025
1.0.383 240 2/8/2025
1.0.382 238 2/6/2025
1.0.381 227 2/6/2025
1.0.380 246 2/6/2025
1.0.379 254 2/6/2025
1.0.378 229 2/6/2025
1.0.377 231 2/5/2025
1.0.376 235 2/5/2025
1.0.375 253 2/5/2025
1.0.374 277 2/3/2025
1.0.373 260 2/2/2025
1.0.372 278 2/1/2025
1.0.371 260 1/31/2025
1.0.370 264 1/30/2025
1.0.369 248 1/26/2025
1.0.368 278 1/21/2025
1.0.367 264 1/20/2025
1.0.366 229 1/20/2025
1.0.365 246 1/19/2025
1.0.364 237 1/19/2025
1.0.363 260 1/15/2025
1.0.362 230 1/15/2025
1.0.361 223 1/14/2025
1.0.360 218 1/12/2025
1.0.359 207 1/12/2025
1.0.358 223 1/12/2025
1.0.357 190 1/12/2025
1.0.356 246 1/10/2025
1.0.355 1,080 12/30/2024
1.0.354 268 12/27/2024
1.0.353 288 12/19/2024
1.0.352 754 11/20/2024
1.0.351 265 11/19/2024
1.0.350 246 11/19/2024
1.0.349 808 11/18/2024
1.0.348 482 11/15/2024
1.0.347 232 11/14/2024
1.0.346 257 11/14/2024
1.0.345 262 11/14/2024
1.0.344 212 11/14/2024
1.0.343 240 11/14/2024
1.0.342 281 11/7/2024
1.0.341 291 10/31/2024
1.0.340 347 10/20/2024
1.0.339 272 10/20/2024
1.0.338 283 10/20/2024
1.0.337 276 10/19/2024
1.0.336 291 10/19/2024
1.0.335 291 10/19/2024
1.0.334 285 10/19/2024
1.0.333 285 10/19/2024
1.0.332 266 10/19/2024
1.0.331 294 10/19/2024
1.0.330 322 10/18/2024
1.0.329 279 10/17/2024
1.0.328 241 10/17/2024
1.0.327 263 10/17/2024
1.0.326 818 10/14/2024
1.0.325 244 10/13/2024
1.0.324 244 10/13/2024
1.0.323 262 10/12/2024
1.0.322 456 10/9/2024
1.0.321 263 10/9/2024
1.0.320 456 10/5/2024
1.0.319 785 9/18/2024
1.0.318 243 9/18/2024
1.0.317 265 9/18/2024
1.0.316 258 9/17/2024
1.0.315 756 9/3/2024
1.0.314 305 9/1/2024
1.0.313 972 8/9/2024
1.0.312 262 8/9/2024
1.0.311 282 8/8/2024
1.0.310 721 7/25/2024
1.0.309 282 7/23/2024
1.0.308 300 7/17/2024
1.0.307 571 7/4/2024
1.0.306 630 6/12/2024
1.0.305 270 6/12/2024
1.0.304 268 6/12/2024
1.0.303 462 5/28/2024
1.0.302 626 5/4/2024
1.0.301 419 4/23/2024
1.0.300 282 4/21/2024
1.0.299 310 4/14/2024
1.0.298 574 3/28/2024
1.0.297 347 3/17/2024
1.0.296 549 3/9/2024
1.0.295 364 2/23/2024
1.0.294 294 2/23/2024
1.0.293 505 2/18/2024
1.0.292 295 2/18/2024
1.0.291 271 2/17/2024
1.0.290 288 2/16/2024
1.0.289 410 2/14/2024
1.0.288 290 2/13/2024
1.0.287 360 2/8/2024
1.0.286 363 2/5/2024
1.0.285 281 2/4/2024
1.0.284 453 1/23/2024
1.0.283 272 1/23/2024
1.0.282 340 1/12/2024
1.0.281 707 1/2/2024
1.0.280 322 12/29/2023
1.0.279 374 12/17/2023
1.0.278 531 12/15/2023
1.0.277 297 12/15/2023
1.0.276 279 12/15/2023
1.0.275 313 12/13/2023
1.0.274 309 12/13/2023
1.0.273 313 12/10/2023
1.0.272 689 11/18/2023
1.0.271 233 11/18/2023
1.0.270 261 11/18/2023
1.0.269 242 11/17/2023
1.0.268 215 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 243 11/9/2023
1.0.263 202 11/9/2023
1.0.262 222 11/9/2023
1.0.261 248 11/3/2023
1.0.260 233 11/1/2023
1.0.259 218 11/1/2023
1.0.258 1,480 9/8/2023
1.0.257 273 9/8/2023
1.0.256 288 9/3/2023
1.0.255 355 8/27/2023
1.0.254 283 8/24/2023
1.0.253 249 8/21/2023
1.0.252 323 8/15/2023
1.0.251 292 8/14/2023
1.0.250 270 8/14/2023
1.0.249 305 8/10/2023
1.0.248 1,021 7/29/2023
1.0.247 1,099 7/1/2023
1.0.246 315 6/29/2023
1.0.245 808 5/27/2023
1.0.244 361 5/21/2023
1.0.243 301 5/19/2023
1.0.242 1,091 5/8/2023
1.0.241 360 5/7/2023
1.0.240 347 5/7/2023
1.0.239 327 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 346 4/21/2023
1.0.234 1,242 4/13/2023
1.0.233 1,141 4/3/2023
1.0.232 493 3/27/2023
1.0.231 438 3/21/2023
1.0.230 440 3/17/2023
1.0.229 435 3/13/2023
1.0.228 1,189 3/6/2023
1.0.227 502 2/26/2023
1.0.226 945 2/21/2023
1.0.225 461 2/20/2023
1.0.224 476 2/16/2023
1.0.223 463 2/15/2023
1.0.222 437 2/14/2023
1.0.221 434 2/14/2023
1.0.220 1,363 2/9/2023
1.0.219 839 2/7/2023
1.0.218 493 2/4/2023
1.0.217 477 2/4/2023
1.0.216 493 2/3/2023
1.0.215 450 2/3/2023
1.0.214 449 2/3/2023
1.0.213 891 2/2/2023
1.0.212 840 1/30/2023
1.0.211 474 1/30/2023
1.0.210 515 1/25/2023
1.0.209 508 1/23/2023
1.0.208 460 1/23/2023
1.0.207 495 1/18/2023
1.0.206 521 1/15/2023
1.0.205 520 1/6/2023
1.0.204 1,423 1/1/2023
1.0.203 489 12/31/2022
1.0.202 975 12/30/2022
1.0.201 507 12/29/2022
1.0.200 517 12/23/2022
1.0.199 1,397 12/12/2022
1.0.198 1,075 12/8/2022
1.0.197 493 12/4/2022
1.0.196 496 12/4/2022
1.0.195 501 12/2/2022
1.0.194 525 11/30/2022
1.0.193 486 11/29/2022
1.0.192 481 11/28/2022
1.0.191 527 11/26/2022
1.0.190 520 11/26/2022
1.0.189 521 11/25/2022
1.0.188 523 11/25/2022
1.0.187 536 11/18/2022
1.0.186 1,605 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 556 11/4/2022
1.0.181 536 11/2/2022
1.0.180 528 11/2/2022
1.0.179 1,438 11/1/2022
1.0.178 1,664 10/16/2022
1.0.177 748 9/25/2022
1.0.176 680 9/10/2022
1.0.175 2,988 9/8/2022
1.0.174 659 9/8/2022
1.0.173 665 9/8/2022
1.0.172 641 9/4/2022
1.0.171 640 9/4/2022
1.0.170 5,360 8/24/2022
1.0.169 724 8/8/2022
1.0.168 647 8/8/2022
1.0.167 1,274 7/31/2022
1.0.166 661 7/31/2022
1.0.165 672 7/26/2022
1.0.164 640 7/26/2022
1.0.163 3,208 7/21/2022
1.0.162 695 7/19/2022
1.0.161 3,165 7/18/2022
1.0.160 700 7/13/2022
1.0.159 682 7/8/2022
1.0.158 703 6/30/2022
1.0.157 713 6/20/2022
1.0.156 664 6/18/2022
1.0.155 707 6/6/2022
1.0.154 754 5/27/2022
1.0.153 5,220 4/30/2022
1.0.152 692 4/20/2022
1.0.151 723 4/10/2022
1.0.150 691 4/7/2022
1.0.149 670 4/7/2022
1.0.148 728 4/2/2022
1.0.147 686 3/29/2022
1.0.146 673 3/27/2022
1.0.145 675 3/27/2022
1.0.144 3,928 3/24/2022
1.0.143 2,692 2/20/2022
1.0.142 653 2/20/2022
1.0.141 661 2/20/2022
1.0.140 692 2/20/2022
1.0.139 712 2/20/2022
1.0.138 677 2/20/2022
1.0.137 668 2/20/2022
1.0.136 688 2/20/2022
1.0.135 693 2/20/2022
1.0.134 679 2/19/2022
1.0.133 4,575 2/10/2022
1.0.132 785 1/27/2022
1.0.131 714 1/27/2022
1.0.130 3,575 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 552 12/27/2021
1.0.125 493 12/27/2021
1.0.124 515 12/27/2021
1.0.123 1,771 12/20/2021
1.0.122 556 12/17/2021
1.0.121 545 12/16/2021
1.0.120 526 12/15/2021
1.0.119 518 12/14/2021
1.0.118 540 12/14/2021
1.0.117 501 12/13/2021
1.0.116 664 12/12/2021
1.0.115 1,638 12/10/2021
1.0.114 549 12/7/2021
1.0.113 548 12/7/2021
1.0.112 1,983 12/6/2021
1.0.111 545 12/6/2021
1.0.110 551 12/5/2021
1.0.109 1,242 12/3/2021
1.0.108 1,048 12/3/2021
1.0.107 582 12/2/2021
1.0.106 2,465 11/29/2021
1.0.105 5,274 11/23/2021
1.0.104 538 11/23/2021
1.0.103 1,622 11/22/2021
1.0.102 633 11/17/2021
1.0.101 587 11/14/2021
1.0.100 1,756 11/13/2021
1.0.99 603 11/11/2021
1.0.98 581 11/11/2021
1.0.97 567 11/10/2021
1.0.96 578 11/9/2021
1.0.95 2,610 11/6/2021
1.0.94 611 11/6/2021
1.0.93 2,177 11/5/2021
1.0.92 635 11/5/2021
1.0.91 595 11/4/2021
1.0.90 566 11/4/2021
1.0.89 627 11/3/2021
1.0.88 690 10/30/2021
1.0.87 2,055 10/21/2021
1.0.86 661 10/17/2021
1.0.85 671 10/17/2021
1.0.84 3,059 10/14/2021
1.0.83 598 10/13/2021
1.0.82 614 10/13/2021
1.0.81 594 10/12/2021
1.0.80 2,148 10/11/2021
1.0.79 576 10/9/2021
1.0.78 1,959 10/7/2021
1.0.77 2,160 10/7/2021
1.0.76 575 10/7/2021
1.0.75 607 10/6/2021
1.0.74 663 9/28/2021
1.0.73 2,373 9/23/2021
1.0.72 710 9/11/2021
1.0.71 613 9/10/2021
1.0.70 679 9/9/2021
1.0.69 579 9/8/2021
1.0.68 639 9/8/2021
1.0.67 2,165 9/6/2021
1.0.66 710 8/31/2021
1.0.65 570 8/30/2021
1.0.64 2,622 7/31/2021
1.0.63 3,051 7/30/2021
1.0.62 691 7/26/2021
1.0.61 4,489 7/5/2021
1.0.60 645 7/1/2021
1.0.59 3,832 6/4/2021
1.0.58 5,079 4/26/2021
1.0.57 2,189 4/19/2021
1.0.56 5,734 4/8/2021
1.0.55 1,813 4/7/2021
1.0.54 627 4/7/2021
1.0.53 1,895 4/3/2021
1.0.52 7,992 3/22/2021
1.0.51 5,782 3/4/2021
1.0.50 2,166 2/26/2021
1.0.49 8,286 2/2/2021
1.0.48 3,237 1/26/2021
1.0.47 3,006 1/24/2021
1.0.46 665 1/24/2021
1.0.45 719 1/23/2021
1.0.44 3,910 1/20/2021
1.0.43 722 1/20/2021
1.0.42 2,093 1/18/2021
1.0.41 638 1/18/2021
1.0.40 2,070 1/16/2021
1.0.39 6,323 12/17/2020
1.0.38 701 12/16/2020
1.0.37 3,223 12/14/2020
1.0.36 2,131 12/9/2020
1.0.35 682 12/9/2020
1.0.34 694 12/7/2020
1.0.33 797 12/6/2020
1.0.32 746 12/2/2020
1.0.31 714 12/2/2020
1.0.30 2,213 12/1/2020
1.0.29 7,374 11/12/2020
1.0.29-atestpub 570 11/11/2020
1.0.28 3,351 10/11/2020
1.0.27 8,623 9/9/2020
1.0.26 2,639 9/3/2020
1.0.25 2,696 8/20/2020
1.0.24 6,168 8/9/2020
1.0.23 2,713 7/28/2020
1.0.22 2,653 7/19/2020
1.0.21 4,468 7/6/2020
1.0.20 6,635 6/6/2020
1.0.19 2,627 6/4/2020
1.0.18 4,394 5/29/2020
1.0.17 4,433 5/21/2020
1.0.16 771 5/17/2020
1.0.15 4,527 5/12/2020
1.0.14 8,247 5/4/2020
1.0.13 796 4/24/2020
1.0.12 783 4/22/2020
1.0.11 762 4/22/2020
1.0.10 784 4/21/2020
1.0.9 3,235 4/18/2020
1.0.8 2,590 4/16/2020
1.0.7 794 4/16/2020
1.0.6 2,267 4/15/2020
1.0.5 2,679 4/11/2020
1.0.4 2,571 4/3/2020
1.0.3 787 4/1/2020
1.0.2 2,497 3/27/2020
1.0.1 2,611 3/22/2020
1.0.0 899 3/22/2020