jfk-solutions.TiaFileFormat 2026.10.20.2

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

Info

TiaFileFormat a Library to access all Tia Portal project Files from Version V10.5 - V20

Package

https://www.nuget.org/packages/jfk-solutions.TiaFileFormat/

Homepage

https://github.com/jfk-solutions/TiaFileFormat

Documentation

PLC start values in Automation XML

Start values preserve the stored literal text. DINT#10000 and 10000, or 2 and 16#02 for a Byte, can represent the same typed value while producing different XML text. The converter preserves their spelling, matching TIA's Automation XML export behavior.

Values in project archives can be sparse. An absent array-element value is not an explicit zero; it inherits its declaration/type default. The CPU's source can include explicit zeros that were absent from the offline value table. TIA's default Automation XML export also omits members inside referenced types when they have neither values nor comments, unless defaults are requested. Use WithDefaultsInInterface when a complete interface export is required, and compare typed values and effective defaults when comparing software. Instance DB values can override FB defaults and must not be discarded merely because they are zero.

Project loading

The default loading mode reads project data sequentially and works with project archives, standalone database streams, and unpacked projects without an index:

using var provider = TiaFileProvider.CreateFromSingleFile(projectPath);
var project = TiaProject.Load(provider);

The same API opens unpacked global libraries (.alxx) and archived global libraries (.zalxx). Archives are detected by their ZIP contents, without a version-specific extension list, and the database is read from System/PEData.plf at the archive root or inside its library folder. An unpacked .alxx descriptor requires the accompanying library directory, including System. TiaProject.Library identifies a standalone library, Archive identifies an archive, and Database.LibraryRoot exposes the library tree. Project/library name and version metadata are also loaded from descriptors inside archives.

Unpacked projects with a supported System/PEData.idx can load database object payloads on demand instead:

var project = TiaProject.Load(provider, useIndex: true);

To ignore an existing index and force the original sequential behavior:

var project = TiaProject.Load(provider, useIndex: false);

The same useIndex parameter is available on TiaDatabaseFile.Load. Indexed loading also defers business-object headers and object allocation. Use the type-aware block lookup to preserve that behavior during exports:

foreach (var storageObject in CodeBlockConverter.FindConvertibleObjects(
             project.Database, prioritizeLargeObjects: true))
{
    // Convert matching PLC block objects in a balanced order for parallel export.
}

Omit prioritizeLargeObjects or set it to false when the original database order is required.

StorageObjectCount, MaterializedStorageObjectCount, IndexedHeaderReadCount, IndexedPayloadReadCount, IndexedPayloadBytesRead, and IndexedHashReadCount show how many indexed objects and payloads were actually touched. Accessing the legacy StorageObjectDictionary, StorageObjects, or AllStorageObjects properties still materializes every object to preserve existing behavior. Explicitly enabling indexed loading uses a supported index from an unpacked project. If the index is missing or belongs to an older project format, the loader ignores it automatically and uses the sequential path. A present but malformed index still causes loading to fail. Archives remain available through the default or explicitly disabled mode.

Online backups

Read saved online backups from a project without connecting to the PLC:

using TiaFileFormat.Wrappers.Online;

var index = 0;
foreach (var backup in OnlineBackupConverter.ReadAll(project))
{
    Console.WriteLine($"{backup.Name}: {backup.LoadType}, {backup.Elements.Count} elements");
    if (backup.Image != null)
        File.WriteAllBytes($"backup-{index}.bin", backup.Image);
    foreach (var diagnostic in backup.Diagnostics)
        Console.WriteLine(diagnostic);
    index++;
}

ReadAll supports sequential and indexed databases. Read(storageObject) reads one backup. The converter is registered in HighLevelObjectConverterWrapper as HighLevelObjectType.OnlineBackup.

