BridgeEditor 3.2.2

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

BridgeEditor

BridgeEditor is an extensible Persian-first content editor for interactive Blazor applications. Version 3.2.2 adds row-height resizing and safer table dimension gestures; version 3.2.1 improved sticky toolbar behavior, long-content fullscreen scrolling, and legacy/interactive table resizing and reordering. Version 3.2 added opt-in realtime collaboration with conflict-safe block/text operations, live presence, remote selections and cursors, idempotent replay, reconnect, and an offline operation queue. Version 3.1 added asynchronous review collaboration: anchored comments, replies, mentions, tracked suggestions, accept/reject review, roles, activity, and named versions. Version 3 introduced the structured Document Model, semantic blocks, block Inspector, drag-and-drop ordering, portable JSON, legacy-HTML migration, and code-first Plugin SDK. HTML-only mode remains the default, so existing consumers keep the version 1 and 2 markup, asset paths, and sanitized HTML contract. The editor also includes RTL/LTR authoring, a bilingual UI, responsive/fullscreen layouts, reusable templates, media, Markdown, clean Word/Google Docs paste, tables, safe embeds, validated uploads, local drafts, application-owned revisions, a .NET sanitizer, and bundled Vazirmatn.

Future collaboration, review, operations, and governance work is tracked in the BridgeEditor roadmap.

Install

dotnet add package BridgeEditor

Import the component namespace in _Imports.razor:

@using BridgeEditor.Components

Reference the packaged static assets in App.razor. The script must load before Blazor starts because the component can initialize during its first interactive render.

<link rel="stylesheet" href="@Assets["_content/BridgeEditor/css/bridge-editor.css"]" />
<script src="@Assets["_content/BridgeEditor/js/bridge-editor.js"]"></script>
<script src="_framework/blazor.web.js"></script>

For a WebAssembly wwwroot/index.html host, use the same _content/BridgeEditor/... paths without the @Assets[...] wrapper.

Usage

<BridgeEditor @ref="editor"
              @bind-Value="html"
              UploadUrl="/api/media/upload"
              VideoUploadUrl="/api/media/upload/video"
              ToolbarPreset="BridgeEditorToolbarPreset.Standard"
              DraftKey="@($"blog-post-{postId}")"
              AutoSaveDelayMilliseconds="2000"
              ChangeDebounceMilliseconds="150"
              MaxWords="1200"
              MaxCharacters="12000"
              MaxImageBytes="@(5 * 1024 * 1024)"
              MaxVideoBytes="@(25 * 1024 * 1024)"
              Placeholder="محتوای خود را اینجا بنویسید…"
              MinHeight="360"
              EnableSourceMode="true"
              OnUploadFailed="HandleUploadFailure" />

@code {
    private BridgeEditor? editor;
    private string? html;

    private void HandleUploadFailure(BridgeEditorUploadEventArgs args)
    {
        // Display or log args.Error.
    }

    private async Task SaveAsync()
    {
        await (editor?.CommitAsync() ?? Task.CompletedTask);
        // Persist html here.
    }
}

UploadUrl is optional. When configured, the editor sends the selected file as a multipart field named file and includes every entry from UploadFields. The field name, credentials, request headers, timeout, accepted MIME types, and client-side image/video size limits are configurable. The endpoint response can be { "location": "/media/file.webp" }, { "url": "/media/file.webp" }, or a JSON string containing the uploaded URL.

DraftKey is also optional. A non-empty, stable key enables debounced autosave in the browser's local storage. RestoreDraftOnInit is opt-in; applications can instead call SaveDraftAsync(), RestoreDraftAsync(), and ClearDraftAsync() explicitly. Drafts are local recovery aids and do not replace server persistence.

Version 3.2 realtime collaboration

Realtime editing is an opt-in layer over the structured document model. BridgeEditor owns the protocol, local conflict resolution, cursor UI, reconnect loop, and offline queue. The application owns authentication and the transport. This keeps the package usable with SignalR, WebSockets, a hosted collaboration service, or an existing message gateway without embedding product-specific infrastructure.

@inject IBridgeEditorRealtimeTransport RealtimeTransport

