Nextended.Aspire.Hosting.WebDataStudio 10.1.33

dotnet add package Nextended.Aspire.Hosting.WebDataStudio --version 10.1.33
                    
NuGet\Install-Package Nextended.Aspire.Hosting.WebDataStudio -Version 10.1.33
                    
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="Nextended.Aspire.Hosting.WebDataStudio" Version="10.1.33" />
                    
For projects that support PackageReference, copy this XML node into the project file to reference the package.
<PackageVersion Include="Nextended.Aspire.Hosting.WebDataStudio" Version="10.1.33" />
                    
Directory.Packages.props
<PackageReference Include="Nextended.Aspire.Hosting.WebDataStudio" />
                    
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 Nextended.Aspire.Hosting.WebDataStudio --version 10.1.33
                    
#r "nuget: Nextended.Aspire.Hosting.WebDataStudio, 10.1.33"
                    
#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 Nextended.Aspire.Hosting.WebDataStudio@10.1.33
                    
#: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=Nextended.Aspire.Hosting.WebDataStudio&version=10.1.33
                    
Install as a Cake Addin
#tool nuget:?package=Nextended.Aspire.Hosting.WebDataStudio&version=10.1.33
                    
Install as a Cake Tool

Nextended

Nextended.Aspire.Hosting.WebDataStudio

NuGet Downloads License

WebDataStudio — a browser database studio for PostgreSQL, MySQL, SQL Server, SQLite, Oracle, DuckDB, ClickHouse, MongoDB and Redis — wired to the databases of your stack, with accounts and roles, an optional SQL assistant, and an MCP endpoint for AI agents.

WebDataStudio

WebDataStudio screenshot

Runs WebDataStudio as an Aspire resource.

📖 Documentation: English · Deutsch  |  🧪 Runnable sample: WebDataStudio.AppHost

Run WebDataStudio — a browser-based database studio for PostgreSQL, MySQL, SQL Server, SQLite, Oracle, DuckDB, ClickHouse, MongoDB and Redis — inside your Aspire stack, with the databases of that stack already wired up.

var builder = DistributedApplication.CreateBuilder(args);

var shop = builder.AddPostgres("pg").AddDatabase("shop").WithWebDataStudio();
var orders = builder.AddSqlServer("sql").AddDatabase("orders").WithWebDataStudio();
var cache = builder.AddRedis("cache").WithWebDataStudio();

builder.Build().Run();

One studio, three connections, no connection string typed anywhere. Open it from the Aspire dashboard and the explorer already lists SHOP, ORDERS and CACHE.

Sharing one studio, or running several

WithWebDataStudio() creates the studio on the first call and attaches to it on every one after — sharing is keyed on the studio's resource name.

// One shared studio (default name "webdatastudio")
shop.WithWebDataStudio();
orders.WithWebDataStudio();

// A second studio, for the databases that belong together
analytics.WithWebDataStudio(studioName: "analytics-studio");
warehouse.WithWebDataStudio(studioName: "analytics-studio");

// A studio you built yourself, with your own options
var admin = builder.AddWebDataStudio("admin-studio")
    .WithLogin("admin", builder.AddParameter("studio-password", secret: true))
    .WithReadOnly();

production.WithWebDataStudio(admin, color: "#e03131", group: "Production");

The same works from the studio's side, which reads better when one studio owns many databases:

builder.AddWebDataStudio("studio")
    .WithReference(shop)
    .WithReference(orders, connectionName: "ORDERS_PROD", readOnly: true, color: "#e03131")
    .WithReference(cache)
    .WithConnection("LEGACY", "Host=old-box;Database=legacy;Username=ro;Password=pw",
        WebDataStudioEngine.PostgreSql, readOnly: true, group: "Legacy");

WithReference on a studio is this package's own overload. Aspire's built-in one would write a ConnectionStrings__* variable, which the studio does not read; this one writes the WDS_CONN_* variables it does.

API