S7 Plus backups (S7PLUSBACKUP) contain numbered chunks of one image, rather than individual PLC blocks. The reader joins them in numeric BlockNumber order, rejecting missing, duplicate, negative or empty chunks. ImageHeader decodes the observed version 2 Siemens !CP outer header. Unsupported headers produce diagnostics while retaining the assembled image and original elements. Classic backups (S7BACKUP) expose individual payloads and decoded compact block headers, including block number, language/type codes and section lengths. Unknown load types retain their original elements with a diagnostic.

Inner S7 Plus PLC code, configuration and values are not decoded yet. Classic MC7 instructions and values also remain binary. Header recognition does not validate image checksums or establish that an image can be restored to a CPU. The original bytes are preserved for further analysis. Local verification used the V21 JochensHaus backup: 137 chunks and a 1,109,651-byte image, identical with sequential and indexed loading. Classic header parsing has synthetic test coverage; a real classic backup has not been validated.

Offline traces

Read trace configurations, saved recordings, measurements, and trace folders directly from an opened project:

using TiaFileFormat.Wrappers.Controller.Traces;

foreach (var trace in TraceConverter.ReadAll(project))
{
    Console.WriteLine($"{trace.Name}: {trace.Signals.Count} signals");
    foreach (var sample in trace.Samples?.Rows ?? Enumerable.Empty<TraceSample>())
        Console.WriteLine($"{sample.Index}: {string.Join(", ", sample.Values)}");
}

TraceConverter is also registered in HighLevelObjectConverterWrapper as HighLevelObjectType.PlcTrace. Read(storageObject) reads an individual trace; ReadAll(database) supports database streams and indexed discovery. ReadAll returns each supported object once; folders and combined recordings also expose their aggregated objects through Items.

Standalone TIA Portal recording exports (.ttrecx) return the same Trace model, including the same typed sample rows and signal column mapping:

var trace = TraceConverter.ReadExport(@"C:\traces\recording.ttrecx");
// A Stream overload is also available and leaves the caller's stream open.

Exported traces have no StorageBusinessObject. Their device settings map to Acquisition and XmlDocuments["Strategy"], as for project traces. General and compatibility XML documents are retained in XmlDocuments; compatibility signal copies do not create duplicate signals.

The wrapper exposes signal names, labels, addresses, types, comments and units, PLC acquisition/trigger settings, recording times and sample counts. Original signal, strategy and presentation XML is available in XmlDocuments. Standard TSP:1.0 and TSP:2.0 recordings expose typed sample rows; column IDs and types are in Samples.SignalIds and Samples.SignalTypes. Invalid values are null. Raw timestamps are retained in nanoseconds without assuming a wall-clock epoch; dropped samples are excluded from Rows.

SamplePayload retains the binary data. Unsupported or malformed payloads and XML produce Diagnostics while retaining the available metadata. Long-term recordings stored in external files, legacy sample-root/block layouts, combined time-axis alignment, and calculated-signal evaluation are not decoded yet. Validation includes 42 saved recordings from a local V17 project and automated tests for sample types, validity, multiple blocks, linked payloads and malformed data.

Automation XML compatibility

Existing calls keep the established V21 serialization conventions. To match TIA Portal V19 PLC block/type XML, select V19 explicitly:

using TiaFileFormat.Wrappers.Converters.AutomationXml;

var xml = block.ToAutomationXml(new AutomationXmlConverter.ConvertOptions
{
    Compatibility = AutomationXmlConverter.CompatibilityMode.V19,
    WriteCommentAndTitleAlthoughWhenEmpty = true,
});

The same options work with WriteAutomationXml. V19 mode writes interface and LAD/FBD/STL/SCL network XML as separately indented fragments, includes fail-safe memory layout, and exports author/family/version metadata for locked blocks. Implementation details of locked blocks remain suppressed. Existing switches, including WithDefaultsInInterface and WithReadOnlyAttributes, still apply. IncludeFailSafeMemoryLayout can also be enabled independently in V21 mode.

