edidkit

MoonBit EDID parser, checksum validator, display timing decoder, and monitor capability audit toolkit.

edid
display
monitor
timing
hardware
validator
moonbit
moon add BenPaoBaMingWangXing/edidkit@0.1.1
Download zip
Version
0.1.1
License
MIT
Last updated
6 days ago
Downloads
9
README

#edidkit

edidkit is a MoonBit native toolkit for parsing, normalizing, auditing, and reporting EDID monitor identification data.

Package: BenPaoBaMingWangXing/edidkit Repository: https://github.com/BenPaoBaMingWangXing/edidkit Mooncakes: https://mooncakes.io/docs/BenPaoBaMingWangXing/edidkit License: MIT

#Purpose

EDID is the data block that a monitor, embedded panel, projector, capture device, or display emulator exposes to describe its identity and supported timings. Driver bring-up, board validation, display QA, firmware testing, KVM compatibility checks, and hardware debugging often need a small parser that can run in a deterministic build environment.

edidkit provides that parser in MoonBit. The package focuses on the EDID 1.x base block and keeps a clear boundary: it decodes the base 128-byte block, validates checksum/header/length, extracts display identity and timing data, normalizes display modes, matches common DMT/CTA/CVT/reduced-blanking/projector timing entries, and produces human-readable or machine-readable audit reports.

#Features

  • Parse EDID hex strings with spaces, colons, commas, dashes, and underscores.
  • Parse EDID bytes into a typed Edid value.
  • Validate base block length, header, checksum, and version.
  • Decode manufacturer ID, product code, serial number, manufacture date, EDID version, digital/analog video input, physical size, gamma, feature flags, chromaticity, established timings, standard timings, detailed timing descriptors, monitor name, serial text, and range limits.
  • Extract normalized display modes from detailed, standard, and established timing data.
  • Pick preferred/best modes and query resolution or refresh support.
  • Match decoded modes against a bundled timing catalog.
  • Audit EDID data with baseline, embedded panel, desktop, full-HD video, projector, workstation, gaming, large-format, and UHD profiles.
  • Render text, Markdown, and JSON reports.
  • Provide runnable examples and MoonBit tests.

#Install

After the package is published on Mooncakes:

moon add BenPaoBaMingWangXing/edidkit

Use it from another package with a MoonBit import alias such as @edidkit.

#Quick Start

Run the bundled parser example:

moon run cmd/main

Run the bundled audit example:

moon run cmd/audit

Expected output includes the decoded identity, monitor name, preferred display mode, matched timing catalog entries, audit status, and Markdown report table.

#API Example

match @edidkit.parse_edid_hex(@edidkit.sample_edid_hex()) {
Ok(edid) => {
println(@edidkit.edid_to_text(edid))
let audit = @edidkit.audit_edid_with_profile(
edid,
@edidkit.DisplayProfile::desktop(),
)
println(@edidkit.audit_to_json(audit))
}
Err(err) => println(err.message)
}

#Main API Groups

  • Parsing: parse_hex_bytes, parse_edid_hex, parse_edid_bytes
  • Samples: sample_edid_hex, sample_edid, sample_audit
  • EDID helpers: Edid::identity, Edid::version_text, Edid::checksum_valid, Edid::monitor_name, Edid::preferred_timing, Edid::display_class
  • Mode extraction: modes_from_edid, preferred_mode, best_mode, modes_at_least, modes_by_resolution, supports_resolution, supports_mode, max_refresh_for_resolution, has_interlaced_modes
  • Timing catalog: timing_catalog, catalog_entries_by_family, catalog_entries_by_resolution, find_catalog_entry, catalog_match_for_mode, catalog_matches_for_edid, highest_catalog_mode
  • Auditing: audit_edid, audit_edid_with_profile, summarize_audit, DisplayProfile::baseline, DisplayProfile::desktop, DisplayProfile::embedded_panel, DisplayProfile::large_format
  • Profile matrix: standard_display_profiles, profile_matrix, check_profile, best_profile_match, accepted_profiles, rejected_profiles
  • Rendering: edid_to_text, audit_to_text, modes_to_text, modes_to_markdown, audit_to_markdown, profile_matrix_to_markdown, edid_to_json, audit_to_json

More details are in docs/API.md.

#Validation

Local validation commands:

moon check moon build moon test moon run cmd/main moon run cmd/audit moon package