<BridgeEditor @ref="editor"
              @bind-Value="html"
              @bind-Document="document"
              StorageMode="BridgeEditorStorageMode.HtmlAndDocument"
              EnableRealtimeCollaboration="true"
              RealtimeTransport="RealtimeTransport"
              RealtimeDocumentKey="@($"blog:{postId}")"
              RealtimeClientId="browserTabId"
              CurrentCollaborator="currentUser"
              OnRealtimeConnectionStateChanged="HandleRealtimeState"
              OnRealtimePresenceChanged="HandlePresence" />

Implement IBridgeEditorRealtimeTransport.ConnectAsync(...) with the application's authorized realtime channel. A connection returns an IBridgeEditorRealtimeSession, the room baseline, operations after that baseline, active peers, and operation IDs already represented by the baseline/history. The session publishes local operations and presence and exposes an ordered IAsyncEnumerable<BridgeEditorRealtimeMessage> for remote changes.

The join operation must be gap-free: capture the baseline, missed operations, and live subscription atomically. Validate document access, collaborator identity, client identity, role, payload limits, and every operation on the server. Treat OperationId as an idempotency key. IDs returned in AcknowledgedOperationIds must already be represented by either InitialDocument or InitialOperations; this prevents an accepted operation from being applied twice when its acknowledgement was lost.

BridgeEditor 3.2 resolves concurrent changes without exchanging or overwriting the entire HTML value:

  • block inserts and moves use deterministic variable-length positions;
  • block metadata and document settings use Lamport last-writer-wins registers with stable tie-breaking;
  • serialized block content uses stable character IDs, predecessor links, and deletion tombstones;
  • operation IDs make reconnect, echo, and retry idempotent;
  • remote changes preserve the local block-relative selection before patching the DOM;
  • live presence includes active/idle state and block-relative selections rendered as colored ranges and cursors.

Unacknowledged operations are retained in a browser-local queue and replayed after reconnect. Persist the structured Document with its stable document/block IDs. Provide a stable, unique-per-tab RealtimeClientId if queued changes must survive a full page reload; two simultaneously open tabs must not share the same client ID. A production transport should retain the operation history for its baseline epoch or implement equivalent snapshot/epoch compaction before accepting very old offline operations.

For demos, tests, and a single-process deployment, register the included reference transport:

builder.Services.AddSingleton<IBridgeEditorRealtimeTransport, BridgeEditorInMemoryRealtimeTransport>();

BridgeEditorInMemoryRealtimeTransport is intentionally process-local, non-durable, and capped at 50,000 retained operations per room. Use a durable/distributed adapter in a multi-instance or production deployment. Realtime collaboration requires Document or HtmlAndDocument; enabling it in HTML-only mode fails closed and reports the Error connection state. Review collaboration remains independently opt-in, so an application may use realtime editing, review workflows, or both.

Version 3.1 review collaboration

Review collaboration is opt-in and asynchronous. BridgeEditor supplies the editor UI, role-aware workflow, portable suggestion markup, and .NET contracts; the consuming application owns authenticated user identity, authorization, persistence, concurrency, retention, mentions/notifications, and database transactions.

<BridgeEditor @ref="editor"
              @bind-Value="html"
              @bind-Document="document"
              StorageMode="BridgeEditorStorageMode.HtmlAndDocument"
              EnableCollaboration="true"
              CollaborationStore="collaborationStore"
              CollaborationDocumentKey="@($"blog:{postId}")"
              CurrentCollaborator="currentUser"
              MentionCandidates="team"
              OnCommentThreadChanged="HandleCommentChanged"
              OnSuggestionChanged="HandleSuggestionChanged" />

@code {
    private BridgeEditor? editor;
    private string? html;
    private BridgeEditorDocument? document;

    private readonly BridgeEditorCollaborator currentUser = new()
    {
        Id = "user-42",
        DisplayName = "سارا احمدی",
        Role = BridgeEditorCollaborationRole.Editor
    };

    private IBridgeEditorCollaborationStore collaborationStore = default!;
    private IReadOnlyList<BridgeEditorCollaborator> team = [];
}