Full inherited declarations reuse a bounded, per-interface cache of XML writer operations. Repeated unchanged sections keep the same XML bytes, including formatting and escaping. Sections with instance values, comments, or accessed mutable children follow normal serialization. The cache is discarded after each interface export; set CacheInheritedInterfaceDeclarations = false to disable it.

Instance expansion also bypasses unchanged intermediate clone generations and allocates scalar members' mutable child lists only when accessed. Observed child lists and deferred default overlays retain their normal cloning path, preserving later edits, per-instance parent links, inherited defaults and sparse comments.

The mode controls serialization conventions; it does not convert a project to another TIA version or change the document's project version. It is not selected automatically from the project version, so existing callers retain their output. Other TIA versions and non-PLC exporters have no version-specific profile yet.

V19 was compared against Openness V19 Update 5 using a copy of Software1500_6.6.0-8014b79b: all 425 exported blocks/types matched byte for byte after excluding the UTF-8 BOM and Openness DocumentInfo metadata. FOB_RTG1 was excluded. The six reported AWL blocks exported successfully; template category casing is corrected in both modes. This comparison covers XML exports, not a separate source-format export_all run. The default output was also compared with the unmodified converter on MixedSample.ap21: all 64 exports were byte-identical.

Password-protected blocks

Pass passwords when converting storage objects, before calling ToAutomationXml:

var readOptions = new TiaFileFormat.Wrappers.ConvertOptions();
readOptions.EncryptionOptions.EncryptionPasswordsPerBlock[blockName] = password;
// Alternatively, add candidate passwords to EncryptionPasswords.
var block = (BaseBlock)new CodeBlockConverter().Convert(storageObject, readOptions);
var xml = block.ToAutomationXml(xmlOptions);

Password-based decryption is independent of V19/V21 XML compatibility. Successfully decrypted blocks export their implementation even while IsKowHowProtected remains true; DecryptionPossible records successful decryption. For supported protection formats, a missing or incorrect password leaves the block locked; the XML exporter still exports its available interface and metadata. Do not skip conversion solely because a block is protected, and do not set DecryptionPossible manually. A password cannot make an unsupported protection format decryptable; unsupported protection versions currently raise an exception during conversion. When retrying with a password, reconvert the original storage object with fresh read options; XML serialization itself does not try passwords.

Offline block call paths

BlockCallPathCatalogBuilder builds call sites, instance-DB associations, and complete calling paths directly from an offline TIA project:

using TiaFileFormat.Wrappers.CodeBlocks.CallPaths;

var catalog = BlockCallPathCatalogBuilder.Build(project);

foreach (var path in catalog.CallingPaths)
{
    Console.WriteLine(path.DisplayName);
}

If the blocks were converted already, avoid loading them again:

var catalog = BlockCallPathCatalogBuilder.BuildFromBlocks(blocks);

The protocol-neutral BuildFromCatalogData entry point is available to online adapters and other block sources that already provide resolved call sites.

TIA catalog caches and extraction tool

TIA project and online block data can reference definitions that are installed with TIA Portal rather than stored completely in the project or transmitted by the CPU. Build portable caches once on a machine with the required TIA libraries, then deploy those cache files with your application. No environment variable is required to load them: both hardware and online conversion use explicit CatalogSources options.

Cache What it contains Why it is needed
hardware.mddcache AML mode: channel definitions and component identities. Hardware mode additionally includes supported drawing descriptors and their assets Supplies catalog metadata without an installed TIA Portal
online.tialib Versioned system interface trees, types/arrays/constants, flags/defaults/AT aliases and named instruction-version mappings Resolves declarations referenced by online S7CommPlus blocks without reading installed TIA PLFs

Both cache creation APIs are public functions in the TiaFileFormat library, available to library customers directly through the resolvers' CreateCache methods:

using TiaFileFormat.Online;
using TiaFileFormat.Wrappers.Hardware.Mdd;