Call Effect
AddWebDataStudio(name = "webdatastudio", port?, image?, tag?) Add the studio container: HTTP endpoint, health check, per-instance data volume.
.WithReference(resource, connectionName?, engine?, readOnly?, group?, color?) Attach any resource that has a connection string.
.WithConnection(name, connectionString, engine, …) Attach a database that is not part of the stack. Also takes a ReferenceExpression.
.WithLogin(user, password) Guard the studio with a login, as an admin. Chain it for more accounts — two calls mean two people can sign in. Both halves also accept an Aspire ParameterResource.
.WithUser(user, password, role, connections…) One account with a role (StudioRoles.Admin, Editor, Viewer) and, optionally, the connections it may see. The password also takes a ParameterResource.
.WithAssistant(server, model, …) Point the studio's optional assistance at a model server in the stack — Ollama, LocalAI, vLLM, llama.cpp. Also takes a URL, a ReferenceExpression or a ParameterResource key.
.WithOllamaAssistant(ollama, model) / .WithLocalAiAssistant(localai, model) The same, named for the two servers people reach for first.
.WithClaudeAssistant(key), .WithChatGptAssistant(key), .WithOpenRouterAssistant(key), .WithGroqAssistant(key), .WithMistralAssistant(key), .WithDeepSeekAssistant(key), .WithGeminiAssistant(key), .WithAzureOpenAiAssistant(resource, deployment, key) The hosted providers, one call each: the right URL and a sensible default model.
.WithMaskedColumns("ssn", "iban") Mask these columns as well, whatever the studio's name heuristic thinks. Chaining adds to the list.
.WithUnmaskedColumns("token_type") Leave these alone, whatever it thinks.
.WithoutColumnMasking() Turn the heuristic off, leaving only the columns you named.
.WithMcpEndpoint(path?, key?, allowWrite?) Serve the studio as an MCP server, so Claude Code, Claude Desktop, VS Code or Cursor can reach its databases. Read-only unless allowWrite.
.WithScheduledQueries(jobs…) Run reading queries on a schedule and write each result as a file.
.WithSavedQueriesFromDirectory(path) Mount a folder of .sql files and import them as saved queries at start.
.WithSeedScript(path) Run a seed script once per connection — a file, or {CONNECTION}.sql per connection.
.WithSchemaSnapshots(path?) Snapshot every connection's schema on start and report the drift since the last one.
.WithOpenTelemetry(collector \| url?, serviceName?) Send the studio's traces and metrics to an OTLP collector — a resource in the stack, or a URL.
.WithSharedResults(ttl?, isPublic?, maxRows?) Let people keep a result and share it as a link. Off by default.
.WithArchives(path?, maxRows?) Move or cap the results the studio keeps as files. They are on by default; this decides where and how big.
.WithAlertWebhook(url, interval?, minSeverity?, connections?) Post new health findings — missing indexes, tables without a key, bloat — to Slack, Teams or any webhook.
.WithMcpTools(WebDataStudioMcpTools.SchemaOnly) Narrow the endpoint to named tools. ReadOnly and SchemaOnly are ready-made sets.
.WithoutAssistantTools() Keep the studio's own assistant from using those MCP tools.
.WithTitle(name) Name shown in the studio's header and browser tab. Defaults to the resource name; null leaves it unnamed.
.WithReadOnly(readOnly = true) Make every connection read-only, enforced in the driver.
.WithQueryTimeout(TimeSpan) Default statement timeout.
.WithMaxRows(int) Default row cap per result.
.WithSessionLimits(maxSessions?, idleTimeout?) Cap open sessions per connection and how long an idle one lives.
.WithSecretKey(base64) Key for the secrets the studio stores; also takes a ParameterResource.
.WithDataVolume(name?) / .WithDataBindMount(path) Put the studio's own data somewhere else.
resource.WithWebDataStudio(configure?, studioName?, connectionName?, engine?) Attach from the database's side, creating or reusing the studio.
resource.WithWebDataStudio(studio, …) Attach to a studio you built yourself.

The optional assistance

The studio can explain a statement and draft one from a question. It is off unless configured: no endpoint means no button, no calls, and /api/health reports assist: false.

Point it at a model server in the same stack, and the conversation never leaves the machine:

var ollama = builder.AddOllama("ollama").WithDataVolume();   // CommunityToolkit
ollama.AddModel("llama3.2");

builder.AddWebDataStudio()
    .WithReference(shop)
    .WithOllamaAssistant(ollama, "llama3.2");                // waits for Ollama, uses its endpoint

LocalAI works the same way — WithLocalAiAssistant(localai, "qwen3-8b") — and so does anything else that speaks the OpenAI chat-completions shape (WithAssistant(server, model, path: "/v1/chat/completions")).

For a hosted model there is one call per provider, so nobody has to look a URL up:

studio.WithClaudeAssistant(builder.AddParameter("anthropic-key", secret: true));
studio.WithChatGptAssistant(openAiKey, "gpt-4o");
studio.WithOpenRouterAssistant(openRouterKey, "anthropic/claude-sonnet-4.5");
studio.WithAzureOpenAiAssistant("my-openai", "gpt4o-deploy", azureKey);
Call Provider Default model
.WithClaudeAssistant(key, model?) Anthropic, through their OpenAI-compatible endpoint claude-sonnet-4-5
.WithChatGptAssistant(key, model?) OpenAI gpt-4o-mini
.WithOpenRouterAssistant(key, model?) OpenRouter — the model name carries the provider anthropic/claude-sonnet-4.5
.WithGroqAssistant(key, model?) Groq llama-3.3-70b-versatile
.WithMistralAssistant(key, model?) Mistral mistral-large-latest
.WithDeepSeekAssistant(key, model?) DeepSeek deepseek-chat
.WithGeminiAssistant(key, model?) Google, through their OpenAI-compatible endpoint gemini-2.5-flash
.WithAzureOpenAiAssistant(resource, deployment, key, apiVersion?) Azure OpenAI — builds the deployment URL for you the deployment name
.WithOllamaAssistant(ollama, model?) / .WithLocalAiAssistant(localai, model) a model server in your own stack llama3.2 / —

Every key also takes an Aspire ParameterResource, which is how it stays out of the manifest.

What leaves the studio is the statement or the question, and — only when the user turns the switch on in the dialog — the table and column names of the connection. Never a row of data. Nothing the model answers is executed: a suggested statement lands in the editor and goes through the same run and preview as anything typed by hand.

Masked columns

The studio masks columns whose names say they hold a secret — password, api_key, iban — before the values leave the server. For a schema it reads wrong, correct it here rather than per person:

studio
    .WithMaskedColumns("ssn", "customer_note")   // mask these too
    .WithUnmaskedColumns("token_type");          // and leave this one alone

WithoutColumnMasking() turns the guessing off and masks only what you named. Anything somebody later sets from the studio's column menu wins over these, because they were looking at the data.

Sharing a result

studio.WithSharedResults(ttl: TimeSpan.FromDays(3), isPublic: false);

A result grows a Share button, and the link shows the rows as they were — a snapshot, not a query: it cannot run anything, and masking is applied before the rows are stored, so a masked column stays masked in that link. isPublic: true lets anybody with the link open it without signing in, which is the point of a link and a decision worth making on purpose.

Traces and metrics

var collector = builder.AddOpenTelemetryCollector("otel");   // Nextended.Aspire.Hosting.Grafana

studio.WithOpenTelemetry(collector);        // or WithOpenTelemetry("http://collector:4317")

The studio then reports its own work to the same collector as the rest of the stack: a span per run (query.execute, tagged with engine, rows and outcome), a span per MCP tool call, and counters for statements, rows and tool calls. It reports as the resource's name unless you say otherwise, so three studios are told apart, and it waits for the collector so the first traces are not thrown away.

Alerts

studio.WithAlertWebhook(builder.AddParameter("slack-webhook", secret: true),
    interval: TimeSpan.FromHours(2), minSeverity: "warning");

The studio runs the analysis behind its health report on that interval and posts what is new — missing indexes, tables without a primary key, bloat — to the webhook. The payload's text field is what Slack, Mattermost, Discord and Teams render; the findings ride along structured, each with the statement that would fix it. Only new findings are sent, and a failed post is retried on the next sweep.

Queries and data that ship with the stack