Implement IBridgeEditorCollaborationStore with your database or API. Required operations cover comment listing/creation/replies/status. The interface also provides default no-op activity and named-version methods, so those surfaces can be added incrementally. Plain comment bodies are always rendered as text. Mention IDs are filtered against MentionCandidates, but the store must still validate document access and every actor/action independently; client roles are user experience controls, not a security boundary.

The built-in roles are:

  • Viewer: read content, comments, suggestions, activity, and versions.
  • Commenter: add comments, replies, and mentions.
  • Reviewer: comment and edit only through Suggestion mode.
  • Editor: direct editing plus accept/reject, resolve/reopen, and named versions.
  • Owner: the full built-in capability set; application-specific administration remains outside BridgeEditor.

Suggestion mode records insertions and deletions with portable <ins>/<del> metadata. Pending suggestions remain in Value, Document, snapshots, revisions, and named versions until reviewed. Before publishing content, request finalized output instead of exposing review markup:

string publishableHtml = await editor.GetPublishedHtmlAsync();
IReadOnlyList<BridgeEditorSuggestion> pending = await editor.GetSuggestionsAsync();

// Server-side equivalent for a background publish pipeline:
string serverPublishableHtml = new BridgeEditorReviewHtmlProcessor().AcceptAll(storedReviewHtml);

await editor.SetSuggestionModeAsync(true);
await editor.AcceptSuggestionAsync(suggestionId);
await editor.RejectSuggestionAsync(otherSuggestionId);
await editor.OpenCollaborationAsync();

GetPublishedHtmlAsync() returns a copy with pending insertions accepted, pending deletions removed, and suggestion metadata stripped; it does not mutate the editor. BridgeEditorHtmlSanitizer preserves the strict set of ins, del, and data-bridge-suggestion-* attributes required for safe review round-trips.

Named versions are immutable checkpoints separate from automatic revision history. The activity timeline records comment, suggestion, and named-version lifecycle events through the application store. Review persistence remains separate from the optional version 3.2 realtime transport.

Version 3 structured documents

Structured editing is deliberately opt-in. Choose Document or HtmlAndDocument storage mode, bind a BridgeEditorDocument, and continue binding Value when the application also needs rendered HTML:

<BridgeEditor @ref="editor"
              @bind-Value="html"
              @bind-Document="document"
              StorageMode="BridgeEditorStorageMode.HtmlAndDocument"
              Plugins="plugins"
              EnableBlockInspector="true"
              EnableBlockDragDrop="true" />

@code {
    private BridgeEditor? editor;
    private string? html;
    private BridgeEditorDocument? document;
}

Each document has a schema version, stable ID, direction, metadata, and ordered blocks. Each block has its own stable ID, normalized type, version, sanitized HTML, and application-owned string data. Editor-only selection classes, drag controls, and data-bridge-* attributes never appear in compatibility HTML.

Use the public APIs to exchange documents or migrate existing content:

BridgeEditorDocument migrated = await editor.MigrateHtmlToDocumentAsync(legacyHtml);
await editor.SetStructuredDocumentAsync(migrated);

string json = await editor.GetDocumentJsonAsync(indented: true);
bool imported = await editor.SetDocumentJsonAsync(json);
string safeHtml = editor.RenderDocumentHtml(migrated);

The built-in document toolbar command opens the block outline and JSON import/export surface. Snapshot schema 2 includes both compatibility HTML and the structured document; schema 1 snapshots from version 2 remain importable.

Block Plugin SDK

Plugins are application-owned definitions, not executable scripts. They provide sanitized initial HTML and declarative Inspector mappings to text or an allowed attribute (href, src, alt, or title):

private static readonly BridgeEditorPluginDefinition[] plugins =
[
    new()
    {
        Name = "product-card",
        DisplayName = "کارت محصول",
        Category = "فروشگاه",
        Version = 1,
        InitialHtml = "<article><h3>نام محصول</h3><p>توضیح</p><a href=\"/products\">مشاهده</a></article>",
        InspectorFields =
        [
            new() { Name = "title", Label = "عنوان", Selector = "h3", Kind = BridgeEditorInspectorFieldKind.Text },
            new() { Name = "description", Label = "توضیح", Selector = "p", Kind = BridgeEditorInspectorFieldKind.Multiline },
            new() { Name = "url", Label = "پیوند", Selector = "a", Attribute = "href", Kind = BridgeEditorInspectorFieldKind.Url }
        ]
    }
];