var hardwareResolver = new MddHardwareCatalogResolver(
    @"C:\Program Files\Siemens\Automation\Portal V21\Data");
var hardwareBuild = hardwareResolver.CreateCache(@"D:\TiaCatalogs\hardware.mddcache");

var onlineResolver = new OnlineLibraryCatalogResolver(
    @"C:\Program Files\Siemens\Automation\Portal V21\Lib");
var onlineCatalog = onlineResolver.CreateCache(
    @"D:\TiaCatalogs\online.tialib", Console.WriteLine);

The separate TiaCatalogCacheTool repository is a thin CLI that calls these public library APIs. It lives beside this checkout at ../TiaCatalogCacheTool; extraction and cache formats stay in TiaFileFormat. Run from this repository with .NET 8 or a compatible newer SDK and the normal TiaFileFormat license beside the tool executable (the existing TiaFileFormatLicensePath build property can copy an external license). This license mechanism is independent of cache loading.

# Both caches from one or several Portal installations.
dotnet run --project ../TiaCatalogCacheTool/TiaCatalogCacheTool.csproj -- all D:\TiaCatalogs "C:\Program Files\Siemens\Automation\Portal V21"

# Build just one cache. Additional source paths can follow the first path.
dotnet run --project ../TiaCatalogCacheTool/TiaCatalogCacheTool.csproj -- hardware D:\TiaCatalogs\hardware.mddcache "C:\Program Files\Siemens\Automation\Portal V21\Data"
dotnet run --project ../TiaCatalogCacheTool/TiaCatalogCacheTool.csproj -- online D:\TiaCatalogs\online.tialib "C:\Program Files\Siemens\Automation\Portal V21\Lib"
dotnet run --project ../TiaCatalogCacheTool/TiaCatalogCacheTool.csproj -- inspect D:\TiaCatalogs\online.tialib

all takes Portal folders containing both Lib and Data; it writes hardware.mddcache and online.tialib in the output directory. The hardware command also accepts MDD packages/files or existing hardware caches. The online command accepts Portal/Lib/copied library trees, Combining roots, System/PEData.plf files, existing .tialib caches or cache directories. With no online sources it discovers installed libraries. Full hardware extraction can take a while; progress, counts and decoding diagnostics are printed. Each output is replaced atomically after its build succeeds; the two outputs of all are independent builds.

Load both through conversion options:

using TiaFileFormat.Wrappers.Hardware;
using TiaFileFormat.S7CommPlus; // The S7CommPlus adapter package/source project.

var hardwareOptions = new HardwareConversionOptions
{
    CatalogSources = new[] { @"D:\TiaCatalogs\hardware.mddcache" }
};
var hardware = project.ToHardwareProject().ConvertAll(hardwareOptions);

var onlineOptions = new OnlineBlockConversionOptions
{
    CatalogSources = new[] { @"D:\TiaCatalogs\online.tialib" }
};
var block = OnlineBlockConverter.GetOnlineBlock(plcBlockContent, onlineOptions);

Each resolver also accepts a directory containing its cache files; both options above can use @"D:\TiaCatalogs". Reuse the options when converting multiple blocks so the online catalog is loaded once. Explicit online sources are independent of the adapter's legacy global configuration and installed-library discovery. Once online cache files are found, only those caches are used, with no raw PLF fallback. Several online caches merge exact named references and reject conflicting entries. Without explicit online options, the existing installed-library discovery remains.

Native applications can use new OnlineLibraryCatalogResolver(sources) and new MddHardwareCatalogResolver(sources) directly. Both expose CatalogSources and CreateCache(outputPath, progress); pass the online resolver's Resolve and ResolveInstructionVersion callbacks to CodeBlockConverter as shown in the online catalog documentation.

For V21 online extraction include Base, External, Safety and Technology Lib/<library>/Combining/System/PEData.plf databases. Preserve each System folder's index and split database companions during extraction. The lookup key is the exact version GUID plus interface part name: different controller variants can share a GUID. Executable library implementations and project databases are not retained. DB-specific layout and retention information still comes from the CPU.