The repository also contains GitHub Actions CI at .github/workflows/ci.yml. The CI runs check, build, test, examples, and package verification on push and pull request.

#Scope and Boundaries

Implemented:

  • EDID 1.x base block parsing and validation.
  • Descriptor decoding for detailed timing, monitor name, serial text, generic text, range limits, empty descriptors, and unknown descriptors.
  • Display mode normalization and timing catalog matching.
  • Profile-based audit and report generation.

Not implemented in version 0.1.1:

  • CTA-861 extension block parsing.
  • DisplayID block parsing.
  • OS display driver integration.
  • Binary file I/O helpers.
  • Web protocol tooling, subtitle parsing, license scanning, SBOM generation, or unrelated protocol tooling.

#Mooncakes Collision Check

On 2026-08-11, Mooncakes public module data and web search were checked for EDID, DisplayID, VESA, DMT, CTA, monitor identification, and display timing packages. No existing Mooncakes package with the same project boundary was found. Nearby keyword matches were unrelated categories such as text layout, regular expression, dotenv, noise generation, or generic scheduling.

The detailed check record is in docs/MOONCAKES_CHECK.md.

#Project Type

This is an original MoonBit open-source library. It is not a port of an existing library. The bundled synthetic EDID sample is self-contained test data created for examples and tests.

#License and Compliance

The project is released under the MIT License. The source code is written for this package and does not include third-party source code, private code, closed-source code, commercial code, images, binary assets, or copied documentation. The only declared external package import is MoonBit core test support for tests.

#Hackathon Materials

  • Project proposal: PROJECT_PROPOSAL.md
  • API documentation: docs/API.md
  • Design notes: docs/DESIGN.md
  • Acceptance checklist: docs/ACCEPTANCE_CHECKLIST.md
  • Mooncakes collision check: docs/MOONCAKES_CHECK.md
  • Test record: docs/TEST_RECORD.md
  • Development log: docs/DEVELOPMENT_LOG.md
  • Changelog: CHANGELOG.md

#
AspectRatio

pub(all) enum AspectRatio {
Ratio16_10
Ratio4_3
Ratio5_4
Ratio16_9
} derive(Eq,
Debug
)

Standard timing aspect ratio code.

#
AspectRatio::name

fn AspectRatio::name(self : AspectRatio) -> String

#
AuditStatus

pub(all) enum AuditStatus {
Accepted
NeedsAttention
Rejected
} derive(Eq,
Debug
)

Overall EDID audit status.

#
AuditStatus::name

fn AuditStatus::name(self : AuditStatus) -> String

#
AuditSummary

pub(all) struct AuditSummary {
status : AuditStatus
diagnostics : Int
notes : Int
warnings : Int
errors : Int
detailed_timings : Int
standard_timings : Int
established_timings : Int
} derive(Eq,
Debug
)

Aggregate counters for EDID diagnostics.

#
BasicDisplay

pub(all) struct BasicDisplay {
width_cm : Int
height_cm : Int
gamma_x100 : Int?
standby : Bool
suspend : Bool
active_off : Bool
preferred_timing : Bool
default_srgb : Bool
} derive(Eq,
Debug
)

Basic display dimensions and gamma.

#
BasicDisplay::aspect_x1000

fn BasicDisplay::aspect_x1000(self : BasicDisplay) -> Int?

#
BasicDisplay::has_physical_size

fn BasicDisplay::has_physical_size(self : BasicDisplay) -> Bool

#
Chromaticity

pub(all) struct Chromaticity {
red_x : Int
red_y : Int
green_x : Int
green_y : Int
blue_x : Int
blue_y : Int
white_x : Int
white_y : Int
} derive(Eq,
Debug
)

Chromaticity coordinates scaled by 10000.

#
Descriptor

pub(all) struct Descriptor {
kind : DescriptorKind
index : Int
text : String?
detailed_timing : DetailedTimingInfo?
range_limits : RangeLimits?
} derive(Eq,
Debug
)

One EDID descriptor slot.

#
Descriptor::is_detailed_timing

fn Descriptor::is_detailed_timing(self : Descriptor) -> Bool

#
DescriptorKind

pub(all) enum DescriptorKind {
DetailedTiming
SerialNumberText
MonitorName
RangeLimits
DisplayProductName
DisplayProductSerial
Text
Empty
Unknown(Int)
} derive(Eq,
Debug
)