builder.AddWebDataStudio()
    .WithReference(shop)
    .WithSavedQueriesFromDirectory("./queries")   // .sql files -> the Saved panel
    .WithSeedScript("./seed");                    // SHOP.sql -> run once on SHOP

Both folders are mounted read-only and read at start. Saved queries are imported idempotently — a restart replaces rather than duplicates — and a file may name its connection and folder in comments (-- wds:connection SHOP, -- wds:folder Ops).

A seed script runs once per content: editing it makes it run again, restarting does not. It never runs on a read-only connection, and never on one marked as production.

Scheduled reports

studio.WithScheduledQueries(
    new ScheduledStudioQuery("orders-per-day", "SHOP",
        "SELECT date(created_at) AS day, count(*) FROM orders GROUP BY 1", DailyAtUtc: "03:00"),
    new ScheduledStudioQuery("queue-depth", "SHOP",
        "SELECT count(*) FROM jobs WHERE state = 'pending'", EveryMinutes: 15, Format: "json"));

The schedule is generated as a file and mounted read-only, so it lives in the app host rather than in a volume somebody has to remember. Results land in /data/exports on the studio's own volume, masked like every other export. Only reading statements run, and a job that says neither EveryMinutes nor DailyAtUtc throws here rather than never running.

Archives

studio.WithArchives();                          // /data/archives, on the studio's own volume
studio.WithArchives("/mnt/archives", maxRows: 50_000);

A result can be kept as a file the studio holds on to: what a table looked like before the migration, what the report said last Tuesday. The panel lists them, opening one shows its rows, and the rows can be scripted back out as INSERTs for wherever they should go next.

The format is NDJSON — a header line naming the columns and where they came from, then one row per line — so anything can read it. Masked columns are masked in the file: an archive of them would be a way around the masking. Archives work without this call; it is for putting them on a different volume, or for capping how much one keeps.

Schema drift

studio.WithSchemaSnapshots();          // /data/snapshots, on the studio's own volume

The studio writes a snapshot of every connection's schema shortly after start and reports what moved since the last one — tables added or removed, and per table which columns, indexes and foreign keys came or went. It lands on GET /api/schema/{connection}/drift, in the log, and in a message when WithAlertWebhook is configured. POST /api/schema/snapshot takes one now.

This is not a migration tool: it catches the drift a migration tool cannot see, like the column somebody added by hand on staging.

The studio as an MCP server

WithMcpEndpoint() makes the studio answer the Model Context Protocol, so an agent can use its databases — Claude Code, Claude Desktop, VS Code, Cursor, anything that speaks MCP:

var mcpKey = builder.AddParameter("mcp-key", secret: true);

var studio = builder.AddWebDataStudio()
    .WithReference(shop)
    .WithMcpEndpoint(mcpKey)                  // read-only
    .WithClaudeAssistant(anthropicKey);       // and the studio's own assistant uses the same tools

The agent gets list_connections, list_tables, list_objects, describe_object, browse_rows, run_query, explain_plan, health_report, server_activity and redis_value — and with allowWrite: true also preview_script and apply_script, in that order, so a write is always shown before it runs. Masking, read-only connections and the row cap apply to an agent exactly as they do to a person. The studio's header carries a dialog with the URL and ready-to-paste client configuration once the endpoint is on.

WithMcpTools(WebDataStudioMcpTools.SchemaOnly) narrows it to the tools you want an agent to have — a whitelist, enforced on the call as well as the listing.

A studio with accounts requires the key. The MCP endpoint sits outside the login screen — an agent has no cookie — so the studio refuses to serve it without one rather than opening a way past the login.

When both the MCP endpoint and an assistant are configured, the studio's own assistant uses the same tools and answers from the database instead of guessing. WithoutAssistantTools() turns that off.

Engines

The engine is read from the resource type, so AddPostgres, AddSqlServer, AddMySql, AddOracle, AddMongoDB, AddRedis, AddValkey and AddGarnet need no help. Anything else — a container you wired up yourself, a connection string from configuration — takes an explicit engine: argument, or the studio guesses from the connection string and skips the connection if it cannot tell.