For code-first registration, implement IBridgeEditorPlugin and add definitions to BridgeEditorPluginRegistry; pass registry.Definitions to the component. URL fields use the same safe-URL policy as editor links and media.

Version 2.2 authoring

Set UiCulture="en" for the built-in English UI; Persian remains the backward-compatible default. TranslationOverrides can replace individual built-in strings without forking the JavaScript asset.

Reusable blocks are available from the blocks toolbar item and by typing / in an empty paragraph. BridgeEditor includes info, warning, success, quote, code, and button blocks. Applications can append sanitized templates:

<BridgeEditor @bind-Value="html"
              Templates="templates"
              MediaLibraryItems="media"
              UiCulture="fa" />

@code {
    private static readonly BridgeEditorTemplateDefinition[] templates =
    [
        new()
        {
            Name = "product-highlight",
            Label = "معرفی محصول",
            Category = "فروشگاه",
            Html = "<aside class=\"pe-callout pe-callout--info\"><h3>محصول</h3><p>توضیح</p></aside>"
        }
    ];

    private static readonly BridgeEditorMediaItem[] media =
    [
        new() { Url = "/media/product.webp", Title = "Product", AlternativeText = "Product image" }
    ];
}

SetMediaLibraryAsync(...) refreshes media while an editor instance is running. The image preparation dialog supports center crop ratios, maximum dimensions, output quality, and alternative text. Set OptimizeImagesBeforeUpload="true" to optimize pasted and dropped raster images too; it is off by default so existing upload bytes remain unchanged.

Markdown-looking plain text is recognized in the default clean paste mode. Use PasteMode="BridgeEditorPasteMode.PlainText" or Markdown to force a mode. GetMarkdownAsync() and SetMarkdownAsync(...) provide explicit conversion APIs.

Server revisions

Implement IBridgeEditorRevisionStore with your database or API, then provide a stable document key. BridgeEditor owns debounce and UI; the application owns authorization, persistence, retention, and concurrency policy.

<BridgeEditor @ref="editor"
              @bind-Value="html"
              RevisionStore="revisionStore"
              RevisionDocumentKey="@($"blog:{postId}")"
              RevisionAuthor="@userName"
              AutoSaveServerRevisions="true"
              ServerAutoSaveDelayMilliseconds="5000"
              OnRevisionSaveFailed="HandleRevisionError" />

The built-in history command lists, previews, and restores revisions. Applications can also call SaveServerRevisionAsync() and RestoreServerRevisionAsync(...) directly. A store is optional; when absent, version 2.1 draft behavior is unchanged.

Server sanitization

BridgeEditorHtmlSanitizer parses untrusted HTML with AngleSharp and rebuilds it from an allow-list. It removes dangerous elements, event handlers, unsafe URLs and CSS, restricts embeds to normalized YouTube/Vimeo URLs, and enforces noopener noreferrer for new-tab links.

IBridgeEditorHtmlSanitizer sanitizer = new BridgeEditorHtmlSanitizer(options =>
{
    options.AllowedTags.Add("mark");
});

var safeHtml = sanitizer.Sanitize(untrustedHtml);

Version 2 extensibility

Register application-owned commands without forking the editor toolbar. Labels are rendered as text, command names are normalized, and the callback receives both the command name and the current sanitized HTML.

<BridgeEditor @ref="editor"
              @bind-Value="html"
              CustomCommands="commands"
              OnCustomCommand="HandleCommand"
              OnMetricsChanged="HandleMetrics"
              MaxWords="1200" />

@code {
    private BridgeEditor? editor;
    private string? html;
    private BridgeEditorContentMetrics metrics = new();
    private static readonly BridgeEditorCommandDefinition[] commands =
    [
        new() { Name = "callout", Label = "Callout", Title = "Insert a product callout" }
    ];

    private Task HandleCommand(BridgeEditorCommandEventArgs args)
    {
        // Apply application-specific behavior based on args.Name and args.Html.
        return Task.CompletedTask;
    }

    private void HandleMetrics(BridgeEditorContentMetrics value) => metrics = value;
}