EDID base block descriptor kind.

#
DescriptorKind::name

fn DescriptorKind::name(self : DescriptorKind) -> String

#
DetailedTimingInfo

pub(all) struct DetailedTimingInfo {
pixel_clock_khz : Int
h_active : Int
h_blanking : Int
v_active : Int
v_blanking : Int
h_sync_offset : Int
h_sync_pulse : Int
v_sync_offset : Int
v_sync_pulse : Int
h_size_mm : Int
v_size_mm : Int
h_border : Int
v_border : Int
interlaced : Bool
positive_hsync : Bool
positive_vsync : Bool
} derive(Eq,
Debug
)

Detailed timing descriptor decoded from an 18-byte EDID descriptor.

#
DetailedTimingInfo::refresh_hz_rounded

fn DetailedTimingInfo::refresh_hz_rounded(self : DetailedTimingInfo) -> Int

#
DetailedTimingInfo::refresh_millihz

fn DetailedTimingInfo::refresh_millihz(self : DetailedTimingInfo) -> Int

#
DetailedTimingInfo::resolution

fn DetailedTimingInfo::resolution(self : DetailedTimingInfo) -> String

#
DiagnosticCode

pub(all) enum DiagnosticCode {
InvalidLength
InvalidHexLength
InvalidHexCharacter
InvalidHeader
InvalidChecksum
UnsupportedVersion
SuspiciousManufactureDate
MissingDetailedTiming
EmptyMonitorName
MissingPreferredTiming
ExtensionBlockIgnored
NonSquarePhysicalSize
UnusualGamma
UnknownDescriptor
MissingMonitorName
InvalidDisplaySize
ProfileRequirementNotMet
InterlacedModeUnsupported
RangeLimitInconsistent
} derive(Eq,
Debug
)

Stable machine-readable diagnostic codes.

#
DiagnosticCode::name

fn DiagnosticCode::name(self : DiagnosticCode) -> String

#
DisplayClass

pub(all) enum DisplayClass {
UnknownDisplay
EmbeddedPanel
DesktopMonitor
Television
Projector
LargeFormatDisplay
} derive(Eq,
Debug
)

Human-oriented monitor class derived from size and preferred mode.

#
DisplayClass::name

fn DisplayClass::name(self : DisplayClass) -> String

#
DisplayMode

pub(all) struct DisplayMode {
width : Int
height : Int
refresh_millihz : Int
pixel_clock_khz : Int?
source : ModeSource
interlaced : Bool
preferred : Bool
name : String
} derive(Eq,
Debug
)

Normalized display mode from EDID timing sources or a known timing table.

#
DisplayMode::is_4k_or_better

fn DisplayMode::is_4k_or_better(self : DisplayMode) -> Bool

#
DisplayMode::is_high_refresh

fn DisplayMode::is_high_refresh(self : DisplayMode) -> Bool

#
DisplayMode::is_portrait

fn DisplayMode::is_portrait(self : DisplayMode) -> Bool

#
DisplayMode::label

fn DisplayMode::label(self : DisplayMode) -> String

#
DisplayMode::pixel_count

fn DisplayMode::pixel_count(self : DisplayMode) -> Int

#
DisplayMode::refresh_hz_rounded

fn DisplayMode::refresh_hz_rounded(self : DisplayMode) -> Int

#
DisplayMode::resolution

fn DisplayMode::resolution(self : DisplayMode) -> String

#
DisplayProfile

pub(all) struct DisplayProfile {
name : String
min_width : Int
min_height : Int
min_refresh_hz : Int
require_preferred_timing : Bool
allow_interlaced : Bool
max_extension_blocks : Int
} derive(Eq,
Debug
)

Compatibility profile used by EDID audits.

#
DisplayProfile::baseline

fn DisplayProfile::baseline() -> DisplayProfile

#
DisplayProfile::desktop

#
DisplayProfile::embedded_panel

fn DisplayProfile::embedded_panel() -> DisplayProfile

#
DisplayProfile::full_hd_video

fn DisplayProfile::full_hd_video() -> DisplayProfile

#
DisplayProfile::gaming

#
DisplayProfile::large_format

fn DisplayProfile::large_format() -> DisplayProfile

#
DisplayProfile::legacy_xga