studio.WithReference(clickhouse, engine: WebDataStudioEngine.ClickHouse);

Notes

  • Connection names become environment variables, so shop-db shows up as SHOP_DB. Pass connectionName for something nicer. Names ending in _ENGINE, _READONLY, _GROUP or _COLOR are rejected: the studio reads those as settings for another connection.
  • Without WithLogin there is no login screen. That is the right default while the studio only listens on your machine — put a login on it before you expose the endpoint.
  • Several accounts: chain WithLogin/WithUser. One plain admin still writes WDS_USER and WDS_PASSWORD; more than one — or one with a role — writes WDS_USERS, which is name:role:secret[:conn,conn] per account separated by ;. Saying the same name twice replaces that account rather than adding a second one with the same login.
var studio = builder.AddWebDataStudio()
    .WithReference(shop)
    .WithReference(warehouse)
    .WithLogin("hans", "hans")                                        // admin
    .WithLogin("pete", "pete")                                        // admin as well
    .WithUser("grace", "read-only", StudioRoles.Viewer, "shop")       // sees shop, read-only
    .WithUser("eve", evePassword, StudioRoles.Editor);                // may write, may not administer

Roles: admin reaches the administration panel, editor may read and write, viewer gets every connection read-only. A connection an account may not see does not exist for it — not in the explorer, and not by guessing its id.

  • Each studio gets its own named volume while you run locally, so two studios in one stack never share saved connections. A published studio gets no volume — see below.
  • The studio shows its resource name in its header and browser tab, so three of them in one stack are told apart at a glance. WithTitle changes it, WithTitle(null) removes it.
  • The studio image is ghcr.io/fgilde/webdatastudio and is always re-pulled, because the default tag is a rolling latest.

Deploying it

Everything the studio needs in Azure is generated for you: a user-assigned managed identity, a database user for that identity (CREATE USER … db_owner) on every Azure SQL database you reference, a Key Vault role where the connection string lives in a secret, and the connection strings themselves as environment variables. The studio image reads Entra connection strings (Authentication=Active Directory Default) and picks the identity up from AZURE_CLIENT_ID, which Container Apps sets.

Three things are your call:

var studio = builder.AddWebDataStudio("admin-studio")
    .WithExternalHttpEndpoints()                    // otherwise it is only reachable inside the environment
    .WithLogin("admin", studioPassword)             // mandatory once the endpoint is public
    .WithReference(db, connectionName: "SHOP");
  • The endpoint is internal by default. WithExternalHttpEndpoints() publishes it.
  • A public studio without a login hands every visitor db_owner. Add WithLogin, and WithReadOnly() if reading is enough. Publishing an external endpoint without a login prints a warning; it does not stop the deploy.
  • A published studio has no persistent storage. Aspire maps a named volume to an Azure Files share, and the studio keeps connections, history and layouts in SQLite — which on an SMB share either crawls or blocks outright. Connections attached in the app host come from the environment on every start and are unaffected; anything a user saves in the UI lives until the next restart. WithDataVolume("name") opts back in if you know your share behaves, and WithSecretKey keeps stored connections readable across replacements of it.

GET /api/health on the deployed studio answers with the version, the commit it was built from and whether its storage is usable — the quickest way to tell a stale image from a broken mount.

The sample

Tests/TestProjects/WebDataStudio.AppHost starts PostgreSQL, SQL Server, MongoDB and Redis behind three studios, and seeds the PostgreSQL database with a small shop — customers, products, orders, order items and a view — so there is something to click around in from the first run.

dotnet run --project Tests/TestProjects/WebDataStudio.AppHost

Supported frameworks

  • net8.0
  • net9.0
  • net10.0

Dependencies

  • Aspire.Hosting.AppHost

The Nextended family

The other 17 packages in the suite:

Core libraries

  • Nextended.Core — Foundation library — extension methods, custom types (Money, Date, BaseId, SuperType), class mapping, deep clone, encryption, hashing and the code-generation attributes.
  • Nextended.Cache — Expression-based caching — automatic cache keys from method expressions, CacheProvider with condition-based invalidation, thread-safe AddOrGetExisting.