V21 contains historical definitions but cannot guarantee all past or future TIA versions, optional libraries or firmware. Supply additional installations when a CPU references missing exact versions; conflicting references stop extraction. Rebuild after relevant TIA/library/hardware-support updates. The caches supply metadata; they do not replace protocol/language decoding, protected-block access, GSDML XML or other independently configured Siemens data. Full online format, source-file and version-coverage details are in docs/online-library-catalog.md.

Compact MDD catalog cache

Use the existing TiaCatalogCacheTool with --mode aml (the CLI default) for channel export, or --mode hardware for portable hardware rendering. Both modes retain package/entry identity, decode status, channel fields and qualified component declarations including versions. Hardware mode also retains the extracted view descriptor, selected supported Detailed (or Simplified fallback) view, XAML/raster resources, inherited descriptors, shared dictionaries and literal model labels. Project hierarchy, parameters, saved layout and slot ownership come from the project itself.

dotnet run --project ../TiaCatalogCacheTool -- hardware D:\TiaCatalogs\aml.mddcache "C:\Program Files\Siemens\Automation\Portal V21\Data" --mode aml
dotnet run --project ../TiaCatalogCacheTool -- hardware D:\TiaCatalogs\hardware.mddcache "C:\Program Files\Siemens\Automation\Portal V21\Data" --mode hardware --compression optimal

all accepts the same hardware options. Generate from the installed catalogs once, then deploy just the cache alongside the reader. Reading the supported native MDD metadata and drawings requires no TIA installation or runtime. Missing catalog entries, unsupported/computed drawings and incomplete dependencies remain explicit coverage diagnostics; a cache cannot supply metadata the extractor did not decode. External GSD/GSDML files remain separate and must be supplied through the project or configured sources. Cache files do not embed fonts or executable implementations.

Library callers can select the same contents:

using System.IO.Compression;
using TiaFileFormat.Wrappers.Hardware;
using TiaFileFormat.Wrappers.Hardware.Mdd;

var resolver = new MddHardwareCatalogResolver(new[] { @"C:\catalogs\Data" });
var build = resolver.CreateCache(@"D:\TiaCatalogs\hardware.mddcache",
    new MddCatalogCacheOptions {
        Mode = MddCatalogCacheMode.Hardware,
        Compression = CompressionLevel.Optimal,
        ResourceCacheBytes = 128L * 1024 * 1024
    }, cancellationToken: cancellationToken);

var options = new HardwareConversionOptions {
    CatalogSources = new[] { build.CacheFilePath },
    UseCatalogCacheFiles = true,
    CacheCatalogResults = true
};
var conversion = project.ToHardwareProject().ConvertAll(options);

The existing CreateCache(path, progress, cancellationToken) overload keeps its hardware-inclusive behavior. The options API also defaults to Hardware; CLI AML is an explicit lightweight default. Hardware caches can be reduced to AML mode; AML caches cannot be upgraded without raw catalogs. Existing cache versions 1–4 remain readable; version 5 records the content mode. Returned results retain their own mutable XML/byte arrays.

Caches already used gzip compression and shared content deduplication. Generation now reuses resource bytes with a bounded per-build budget and avoids exploratory string recovery during catalog lookup. Shared buffers are hashed once; identical independent assets are still deduplicated by SHA-256. --compression optimal (default) minimizes size; fast trades size for compression work; none keeps the gzip envelope without compression. --resource-cache-mib 0 disables build resource reuse (default 128, maximum 512). Timings, sizes, reuse hits, visual counts and coverage counts are printed. Existing per-resource and decoded-cache size limits still apply. Output replacement is atomic; cancellation preserves existing output.