fn DisplayProfile::legacy_xga() -> DisplayProfile

#
DisplayProfile::projector_room

fn DisplayProfile::projector_room() -> DisplayProfile

#
DisplayProfile::uhd_video

fn DisplayProfile::uhd_video() -> DisplayProfile

#
DisplayProfile::workstation

fn DisplayProfile::workstation() -> DisplayProfile

#
Edid

pub(all) struct Edid {
bytes : Array[Int]
manufacturer : ManufacturerId
product_code : Int
serial_number : Int
manufacture : ManufactureDate
version_major : Int
version_minor : Int
video_input : VideoInput
display : BasicDisplay
chromaticity : Chromaticity
established_timings : Array[EstablishedTiming]
standard_timings : Array[StandardTiming]
descriptors : Array[Descriptor]
extension_count : Int
checksum : Int
diagnostics : Array[EdidDiagnostic]
} derive(Eq,
Debug
)

Parsed EDID base block.

#
Edid::checksum_valid

fn Edid::checksum_valid(self : Edid) -> Bool

#
Edid::detailed_timing_count

fn Edid::detailed_timing_count(self : Edid) -> Int

#
Edid::display_class

fn Edid::display_class(self : Edid) -> DisplayClass

#
Edid::enabled_established_timing_count

fn Edid::enabled_established_timing_count(self : Edid) -> Int

#
Edid::identity

fn Edid::identity(self : Edid) -> String

#
Edid::monitor_name

fn Edid::monitor_name(self : Edid) -> String?

#
Edid::preferred_timing

fn Edid::preferred_timing(self : Edid) -> DetailedTimingInfo?

#
Edid::valid_standard_timing_count

fn Edid::valid_standard_timing_count(self : Edid) -> Int

#
Edid::version_text

fn Edid::version_text(self : Edid) -> String

#
EdidAudit

pub(all) struct EdidAudit {
status : AuditStatus
profile_name : String
diagnostics : Array[EdidDiagnostic]
summary : AuditSummary
preferred_mode : DisplayMode?
display_class : DisplayClass
} derive(Eq,
Debug
)

Complete audit result for one EDID block.

#
EdidAudit::diagnostics_by_severity

fn EdidAudit::diagnostics_by_severity(self : EdidAudit, severity : Severity) -> Array[EdidDiagnostic]

#
EdidAudit::has_diagnostic

fn EdidAudit::has_diagnostic(self : EdidAudit, code : DiagnosticCode) -> Bool

#
EdidAudit::has_errors

fn EdidAudit::has_errors(self : EdidAudit) -> Bool

#
EdidAudit::has_warnings

fn EdidAudit::has_warnings(self : EdidAudit) -> Bool

#
EdidAudit::is_ok

fn EdidAudit::is_ok(self : EdidAudit) -> Bool

#
EdidDiagnostic

pub(all) struct EdidDiagnostic {
code : DiagnosticCode
severity : Severity
message : String
offset : Int?
} derive(Eq,
Debug
)

Recoverable diagnostic produced while parsing or auditing EDID data.

#
EdidDiagnostic::make

fn EdidDiagnostic::make(code : DiagnosticCode, severity : Severity, message : String, offset : Int?) -> EdidDiagnostic

#
EdidDiagnostic::to_error

fn EdidDiagnostic::to_error(self : EdidDiagnostic) -> EdidError

#
EdidError

pub(all) struct EdidError {
code : DiagnosticCode
message : String
offset : Int?
} derive(Eq,
Debug
)

Parse error returned when an EDID input cannot produce a base block.

#
EdidError::make

fn EdidError::make(code : DiagnosticCode, message : String, offset : Int?) -> EdidError

#
EstablishedTiming

pub(all) struct EstablishedTiming {
name : String
width : Int
height : Int
refresh_hz : Int
enabled : Bool
byte_offset : Int
bit_mask : Int
} derive(Eq,
Debug
)

One established timing capability.

#
ManufactureDate

pub(all) struct ManufactureDate {
week : Int
year : Int
model_year : Bool
} derive(Eq,
Debug
)

EDID manufacture date fields.

#
ManufactureDate::description

fn ManufactureDate::description(self : ManufactureDate) -> String

#
ManufacturerId

pub(all) struct ManufacturerId {
raw : Int
code : String
} derive(Eq,
Debug
)