Data access

  • Nextended.EF — Entity Framework Core extensions — graph loading (LoadGraphAsync, IncludeAll, MultiInclude), declarative include definitions, paging, dynamic sorting and bulk operations.

ASP.NET Core & web

  • Nextended.Web — ASP.NET Core utilities — zero-config OData (AddODataAuto), composable IQueryable OData appliers, strongly typed controller URLs, streaming download helpers and a background executor that can replay a captured request.
  • Nextended.ResponseFilters — Fluent, provider-agnostic pipeline that redacts, masks, rounds, truncates, hashes, prunes and restructures response DTOs before serialization — per request, per user, per permission.
  • Nextended.ResponseFilters.AspNetCore — ASP.NET Core adapter for Nextended.ResponseFilters — registers the pipeline as a global IAsyncResultFilter and replays structural edits against the serialized JSON tree.

UI libraries

  • Nextended.Blazor — Blazor helpers — IBrowserFile extensions (bytes, data URLs, downloads), a hierarchical model for browsing inside uploaded zip/tar/rar archives, MIME-type detection and component-parameter reflection.
  • Nextended.UI — WPF and Windows desktop helpers — a global input-binding manager with hold/sequence matching, DirectInput and XInput gamepad readers, key-bind capture controls, converters, behaviours, markup extensions and runtime-defined PropertyGrid types.

Code generation & tooling

  • Nextended.Imaging — Image processing — aspect-preserving resize, crop, colour replacement, brightness-based foreground picking, thumbnail generation, byte/data-URL conversion and MIME detection from magic bytes.
  • Nextended.CodeGen — Roslyn source generator — DTOs and interfaces from your entities, strongly typed classes from JSON/XML, lookup tables from Excel, and documentation from source files.

.NET Aspire hosting

  • Nextended.Aspire — Conditional AppHost builder extensions — WithReferenceIf / WaitForIf / WithExplicitStartIf, strongly typed environment variables from config objects, HTTPS dev-cert wiring, Docker guards, GitHub-source resources and npm app discovery.
  • Nextended.Aspire.Hosting.Supabase — The complete Supabase stack — Postgres, Auth (GoTrue), REST, Realtime, Storage, Studio, Kong and Edge Functions — as one composable Aspire resource.
  • Nextended.Aspire.Hosting.N8n — The n8n workflow-automation platform as an Aspire resource, with Postgres persistence, workflow import and a typed client for triggering workflows from .NET.
  • Nextended.Aspire.Hosting.Grafana — Grafana, Prometheus, Loki, Tempo, Promtail, cAdvisor, postgres_exporter and the OpenTelemetry Collector as composable resources with auto-provisioned datasources.
  • Nextended.Aspire.Hosting.WebDataStudio — WebDataStudio — a browser database studio for PostgreSQL, MySQL, SQL Server, SQLite, Oracle, DuckDB, ClickHouse, MongoDB and Redis — wired to the databases of your stack, with accounts and roles, an optional SQL assistant, and an MCP endpoint for AI agents. (this package)
  • Nextended.Aspire.Hosting.AspireUI — AspireUI — the visual AppHost builder — as a resource inside your own Aspire stack, with an optional pre-seeded admin user and a starter stack built from your project paths.
  • Nextended.Aspire.Hosting.LocalAI — Self-hosted, OpenAI-compatible multimodal AI — image generation, text-to-speech, speech-to-text and video — with gallery model management, GPU support and Open WebUI.
  • Nextended.Aspire.Hosting.Php — Run PHP endpoints inside your Aspire stack — a docroot folder or a single router script served by PHP's built-in web server, with php.ini settings as fluent options.

License

GPL-3.0-or-later — see LICENSE.

Product Compatible and additional computed target framework versions.
.NET net8.0 is compatible.  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 is compatible.  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

This package is not used by any NuGet packages.

GitHub repositories

This package is not used by any popular GitHub repositories.

Version Downloads Last Updated
10.1.33 0 8/24/2026
10.1.32 111 8/20/2026
10.1.31 50 8/19/2026
10.1.30 44 8/19/2026