MaxWords and MaxCharacters are advisory: the status bar and OnMetricsChanged report the limit state without silently deleting user content. Use GetMetricsAsync() before persistence when a hard validation rule is required.

Portable snapshots include sanitized HTML, plain text, metrics, direction, capture time, and a schema version:

BridgeEditorDocumentSnapshot snapshot = await editor.ExportDocumentAsync();
await editor.ImportDocumentAsync(snapshot);

Toolbar profiles

  • Minimal: undo/redo, block type, basic emphasis, lists, link, direction, fullscreen, and help.
  • Standard: common CMS authoring commands, blocks, the structured-document outline when enabled, media library, revision history when configured, nested-list indentation, find/replace, advanced tables, uploads, and safe embeds without unrestricted font/color or HTML source controls.
  • Full: every built-in command and the backward-compatible default.

Use ToolbarItems to override the selected profile with an explicit command allow-list:

<BridgeEditor @bind-Value="html"
              ToolbarItems="toolbarItems" />

@code {
    private static readonly string[] toolbarItems =
        ["undo", "redo", "bold", "italic", "link"];
}

Supported built-in toolbar item names are undo, redo, block, bold, italic, underline, strike, unordered-list, ordered-list, indent, outdent, align-right, align-center, align-left, align-justify, font-family, font-size, text-color, background-color, clear-format, link, table, blocks, document, image, video, media-library, embed, find-replace, history, collaboration, horizontal-rule, direction, source, fullscreen, and help. Custom command names can also be included when an explicit ToolbarItems allow-list is used.

The font selector includes the bundled Vazirmatn variable font and web-safe fallbacks. Applications that render saved editor HTML on pages where the editor stylesheet is not loaded should provide their own matching @font-face declaration so Vazirmatn-formatted content renders identically outside the editor.

The inline table toolbar can move a table up or down, reset the active row height or all table dimensions, add or delete rows and columns, toggle a header row, add a caption, merge a cell with its next neighbour, split a merged cell, and delete the table. Selecting a table exposes pointer/touch handles for reordering the whole table, resizing the table, resizing individual columns with RTL/LTR-aware movement, and resizing every row vertically. Column resize targeting follows logical columns across colspan cells, so handles remain available after a merge. Focus a resize handle and use the arrow keys for an 8-pixel adjustment or Shift plus an arrow key for 24 pixels. Click-only or cancelled resize gestures restore the original dimensions. Coarse-pointer devices receive larger touch targets. Legacy tables without pe-table are normalized automatically. The media toolbar edits alignment, width, title, image alternative text, and caption. Embedded iframes are limited to normalized YouTube and Vimeo URLs and receive restrictive browser attributes.

The main toolbar is sticky by default, and the contextual table toolbar follows it. If the host application has its own fixed header, set the offset on the editor host or a surrounding scope:

.bridge-editor-host {
    --pe-sticky-offset: 64px;
}

Interaction and events

ReadOnly keeps selection and copying available while preventing edits. Disabled prevents editing and disables every editor control. Both properties can change while the component is running, or can be changed through SetStateAsync(...).

The component exposes OnReady, OnFocus, OnBlur, OnChange, OnMetricsChanged, OnCustomCommand, OnBlockSelected, DocumentChanged, OnDraftSaved, OnDraftRestored, OnUploadStarted, OnUploadProgress, OnUploadCompleted, and OnUploadFailed. Upload callbacks receive a BridgeEditorUploadEventArgs value containing file metadata, progress, result URL, and error details.