Three-letter EISA manufacturer identifier.

#
ModeSource

pub(all) enum ModeSource {
PreferredDetailed
DetailedDescriptor
StandardTimingSource
EstablishedTimingSource
DmtDatabase
Inferred
} derive(Eq,
Debug
)

Source used to derive a normalized display mode.

#
ModeSource::name

fn ModeSource::name(self : ModeSource) -> String

#
ProfileCheck

pub(all) struct ProfileCheck {
profile_name : String
status : AuditStatus
score : Int
minimum_mode_met : Bool
preferred_timing_met : Bool
interlaced_policy_met : Bool
extension_policy_met : Bool
} derive(Eq,
Debug
)

One profile matrix row.

#
ProfileCheck::failed_requirements

fn ProfileCheck::failed_requirements(self : ProfileCheck) -> Int

#
ProfileCheck::is_ok

fn ProfileCheck::is_ok(self : ProfileCheck) -> Bool

#
RangeLimits

pub(all) struct RangeLimits {
min_vertical_hz : Int
max_vertical_hz : Int
min_horizontal_khz : Int
max_horizontal_khz : Int
max_pixel_clock_mhz : Int
} derive(Eq,
Debug
)

Range limits descriptor decoded from tag 0xFD.

#
Severity

pub(all) enum Severity {
Note
Warning
Error
} derive(Eq,
Debug
)

Severity used by parser and audit diagnostics.

#
Severity::name

fn Severity::name(self : Severity) -> String

#
StandardTiming

pub(all) struct StandardTiming {
width : Int
height : Int
refresh_hz : Int
aspect : AspectRatio
byte_offset : Int
valid : Bool
} derive(Eq,
Debug
)

One standard timing capability.

#
TimingCatalogEntry

pub(all) struct TimingCatalogEntry {
id : String
family : TimingFamily
width : Int
height : Int
refresh_millihz : Int
pixel_clock_khz : Int
progressive : Bool
aspect : String
name : String
} derive(Eq,
Debug
)

Known timing entry used for matching and reporting.

#
TimingCatalogEntry::is_high_refresh

fn TimingCatalogEntry::is_high_refresh(self : TimingCatalogEntry) -> Bool

#
TimingCatalogEntry::label

fn TimingCatalogEntry::label(self : TimingCatalogEntry) -> String

#
TimingCatalogEntry::pixel_count

fn TimingCatalogEntry::pixel_count(self : TimingCatalogEntry) -> Int

#
TimingFamily

pub(all) enum TimingFamily {
EstablishedFamily
DmtFamily
CtaFamily
CvtFamily
RbFamily
ProjectorFamily
} derive(Eq,
Debug
)

Catalog family for a known display timing.

#
TimingFamily::name

fn TimingFamily::name(self : TimingFamily) -> String

#
VideoInput

pub(all) struct VideoInput {
signal : VideoSignal
interface_name : String
bit_depth : String
voltage : String
sync : String
} derive(Eq,
Debug
)

Video input information decoded from byte 20.

#
VideoSignal

pub(all) enum VideoSignal {
Digital
Analog
} derive(Eq,
Debug
)

Display color/input family reported by the video input byte.

#
VideoSignal::name

fn VideoSignal::name(self : VideoSignal) -> String

#
accepted_profiles

fn accepted_profiles(edid : Edid) -> Array[ProfileCheck]

#
audit_edid

fn audit_edid(edid : Edid) -> EdidAudit

#
audit_edid_with_profile

fn audit_edid_with_profile(edid : Edid, profile : DisplayProfile) -> EdidAudit

#
audit_summary_to_json

fn audit_summary_to_json(summary : AuditSummary) -> String

#
audit_summary_to_text

fn audit_summary_to_text(summary : AuditSummary) -> String

#
audit_to_json

fn audit_to_json(audit : EdidAudit) -> String

#
audit_to_markdown

fn audit_to_markdown(audit : EdidAudit) -> String

#
audit_to_text

fn audit_to_text(audit : EdidAudit) -> String

#
best_mode

fn best_mode(edid : Edid) -> DisplayMode?

#
best_profile_match

fn best_profile_match(edid : Edid) -> ProfileCheck

#
catalog_entries_by_family

fn catalog_entries_by_family(family : TimingFamily) -> Array[TimingCatalogEntry]

#
catalog_entries_by_resolution