Set UseCatalogCacheFiles = false to ignore .mddcache sources and use configured raw catalogs. Set CacheCatalogResults = false to disable result memoization. Direct resolver users have equivalent useCacheFiles and cacheResults constructor arguments. Source discovery/indexes are scoped to a resolver instance; create a new resolver after changing source files. No files are generated automatically by lookup. Rebuild portable caches after relevant catalog updates.

Hardware parameter values

Hardware conversion retains bounded persistent parameter trees with explicit Known, Opaque, Redacted and Unresolved states. Unsupported binary values keep their length and digest; secret fields remain redacted. Node and last-used IPv4/router/mask and MAC integers decode to address notation without truncating out-of-range values. Version 12.0.0.0 IPv6 collections in NodeIPv6Addresses and NetLastUsedIPv6Address decode all indexed address/prefix entries and the last-used index. Entry order and address spelling are canonicalized for comparison. Malformed or unsupported records remain opaque, rather than recovering isolated text from them.

Workspace HMI model dependency

When the sibling BaseHmiTypes repository is available at ../BaseHmiTypes, C# builds use its source project by default. This keeps the parser and HTML renderer aligned during development. Set -p:UseLocalBaseHmiTypes=false to validate the package dependency instead.

The package dependency is BaseHmiTypes 2026.10.4.1. This version has been built and tested locally; publication is pending. Package-only builds need that package in a configured local feed until it is published.

Licensing

Visit http://jfk-solutions.de for more information.

How To Release

  • Build release Build
  • Run IntelliLock and Protect Assemblies
  • Run nuget\CreateNuget.ps1
  • Upload Nuget
Product Compatible and additional computed target framework versions.
.NET net5.0 was computed.  net5.0-windows was computed.  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 is compatible.  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 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. 
.NET Core netcoreapp2.0 was computed.  netcoreapp2.1 was computed.  netcoreapp2.2 was computed.  netcoreapp3.0 was computed.  netcoreapp3.1 was computed. 
.NET Standard netstandard2.0 is compatible.  netstandard2.1 was computed. 
.NET Framework net461 was computed.  net462 was computed.  net463 was computed.  net47 was computed.  net471 was computed.  net472 was computed.  net48 was computed.  net481 was computed. 
MonoAndroid monoandroid was computed. 
MonoMac monomac was computed. 
MonoTouch monotouch was computed. 
Tizen tizen40 was computed.  tizen60 was computed. 
Xamarin.iOS xamarinios was computed. 
Xamarin.Mac xamarinmac was computed. 
Xamarin.TVOS xamarintvos was computed. 
Xamarin.WatchOS xamarinwatchos was computed. 
Compatible target framework(s)
Included target framework(s) (in package)
Learn more about Target Frameworks and .NET Standard.

NuGet packages (1)

Showing the top 1 NuGet packages that depend on jfk-solutions.TiaFileFormat:

Package Downloads
jfk-solutions.TiaFileFormat.S7CommPlus

Package Description

GitHub repositories

This package is not used by any popular GitHub repositories.

Version Downloads Last Updated
2026.10.20.2 71 10/20/2026
2026.10.20.1 33 10/20/2026
2026.10.19.2 42 10/19/2026
2026.10.19.1 34 10/19/2026
2026.10.16.1 104 10/16/2026
2026.10.14.3 43 10/14/2026
2026.10.14.2 38 10/14/2026
2026.10.10.2 64 10/10/2026
2026.10.10.1 35 10/10/2026
2026.10.9.1 39 10/9/2026
2026.10.8.1 43 10/8/2026
2026.10.5.1 62 10/5/2026
2026.10.2.2 64 10/2/2026
2026.10.2.1 58 10/2/2026
2026.9.16.1 96 9/16/2026
2026.9.15.3 57 9/15/2026
2026.9.15.2 59 9/15/2026
2026.9.15.1 59 9/15/2026
2026.9.11.1 75 9/11/2026
2026.9.4.1 179 9/4/2026
Loading failed