Ecng.Net.SocketIO 1.0.505

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.505
                    
NuGet\Install-Package Ecng.Net.SocketIO -Version 1.0.505
                    
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.505" />
                    
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.505" />
                    
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.505
                    
#r "nuget: Ecng.Net.SocketIO, 1.0.505"
                    
#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.505
                    
#: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.505
                    
Install as a Cake Addin
#tool nuget:?package=Ecng.Net.SocketIO&version=1.0.505
                    
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.517 30 1/16/2026
1.0.516 105 1/14/2026
1.0.515 82 1/13/2026
1.0.514 78 1/13/2026
1.0.513 90 1/12/2026
1.0.512 124 1/9/2026
1.0.511 104 1/9/2026
1.0.510 91 1/8/2026
1.0.509 94 1/8/2026
1.0.508 93 1/7/2026
1.0.507 95 1/6/2026
1.0.506 91 1/6/2026
1.0.505 97 1/5/2026
1.0.504 109 1/4/2026
1.0.503 112 1/1/2026
1.0.502 101 12/31/2025
1.0.501 102 12/30/2025
1.0.500 95 12/30/2025
1.0.499 105 12/29/2025
1.0.498 101 12/29/2025
1.0.497 105 12/26/2025
1.0.496 98 12/26/2025
1.0.495 95 12/26/2025
1.0.494 116 12/26/2025
1.0.493 187 12/25/2025
1.0.492 191 12/25/2025
1.0.491 199 12/24/2025
1.0.490 193 12/23/2025
1.0.489 183 12/22/2025
1.0.488 182 12/22/2025
1.0.487 189 12/22/2025
1.0.486 173 12/21/2025
1.0.485 230 12/19/2025
1.0.484 251 12/19/2025
1.0.483 294 12/18/2025
1.0.482 292 12/17/2025
1.0.481 293 12/15/2025
1.0.480 266 12/15/2025
1.0.479 249 12/14/2025
1.0.478 171 12/14/2025
1.0.477 170 12/13/2025
1.0.476 191 12/13/2025
1.0.475 158 12/12/2025
1.0.474 143 12/12/2025
1.0.473 130 12/12/2025
1.0.472 139 12/12/2025
1.0.471 133 12/12/2025
1.0.470 136 12/12/2025
1.0.469 137 12/12/2025
1.0.468 737 12/2/2025
1.0.467 695 12/2/2025
1.0.466 690 12/2/2025
1.0.465 291 11/30/2025
1.0.464 164 11/29/2025
1.0.463 156 11/28/2025
1.0.462 162 11/28/2025
1.0.461 208 11/27/2025
1.0.460 246 11/24/2025
1.0.459 217 11/24/2025
1.0.458 215 11/23/2025
1.0.457 187 11/23/2025
1.0.456 241 11/22/2025
1.0.455 452 11/20/2025
1.0.454 429 11/20/2025
1.0.453 425 11/20/2025
1.0.452 450 11/18/2025
1.0.451 428 11/18/2025
1.0.450 356 11/13/2025
1.0.449 294 11/10/2025
1.0.448 1,117 11/1/2025
1.0.447 223 10/31/2025
1.0.446 231 10/28/2025
1.0.445 349 10/27/2025
1.0.444 219 10/27/2025
1.0.443 148 10/25/2025
1.0.442 179 10/24/2025
1.0.441 286 10/20/2025
1.0.440 319 10/12/2025
1.0.439 169 10/11/2025
1.0.438 304 10/7/2025
1.0.437 245 10/6/2025
1.0.436 287 10/3/2025
1.0.435 257 10/1/2025
1.0.434 229 10/1/2025
1.0.433 229 9/30/2025
1.0.432 232 9/28/2025
1.0.431 248 9/25/2025
1.0.430 3,212 9/5/2025
1.0.429 261 9/2/2025
1.0.428 616 8/30/2025
1.0.427 284 8/30/2025
1.0.426 284 8/20/2025
1.0.425 231 8/20/2025
1.0.424 242 8/19/2025
1.0.423 251 8/15/2025
1.0.422 344 8/10/2025
1.0.421 1,064 7/16/2025
1.0.420 299 7/14/2025
1.0.419 269 7/13/2025
1.0.418 247 7/13/2025
1.0.417 221 7/12/2025
1.0.416 732 7/8/2025
1.0.415 281 7/4/2025
1.0.414 277 7/2/2025
1.0.413 439 6/24/2025
1.0.412 1,046 6/16/2025
1.0.411 430 6/9/2025
1.0.410 310 6/8/2025
1.0.409 633 5/21/2025
1.0.408 278 5/21/2025
1.0.407 265 5/17/2025
1.0.406 670 5/12/2025
1.0.405 367 5/12/2025
1.0.404 334 5/12/2025
1.0.403 257 5/11/2025
1.0.402 266 5/11/2025
1.0.401 221 5/10/2025
1.0.400 185 5/10/2025
1.0.399 309 5/6/2025
1.0.398 235 5/3/2025
1.0.397 399 4/17/2025
1.0.396 350 4/15/2025
1.0.395 249 4/12/2025
1.0.394 326 4/9/2025
1.0.393 285 4/6/2025
1.0.392 240 4/5/2025
1.0.391 1,114 3/22/2025
1.0.390 310 3/20/2025
1.0.389 299 3/20/2025
1.0.388 286 3/19/2025
1.0.387 855 2/26/2025
1.0.386 264 2/26/2025
1.0.385 785 2/8/2025
1.0.384 263 2/8/2025
1.0.383 243 2/8/2025
1.0.382 240 2/6/2025
1.0.381 229 2/6/2025
1.0.380 250 2/6/2025
1.0.379 257 2/6/2025
1.0.378 231 2/6/2025
1.0.377 233 2/5/2025
1.0.376 237 2/5/2025
1.0.375 256 2/5/2025
1.0.374 281 2/3/2025
1.0.373 264 2/2/2025
1.0.372 280 2/1/2025
1.0.371 262 1/31/2025
1.0.370 267 1/30/2025
1.0.369 252 1/26/2025
1.0.368 281 1/21/2025
1.0.367 267 1/20/2025
1.0.366 232 1/20/2025
1.0.365 250 1/19/2025
1.0.364 239 1/19/2025
1.0.363 264 1/15/2025
1.0.362 233 1/15/2025
1.0.361 226 1/14/2025
1.0.360 220 1/12/2025
1.0.359 209 1/12/2025
1.0.358 226 1/12/2025
1.0.357 192 1/12/2025
1.0.356 248 1/10/2025
1.0.355 1,082 12/30/2024
1.0.354 273 12/27/2024
1.0.353 291 12/19/2024
1.0.352 757 11/20/2024
1.0.351 268 11/19/2024
1.0.350 249 11/19/2024
1.0.349 810 11/18/2024
1.0.348 486 11/15/2024
1.0.347 235 11/14/2024
1.0.346 259 11/14/2024
1.0.345 264 11/14/2024
1.0.344 217 11/14/2024
1.0.343 245 11/14/2024
1.0.342 283 11/7/2024
1.0.341 296 10/31/2024
1.0.340 351 10/20/2024
1.0.339 274 10/20/2024
1.0.338 287 10/20/2024
1.0.337 278 10/19/2024
1.0.336 293 10/19/2024
1.0.335 295 10/19/2024
1.0.334 287 10/19/2024
1.0.333 289 10/19/2024
1.0.332 268 10/19/2024
1.0.331 297 10/19/2024
1.0.330 327 10/18/2024
1.0.329 281 10/17/2024
1.0.328 245 10/17/2024
1.0.327 267 10/17/2024
1.0.326 822 10/14/2024
1.0.325 248 10/13/2024
1.0.324 247 10/13/2024
1.0.323 264 10/12/2024
1.0.322 461 10/9/2024
1.0.321 265 10/9/2024
1.0.320 458 10/5/2024
1.0.319 788 9/18/2024
1.0.318 245 9/18/2024
1.0.317 268 9/18/2024
1.0.316 261 9/17/2024
1.0.315 760 9/3/2024
1.0.314 307 9/1/2024
1.0.313 975 8/9/2024
1.0.312 265 8/9/2024
1.0.311 284 8/8/2024
1.0.310 725 7/25/2024
1.0.309 287 7/23/2024
1.0.308 303 7/17/2024
1.0.307 576 7/4/2024
1.0.306 634 6/12/2024
1.0.305 272 6/12/2024
1.0.304 273 6/12/2024
1.0.303 467 5/28/2024
1.0.302 629 5/4/2024
1.0.301 422 4/23/2024
1.0.300 284 4/21/2024
1.0.299 313 4/14/2024
1.0.298 579 3/28/2024
1.0.297 349 3/17/2024
1.0.296 553 3/9/2024
1.0.295 366 2/23/2024
1.0.294 296 2/23/2024
1.0.293 509 2/18/2024
1.0.292 299 2/18/2024
1.0.291 275 2/17/2024
1.0.290 291 2/16/2024
1.0.289 414 2/14/2024
1.0.288 292 2/13/2024
1.0.287 363 2/8/2024
1.0.286 365 2/5/2024
1.0.285 283 2/4/2024
1.0.284 455 1/23/2024
1.0.283 276 1/23/2024
1.0.282 342 1/12/2024
1.0.281 709 1/2/2024
1.0.280 324 12/29/2023
1.0.279 376 12/17/2023
1.0.278 534 12/15/2023
1.0.277 301 12/15/2023
1.0.276 281 12/15/2023
1.0.275 315 12/13/2023
1.0.274 313 12/13/2023
1.0.273 315 12/10/2023
1.0.272 689 11/18/2023
1.0.271 234 11/18/2023
1.0.270 263 11/18/2023
1.0.269 244 11/17/2023
1.0.268 215 11/12/2023
1.0.267 217 11/12/2023
1.0.266 240 11/10/2023
1.0.265 202 11/10/2023
1.0.264 245 11/9/2023
1.0.263 203 11/9/2023
1.0.262 223 11/9/2023
1.0.261 248 11/3/2023
1.0.260 233 11/1/2023
1.0.259 220 11/1/2023
1.0.258 1,480 9/8/2023
1.0.257 273 9/8/2023
1.0.256 290 9/3/2023
1.0.255 355 8/27/2023
1.0.254 283 8/24/2023
1.0.253 250 8/21/2023
1.0.252 325 8/15/2023
1.0.251 293 8/14/2023
1.0.250 270 8/14/2023
1.0.249 307 8/10/2023
1.0.248 1,023 7/29/2023
1.0.247 1,101 7/1/2023
1.0.246 315 6/29/2023
1.0.245 808 5/27/2023
1.0.244 363 5/21/2023
1.0.243 301 5/19/2023
1.0.242 1,093 5/8/2023
1.0.241 362 5/7/2023
1.0.240 350 5/7/2023
1.0.239 328 5/7/2023
1.0.238 375 5/1/2023
1.0.237 419 4/22/2023
1.0.236 380 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 495 3/27/2023
1.0.231 438 3/21/2023
1.0.230 441 3/17/2023
1.0.229 436 3/13/2023
1.0.228 1,190 3/6/2023
1.0.227 502 2/26/2023
1.0.226 946 2/21/2023
1.0.225 461 2/20/2023
1.0.224 477 2/16/2023
1.0.223 464 2/15/2023
1.0.222 437 2/14/2023
1.0.221 434 2/14/2023
1.0.220 1,364 2/9/2023
1.0.219 841 2/7/2023
1.0.218 495 2/4/2023
1.0.217 477 2/4/2023
1.0.216 493 2/3/2023
1.0.215 453 2/3/2023
1.0.214 449 2/3/2023
1.0.213 891 2/2/2023
1.0.212 841 1/30/2023
1.0.211 474 1/30/2023
1.0.210 517 1/25/2023
1.0.209 508 1/23/2023
1.0.208 461 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,425 1/1/2023
1.0.203 491 12/31/2022
1.0.202 975 12/30/2022
1.0.201 509 12/29/2022
1.0.200 517 12/23/2022
1.0.199 1,399 12/12/2022
1.0.198 1,076 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 488 11/29/2022
1.0.192 483 11/28/2022
1.0.191 527 11/26/2022
1.0.190 520 11/26/2022
1.0.189 523 11/25/2022
1.0.188 523 11/25/2022
1.0.187 536 11/18/2022
1.0.186 1,606 11/11/2022
1.0.185 559 11/11/2022
1.0.184 514 11/10/2022
1.0.183 576 11/5/2022
1.0.182 558 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,665 10/16/2022
1.0.177 749 9/25/2022
1.0.176 682 9/10/2022
1.0.175 2,990 9/8/2022
1.0.174 660 9/8/2022
1.0.173 667 9/8/2022
1.0.172 644 9/4/2022
1.0.171 641 9/4/2022
1.0.170 5,362 8/24/2022
1.0.169 725 8/8/2022
1.0.168 647 8/8/2022
1.0.167 1,274 7/31/2022
1.0.166 663 7/31/2022
1.0.165 673 7/26/2022
1.0.164 642 7/26/2022
1.0.163 3,208 7/21/2022
1.0.162 696 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 704 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 756 5/27/2022
1.0.153 5,221 4/30/2022
1.0.152 692 4/20/2022
1.0.151 724 4/10/2022
1.0.150 691 4/7/2022
1.0.149 670 4/7/2022
1.0.148 730 4/2/2022
1.0.147 688 3/29/2022
1.0.146 674 3/27/2022
1.0.145 677 3/27/2022
1.0.144 3,929 3/24/2022
1.0.143 2,693 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 713 2/20/2022
1.0.138 678 2/20/2022
1.0.137 669 2/20/2022
1.0.136 689 2/20/2022
1.0.135 694 2/20/2022
1.0.134 679 2/19/2022
1.0.133 4,578 2/10/2022
1.0.132 788 1/27/2022
1.0.131 714 1/27/2022
1.0.130 3,576 1/24/2022
1.0.129 662 1/24/2022
1.0.128 701 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,772 12/20/2021
1.0.122 557 12/17/2021
1.0.121 546 12/16/2021
1.0.120 528 12/15/2021
1.0.119 518 12/14/2021
1.0.118 541 12/14/2021
1.0.117 501 12/13/2021
1.0.116 664 12/12/2021
1.0.115 1,641 12/10/2021
1.0.114 549 12/7/2021
1.0.113 548 12/7/2021
1.0.112 1,985 12/6/2021
1.0.111 545 12/6/2021
1.0.110 552 12/5/2021
1.0.109 1,242 12/3/2021
1.0.108 1,049 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 540 11/23/2021
1.0.103 1,624 11/22/2021
1.0.102 634 11/17/2021
1.0.101 588 11/14/2021
1.0.100 1,756 11/13/2021
1.0.99 605 11/11/2021
1.0.98 581 11/11/2021
1.0.97 567 11/10/2021
1.0.96 580 11/9/2021
1.0.95 2,612 11/6/2021
1.0.94 611 11/6/2021
1.0.93 2,177 11/5/2021
1.0.92 637 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 691 10/30/2021
1.0.87 2,055 10/21/2021
1.0.86 662 10/17/2021
1.0.85 672 10/17/2021
1.0.84 3,059 10/14/2021
1.0.83 600 10/13/2021
1.0.82 617 10/13/2021
1.0.81 595 10/12/2021
1.0.80 2,148 10/11/2021
1.0.79 576 10/9/2021
1.0.78 1,960 10/7/2021
1.0.77 2,162 10/7/2021
1.0.76 576 10/7/2021
1.0.75 610 10/6/2021
1.0.74 664 9/28/2021
1.0.73 2,373 9/23/2021
1.0.72 710 9/11/2021
1.0.71 615 9/10/2021
1.0.70 679 9/9/2021
1.0.69 581 9/8/2021
1.0.68 642 9/8/2021
1.0.67 2,167 9/6/2021
1.0.66 713 8/31/2021
1.0.65 570 8/30/2021
1.0.64 2,622 7/31/2021
1.0.63 3,053 7/30/2021
1.0.62 691 7/26/2021
1.0.61 4,489 7/5/2021
1.0.60 647 7/1/2021
1.0.59 3,834 6/4/2021
1.0.58 5,082 4/26/2021
1.0.57 2,190 4/19/2021
1.0.56 5,736 4/8/2021
1.0.55 1,815 4/7/2021
1.0.54 627 4/7/2021
1.0.53 1,895 4/3/2021
1.0.52 7,994 3/22/2021
1.0.51 5,782 3/4/2021
1.0.50 2,169 2/26/2021
1.0.49 8,287 2/2/2021
1.0.48 3,238 1/26/2021
1.0.47 3,009 1/24/2021
1.0.46 668 1/24/2021
1.0.45 721 1/23/2021
1.0.44 3,913 1/20/2021
1.0.43 725 1/20/2021
1.0.42 2,095 1/18/2021
1.0.41 640 1/18/2021
1.0.40 2,072 1/16/2021
1.0.39 6,326 12/17/2020
1.0.38 702 12/16/2020
1.0.37 3,226 12/14/2020
1.0.36 2,132 12/9/2020
1.0.35 685 12/9/2020
1.0.34 697 12/7/2020
1.0.33 798 12/6/2020
1.0.32 749 12/2/2020
1.0.31 715 12/2/2020
1.0.30 2,215 12/1/2020
1.0.29 7,375 11/12/2020
1.0.29-atestpub 571 11/11/2020
1.0.28 3,354 10/11/2020
1.0.27 8,625 9/9/2020
1.0.26 2,641 9/3/2020
1.0.25 2,700 8/20/2020
1.0.24 6,170 8/9/2020
1.0.23 2,714 7/28/2020
1.0.22 2,653 7/19/2020
1.0.21 4,468 7/6/2020
1.0.20 6,637 6/6/2020
1.0.19 2,628 6/4/2020
1.0.18 4,394 5/29/2020
1.0.17 4,433 5/21/2020
1.0.16 772 5/17/2020
1.0.15 4,528 5/12/2020
1.0.14 8,248 5/4/2020
1.0.13 797 4/24/2020
1.0.12 785 4/22/2020
1.0.11 762 4/22/2020
1.0.10 784 4/21/2020
1.0.9 3,238 4/18/2020
1.0.8 2,592 4/16/2020
1.0.7 794 4/16/2020
1.0.6 2,268 4/15/2020
1.0.5 2,679 4/11/2020
1.0.4 2,571 4/3/2020
1.0.3 790 4/1/2020
1.0.2 2,498 3/27/2020
1.0.1 2,611 3/22/2020
1.0.0 900 3/22/2020