fn catalog_entries_by_resolution(width : Int, height : Int) -> Array[TimingCatalogEntry]

#
catalog_match_for_mode

fn catalog_match_for_mode(mode : DisplayMode) -> TimingCatalogEntry?

#
catalog_matches_for_edid

fn catalog_matches_for_edid(edid : Edid) -> Array[TimingCatalogEntry]

#
catalog_summary_for_edid

fn catalog_summary_for_edid(edid : Edid) -> String

#
catalog_to_markdown

fn catalog_to_markdown(entries : Array[TimingCatalogEntry]) -> String

#
check_profile

fn check_profile(edid : Edid, profile : DisplayProfile) -> ProfileCheck

#
diagnostic_to_json

fn diagnostic_to_json(diagnostic : EdidDiagnostic) -> String

#
diagnostic_to_text

fn diagnostic_to_text(diagnostic : EdidDiagnostic) -> String

#
dmt_name_for_mode

fn dmt_name_for_mode(mode : DisplayMode) -> String?

#
edid_to_json

fn edid_to_json(edid : Edid) -> String

#
edid_to_text

fn edid_to_text(edid : Edid) -> String

#
find_catalog_entry

fn find_catalog_entry(id : String) -> TimingCatalogEntry?

#
has_interlaced_modes

fn has_interlaced_modes(edid : Edid) -> Bool

#
high_refresh_catalog_entries

fn high_refresh_catalog_entries() -> Array[TimingCatalogEntry]

#
highest_catalog_mode

fn highest_catalog_mode() -> TimingCatalogEntry

#
known_dmt_modes

fn known_dmt_modes() -> Array[DisplayMode]

#
max_refresh_for_resolution

fn max_refresh_for_resolution(edid : Edid, width : Int, height : Int) -> Int?

#
mode_to_json

fn mode_to_json(mode : DisplayMode) -> String

#
mode_to_text

fn mode_to_text(mode : DisplayMode) -> String

#
modes_at_least

fn modes_at_least(edid : Edid, width : Int, height : Int, refresh_hz : Int) -> Array[DisplayMode]

#
modes_by_resolution

fn modes_by_resolution(edid : Edid, width : Int, height : Int) -> Array[DisplayMode]

#
modes_from_edid

fn modes_from_edid(edid : Edid) -> Array[DisplayMode]

#
modes_to_markdown

fn modes_to_markdown(modes : Array[DisplayMode]) -> String

#
modes_to_text

fn modes_to_text(modes : Array[DisplayMode]) -> String

#
parse_edid_bytes

fn parse_edid_bytes(data : Array[Int]) -> Result[Edid, EdidError]

#
parse_edid_hex

fn parse_edid_hex(input : String) -> Result[Edid, EdidError]

#
parse_hex_bytes

fn parse_hex_bytes(input : String) -> Result[Array[Int], EdidError]

#
preferred_mode

fn preferred_mode(edid : Edid) -> DisplayMode?

#
profile_matrix

fn profile_matrix(edid : Edid) -> Array[ProfileCheck]

#
profile_matrix_to_markdown

fn profile_matrix_to_markdown(checks : Array[ProfileCheck]) -> String

#
profile_matrix_to_text

fn profile_matrix_to_text(checks : Array[ProfileCheck]) -> String

#
rejected_profiles

fn rejected_profiles(edid : Edid) -> Array[ProfileCheck]

#
sample_audit

fn sample_audit() -> EdidAudit raise

#
sample_edid

fn sample_edid() -> Edid raise

#
sample_edid_hex

fn sample_edid_hex() -> String

Self-contained synthetic EDID sample used by examples and tests.

#
standard_display_profiles

fn standard_display_profiles() -> Array[DisplayProfile]

#
summarize_audit

fn summarize_audit(edid : Edid, diagnostics : Array[EdidDiagnostic]) -> AuditSummary

#
supports_mode

fn supports_mode(edid : Edid, width : Int, height : Int, refresh_hz : Int) -> Bool

#
supports_resolution

fn supports_resolution(edid : Edid, width : Int, height : Int) -> Bool

#
timing_catalog

fn timing_catalog() -> Array[TimingCatalogEntry]

#
version

fn version() -> String

Powered by MoonBit

Site sourceReport issuePackagesBuild queueSkillsStatistics

© 2026 mooncakes.io