Public API

  • Two-way binding: Value / ValueChanged
  • Lifecycle: AutoInit, InitAsync(), DestroyAsync()
  • Content: GetHtmlAsync(), SetHtmlAsync(...), GetMarkdownAsync(), SetMarkdownAsync(...), CommitAsync(), ExecuteCommandAsync(...), GetMetricsAsync(), ExportDocumentAsync(), ImportDocumentAsync(...)
  • Structured documents: StorageMode, Document / DocumentChanged, GetStructuredDocumentAsync(), SetStructuredDocumentAsync(...), GetDocumentJsonAsync(...), SetDocumentJsonAsync(...), MigrateHtmlToDocumentAsync(...), RenderDocumentHtml(...)
  • Structured blocks: Plugins, EnableBlockInspector, EnableBlockDragDrop, OnBlockSelected, IBridgeEditorPlugin, BridgeEditorPluginRegistry
  • Presentation: Direction, UiCulture, TranslationOverrides, Placeholder, AriaLabel, MinHeight, EnableSourceMode, ShowHeader, ShowStatusBar
  • Toolbar: ToolbarPreset, ToolbarItems, CustomCommands, OnCustomCommand
  • Blocks/media: Templates, IncludeBuiltInTemplates, EnableSlashCommands, MediaLibraryItems, SetMediaLibraryAsync(...), EnableImageEditor, OptimizeImagesBeforeUpload, MaxImageDimension, ImageQuality
  • Paste: PasteMode, EnableMarkdownPaste
  • Validation: MaxWords, MaxCharacters, ChangeDebounceMilliseconds, OnMetricsChanged
  • State: ReadOnly, Disabled, SetStateAsync(...)
  • Drafts: DraftKey, AutoSaveDelayMilliseconds, RestoreDraftOnInit, SaveDraftAsync(), RestoreDraftAsync(), ClearDraftAsync()
  • Uploads: UploadUrl, VideoUploadUrl, UploadFields, UploadFieldName, UploadHeaders, UploadWithCredentials, ImageAccept, VideoAccept, MaxImageBytes, MaxVideoBytes, UploadTimeoutMilliseconds
  • Revisions: RevisionStore, RevisionDocumentKey, RevisionAuthor, AutoSaveServerRevisions, ServerAutoSaveDelayMilliseconds, RevisionHistoryLimit, SaveServerRevisionAsync(), RestoreServerRevisionAsync(...)
  • Security: HtmlSanitizer, SanitizeHtml(...)
  • Events: OnReady, OnFocus, OnBlur, OnChange, DocumentChanged, OnBlockSelected, OnMetricsChanged, OnCustomCommand, OnDraftSaved, OnDraftRestored, OnUploadStarted, OnUploadProgress, OnUploadCompleted, OnUploadFailed, OnRevisionSaved, OnRevisionRestored, OnRevisionSaveFailed

Upgrading from 1.x or 2.x

Version 3 preserves existing component parameters, JavaScript/CSS asset paths, HTML output, and defaults. Existing consumers can update the package without changing markup because StorageMode defaults to Html. To adopt blocks gradually, first call MigrateHtmlToDocumentAsync, persist the returned JSON beside existing HTML, and then switch selected screens to HtmlAndDocument. New exports use snapshot schema 2; imports accept both schema 1 and 2.

Version 3 does not include real-time collaboration or AI authoring. Those capabilities require separate persistence, authorization, conflict-resolution, and provider contracts and are intentionally outside the 3.0 foundation.

Demo and tests

dotnet run --project samples/BridgeEditor.Demo
dotnet test tests/BridgeEditor.Tests

The client-side sanitizer and upload checks are defense in depth for the editing experience. Applications must still validate uploads and sanitize untrusted HTML on the server before storing or rendering it. BridgeEditorHtmlSanitizer supplies a safe default policy, but authorization and storage validation remain application responsibilities.

License

MIT

BridgeEditor is developed by BridgeGroup. The bundled Vazirmatn font is licensed separately under the SIL Open Font License; see THIRD-PARTY-NOTICES.md in the package.

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

NuGet packages

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
3.2.2 330 7/26/2026
3.2.1 116 7/26/2026
3.2.0 116 7/21/2026
3.1.0 113 7/20/2026
3.0.0 123 7/20/2026
2.2.0 117 7/20/2026
2.1.0 113 7/20/2026
2.0.0 114 7/19/2026
1.2.0 108 7/19/2026
1.1.0 120 7/19/2026
1.0.0 117 7/19/2026
1.0.0-gbd34cdba77 106 7/19/2026