diff --git a/SabreTools.Models/OfflineList/CanOpen.cs b/SabreTools.Models/OfflineList/CanOpen.cs
new file mode 100644
index 00000000..a39b819f
--- /dev/null
+++ b/SabreTools.Models/OfflineList/CanOpen.cs
@@ -0,0 +1,12 @@
+using System.Xml;
+using System.Xml.Serialization;
+
+namespace SabreTools.Models.OfflineList
+{
+ [XmlRoot("canOpen")]
+ public class CanOpen
+ {
+ [XmlElement("extension")]
+ public string[]? Extension { get; set; }
+ }
+}
\ No newline at end of file
diff --git a/SabreTools.Models/OfflineList/Configuration.cs b/SabreTools.Models/OfflineList/Configuration.cs
new file mode 100644
index 00000000..0ea8dc84
--- /dev/null
+++ b/SabreTools.Models/OfflineList/Configuration.cs
@@ -0,0 +1,41 @@
+using System.Xml;
+using System.Xml.Serialization;
+
+namespace SabreTools.Models.OfflineList
+{
+ [XmlRoot("configuration")]
+ public class Configuration
+ {
+ [XmlElement("datName")]
+ public string? DatName { get; set; }
+
+ [XmlElement("datVersion")]
+ public string? DatVersion { get; set; }
+
+ [XmlElement("system")]
+ public string? System { get; set; }
+
+ /// Numeric?
+ [XmlElement("screenshotsWidth")]
+ public string? ScreenshotsWidth { get; set; }
+
+ /// Numeric?
+ [XmlElement("screenshotsHeight")]
+ public string? ScreenshotsHeight { get; set; }
+
+ [XmlElement("infos")]
+ public Infos? Infos { get; set; }
+
+ [XmlElement("canOpen")]
+ public CanOpen? CanOpen { get; set; }
+
+ [XmlElement("newDat")]
+ public NewDat? NewDat { get; set; }
+
+ [XmlElement("search")]
+ public Search? Search { get; set; }
+
+ [XmlElement("romtitle")]
+ public string? RomTitle { get; set; }
+ }
+}
\ No newline at end of file
diff --git a/SabreTools.Models/OfflineList/Dat.cs b/SabreTools.Models/OfflineList/Dat.cs
new file mode 100644
index 00000000..dd938651
--- /dev/null
+++ b/SabreTools.Models/OfflineList/Dat.cs
@@ -0,0 +1,15 @@
+using System.Xml;
+using System.Xml.Serialization;
+
+namespace SabreTools.Models.OfflineList
+{
+ [XmlRoot("dat")]
+ public class Dat
+ {
+ [XmlElement("configuration")]
+ public Configuration? Configuration { get; set; }
+
+ [XmlElement("games")]
+ public Games? Games { get; set; }
+ }
+}
\ No newline at end of file
diff --git a/SabreTools.Models/OfflineList/DatUrl.cs b/SabreTools.Models/OfflineList/DatUrl.cs
new file mode 100644
index 00000000..88b278af
--- /dev/null
+++ b/SabreTools.Models/OfflineList/DatUrl.cs
@@ -0,0 +1,14 @@
+using System.Xml;
+using System.Xml.Serialization;
+
+namespace SabreTools.Models.OfflineList
+{
+ [XmlRoot("datURL")]
+ public class DatUrl
+ {
+ [XmlAttribute("fileName")]
+ public string? FileName { get; set; }
+
+ public string? Content { get; set; }
+ }
+}
\ No newline at end of file
diff --git a/SabreTools.Models/OfflineList/FileRomCRC.cs b/SabreTools.Models/OfflineList/FileRomCRC.cs
new file mode 100644
index 00000000..e7bd74f4
--- /dev/null
+++ b/SabreTools.Models/OfflineList/FileRomCRC.cs
@@ -0,0 +1,14 @@
+using System.Xml;
+using System.Xml.Serialization;
+
+namespace SabreTools.Models.OfflineList
+{
+ [XmlRoot("romCRC")]
+ public class FileRomCRC
+ {
+ [XmlAttribute("extension")]
+ public string? Extension { get; set; }
+
+ public string? Content { get; set; }
+ }
+}
\ No newline at end of file
diff --git a/SabreTools.Models/OfflineList/Files.cs b/SabreTools.Models/OfflineList/Files.cs
new file mode 100644
index 00000000..dec96125
--- /dev/null
+++ b/SabreTools.Models/OfflineList/Files.cs
@@ -0,0 +1,12 @@
+using System.Xml;
+using System.Xml.Serialization;
+
+namespace SabreTools.Models.OfflineList
+{
+ [XmlRoot("files")]
+ public class Files
+ {
+ [XmlElement("romCRC")]
+ public FileRomCRC[]? RomCRC { get; set; }
+ }
+}
\ No newline at end of file
diff --git a/SabreTools.Models/OfflineList/Find.cs b/SabreTools.Models/OfflineList/Find.cs
new file mode 100644
index 00000000..674db9f6
--- /dev/null
+++ b/SabreTools.Models/OfflineList/Find.cs
@@ -0,0 +1,18 @@
+using System.Xml;
+using System.Xml.Serialization;
+
+namespace SabreTools.Models.OfflineList
+{
+ [XmlRoot("find")]
+ public class Find
+ {
+ [XmlAttribute("operation")]
+ public string? Operation { get; set; }
+
+ /// Numeric?
+ [XmlAttribute("value")]
+ public string? Value { get; set; }
+
+ public string? Content { get; set; }
+ }
+}
\ No newline at end of file
diff --git a/SabreTools.Models/OfflineList/Game.cs b/SabreTools.Models/OfflineList/Game.cs
new file mode 100644
index 00000000..9ffd8f8e
--- /dev/null
+++ b/SabreTools.Models/OfflineList/Game.cs
@@ -0,0 +1,51 @@
+using System.Xml;
+using System.Xml.Serialization;
+
+namespace SabreTools.Models.OfflineList
+{
+ [XmlRoot("game")]
+ public class Game
+ {
+ [XmlElement("imageNumber")]
+ public string? ImageNumber { get; set; }
+
+ [XmlElement("releaseNumber")]
+ public string? ReleaseNumber { get; set; }
+
+ [XmlElement("title")]
+ public string? Title { get; set; }
+
+ [XmlElement("saveType")]
+ public string? SaveType { get; set; }
+
+ [XmlElement("romSize")]
+ public long? RomSize { get; set; }
+
+ [XmlElement("publisher")]
+ public string? Publisher { get; set; }
+
+ [XmlElement("location")]
+ public string? Location { get; set; }
+
+ [XmlElement("sourceRom")]
+ public string? SourceRom { get; set; }
+
+ [XmlElement("language")]
+ public string? Language { get; set; }
+
+ [XmlElement("files")]
+ public Files? Files { get; set; }
+
+ [XmlElement("im1CRC")]
+ public string? Im1CRC { get; set; }
+
+ [XmlElement("im2CRC")]
+ public string? Im2CRC { get; set; }
+
+ [XmlElement("comment")]
+ public string? Comment { get; set; }
+
+ [XmlElement("duplicateId")]
+ public string? DuplicateID { get; set; }
+ }
+}
\ No newline at end of file
diff --git a/SabreTools.Models/OfflineList/Games.cs b/SabreTools.Models/OfflineList/Games.cs
new file mode 100644
index 00000000..b70ecff4
--- /dev/null
+++ b/SabreTools.Models/OfflineList/Games.cs
@@ -0,0 +1,12 @@
+using System.Xml;
+using System.Xml.Serialization;
+
+namespace SabreTools.Models.OfflineList
+{
+ [XmlRoot("games")]
+ public class Games
+ {
+ [XmlElement("game")]
+ public Game[]? Game { get; set; }
+ }
+}
\ No newline at end of file
diff --git a/SabreTools.Models/OfflineList/InfoBase.cs b/SabreTools.Models/OfflineList/InfoBase.cs
new file mode 100644
index 00000000..ffd0c453
--- /dev/null
+++ b/SabreTools.Models/OfflineList/InfoBase.cs
@@ -0,0 +1,56 @@
+using System.Xml;
+using System.Xml.Serialization;
+
+namespace SabreTools.Models.OfflineList
+{
+ public class InfoBase
+ {
+ [XmlAttribute("visible")]
+ public bool? Visible { get; set; }
+
+ [XmlAttribute("inNamingOption")]
+ public bool? InNamingOption { get; set; }
+
+ [XmlAttribute("default")]
+ public bool? Default { get; set; }
+ }
+
+ [XmlRoot("title")]
+ public class Title : InfoBase { }
+
+ [XmlRoot("location")]
+ public class Location : InfoBase { }
+
+ [XmlRoot("publisher")]
+ public class Publisher : InfoBase { }
+
+ [XmlRoot("sourceRom")]
+ public class SourceRom : InfoBase { }
+
+ [XmlRoot("romSize")]
+ public class RomSize : InfoBase { }
+
+ [XmlRoot("releaseNumber")]
+ public class ReleaseNumber : InfoBase { }
+
+ [XmlRoot("imageNumber")]
+ public class ImageNumber : InfoBase { }
+
+ [XmlRoot("languageNumber")]
+ public class LanguageNumber : InfoBase { }
+
+ [XmlRoot("comment")]
+ public class Comment : InfoBase { }
+
+ [XmlRoot("romCRC")]
+ public class RomCRC : InfoBase { }
+
+ [XmlRoot("im1CRC")]
+ public class Im1CRC : InfoBase { }
+
+ [XmlRoot("im2CRC")]
+ public class Im2CRC : InfoBase { }
+
+ [XmlRoot("languages")]
+ public class Languages : InfoBase { }
+}
\ No newline at end of file
diff --git a/SabreTools.Models/OfflineList/Infos.cs b/SabreTools.Models/OfflineList/Infos.cs
new file mode 100644
index 00000000..aff42cab
--- /dev/null
+++ b/SabreTools.Models/OfflineList/Infos.cs
@@ -0,0 +1,45 @@
+using System.Xml;
+using System.Xml.Serialization;
+
+namespace SabreTools.Models.OfflineList
+{
+ [XmlRoot("infos")]
+ public class Infos
+ {
+ [XmlElement("title")]
+ public Title? Title { get; set; }
+
+ [XmlElement("location")]
+ public Location? Location { get; set; }
+
+ [XmlElement("publisher")]
+ public Publisher? Publisher { get; set; }
+
+ [XmlElement("sourceRom")]
+ public SourceRom? SourceRom { get; set; }
+
+ [XmlElement("romSize")]
+ public RomSize? RomSize { get; set; }
+
+ [XmlElement("releaseNumber")]
+ public ReleaseNumber? ReleaseNumber { get; set; }
+
+ [XmlElement("languageNumber")]
+ public LanguageNumber? LanguageNumber { get; set; }
+
+ [XmlElement("comment")]
+ public Comment? Comment { get; set; }
+
+ [XmlElement("romCRC")]
+ public RomCRC? RomCRC { get; set; }
+
+ [XmlElement("im1CRC")]
+ public Im1CRC? Im1CRC { get; set; }
+
+ [XmlElement("im2CRC")]
+ public Im2CRC? Im2CRC { get; set; }
+
+ [XmlElement("languages")]
+ public Languages? Languages { get; set; }
+ }
+}
\ No newline at end of file
diff --git a/SabreTools.Models/OfflineList/NewDat.cs b/SabreTools.Models/OfflineList/NewDat.cs
new file mode 100644
index 00000000..2b89b63f
--- /dev/null
+++ b/SabreTools.Models/OfflineList/NewDat.cs
@@ -0,0 +1,18 @@
+using System.Xml;
+using System.Xml.Serialization;
+
+namespace SabreTools.Models.OfflineList
+{
+ [XmlRoot("newDat")]
+ public class NewDat
+ {
+ [XmlElement("datVersionURL")]
+ public string? DatVersionUrl { get; set; }
+
+ [XmlElement("datURL")]
+ public DatUrl? DatUrl { get; set; }
+
+ [XmlElement("imURL")]
+ public string? ImUrl { get; set; }
+ }
+}
\ No newline at end of file
diff --git a/SabreTools.Models/OfflineList/Search.cs b/SabreTools.Models/OfflineList/Search.cs
new file mode 100644
index 00000000..69698bdc
--- /dev/null
+++ b/SabreTools.Models/OfflineList/Search.cs
@@ -0,0 +1,12 @@
+using System.Xml;
+using System.Xml.Serialization;
+
+namespace SabreTools.Models.OfflineList
+{
+ [XmlRoot("search")]
+ public class Search
+ {
+ [XmlElement("to")]
+ public To[]? To { get; set; }
+ }
+}
\ No newline at end of file
diff --git a/SabreTools.Models/OfflineList/To.cs b/SabreTools.Models/OfflineList/To.cs
new file mode 100644
index 00000000..56bbb60a
--- /dev/null
+++ b/SabreTools.Models/OfflineList/To.cs
@@ -0,0 +1,21 @@
+using System.Xml;
+using System.Xml.Serialization;
+
+namespace SabreTools.Models.OfflineList
+{
+ [XmlRoot("to")]
+ public class To
+ {
+ [XmlAttribute("value")]
+ public string? Value { get; set; }
+
+ [XmlAttribute("default")]
+ public bool? Default { get; set; }
+
+ [XmlAttribute("auto")]
+ public bool? Auto { get; set; }
+
+ [XmlElement("find")]
+ public Find[]? Find { get; set; }
+ }
+}
\ No newline at end of file
diff --git a/SabreTools.Models/OpenMSX/Dump.cs b/SabreTools.Models/OpenMSX/Dump.cs
new file mode 100644
index 00000000..2c368a4e
--- /dev/null
+++ b/SabreTools.Models/OpenMSX/Dump.cs
@@ -0,0 +1,21 @@
+using System.Xml;
+using System.Xml.Serialization;
+
+namespace SabreTools.Models.OpenMSX
+{
+ [XmlRoot("dump")]
+ public class Dump
+ {
+ [XmlElement("original")]
+ public Original? Original { get; set; }
+
+ [XmlElement("rom")]
+ public Rom? Rom { get; set; }
+
+ [XmlElement("megarom")]
+ public MegaRom? MegaRom { get; set; }
+
+ [XmlElement("sccpluscart")]
+ public SCCPlusCart? SCCPlusCart { get; set; }
+ }
+}
\ No newline at end of file
diff --git a/SabreTools.Models/OpenMSX/MegaRom.cs b/SabreTools.Models/OpenMSX/MegaRom.cs
new file mode 100644
index 00000000..043b1969
--- /dev/null
+++ b/SabreTools.Models/OpenMSX/MegaRom.cs
@@ -0,0 +1,18 @@
+using System.Xml;
+using System.Xml.Serialization;
+
+namespace SabreTools.Models.OpenMSX
+{
+ [XmlRoot("megarom")]
+ public class MegaRom
+ {
+ [XmlElement("type")]
+ public string? Type { get; set; }
+
+ [XmlElement("hash")]
+ public string? Hash { get; set; }
+
+ [XmlElement("remark")]
+ public string? Remark { get; set; }
+ }
+}
\ No newline at end of file
diff --git a/SabreTools.Models/OpenMSX/Original.cs b/SabreTools.Models/OpenMSX/Original.cs
new file mode 100644
index 00000000..1ded0f69
--- /dev/null
+++ b/SabreTools.Models/OpenMSX/Original.cs
@@ -0,0 +1,14 @@
+using System.Xml;
+using System.Xml.Serialization;
+
+namespace SabreTools.Models.OpenMSX
+{
+ [XmlRoot("original")]
+ public class Original
+ {
+ [XmlElement("value")]
+ public bool Value { get; set; }
+
+ public string? Content { get; set; }
+ }
+}
\ No newline at end of file
diff --git a/SabreTools.Models/OpenMSX/Rom.cs b/SabreTools.Models/OpenMSX/Rom.cs
new file mode 100644
index 00000000..a277b2f6
--- /dev/null
+++ b/SabreTools.Models/OpenMSX/Rom.cs
@@ -0,0 +1,21 @@
+using System.Xml;
+using System.Xml.Serialization;
+
+namespace SabreTools.Models.OpenMSX
+{
+ [XmlRoot("rom")]
+ public class Rom
+ {
+ [XmlElement("start")]
+ public string? Start { get; set; }
+
+ [XmlElement("type")]
+ public string? Type { get; set; }
+
+ [XmlElement("hash")]
+ public string? Hash { get; set; }
+
+ [XmlElement("remark")]
+ public string? Remark { get; set; }
+ }
+}
\ No newline at end of file
diff --git a/SabreTools.Models/OpenMSX/SCCPlusCart.cs b/SabreTools.Models/OpenMSX/SCCPlusCart.cs
new file mode 100644
index 00000000..054abb04
--- /dev/null
+++ b/SabreTools.Models/OpenMSX/SCCPlusCart.cs
@@ -0,0 +1,18 @@
+using System.Xml;
+using System.Xml.Serialization;
+
+namespace SabreTools.Models.OpenMSX
+{
+ [XmlRoot("sccpluscart")]
+ public class SCCPlusCart
+ {
+ [XmlElement("boot")]
+ public string? Boot { get; set; }
+
+ [XmlElement("hash")]
+ public string? Hash { get; set; }
+
+ [XmlElement("remark")]
+ public string? Remark { get; set; }
+ }
+}
\ No newline at end of file
diff --git a/SabreTools.Models/OpenMSX/Software.cs b/SabreTools.Models/OpenMSX/Software.cs
new file mode 100644
index 00000000..ebbba752
--- /dev/null
+++ b/SabreTools.Models/OpenMSX/Software.cs
@@ -0,0 +1,30 @@
+using System.Xml;
+using System.Xml.Serialization;
+
+namespace SabreTools.Models.OpenMSX
+{
+ [XmlRoot("software")]
+ public class Software
+ {
+ [XmlElement("title")]
+ public string Title { get; set; }
+
+ [XmlElement("genmsxid")]
+ public string? GenMSXID { get; set; }
+
+ [XmlElement("system")]
+ public string System { get; set; }
+
+ [XmlElement("company")]
+ public string Company { get; set; }
+
+ [XmlElement("year")]
+ public string Year { get; set; }
+
+ [XmlElement("country")]
+ public string Country { get; set; }
+
+ [XmlElement("dump")]
+ public Dump[]? Dump { get; set; }
+ }
+}
\ No newline at end of file
diff --git a/SabreTools.Models/OpenMSX/SoftwareDb.cs b/SabreTools.Models/OpenMSX/SoftwareDb.cs
new file mode 100644
index 00000000..4341a42c
--- /dev/null
+++ b/SabreTools.Models/OpenMSX/SoftwareDb.cs
@@ -0,0 +1,15 @@
+using System.Xml;
+using System.Xml.Serialization;
+
+namespace SabreTools.Models.OpenMSX
+{
+ [XmlRoot("softwaredb")]
+ public class SoftwareDb
+ {
+ [XmlAttribute("timestamp")]
+ public string? Timestamp { get; set; }
+
+ [XmlAttribute("software")]
+ public Software[]? Software { get; set; }
+ }
+}
\ No newline at end of file
diff --git a/SabreTools.Models/RomCenter/Credits.cs b/SabreTools.Models/RomCenter/Credits.cs
new file mode 100644
index 00000000..565c7db6
--- /dev/null
+++ b/SabreTools.Models/RomCenter/Credits.cs
@@ -0,0 +1,27 @@
+namespace SabreTools.Models.RomCenter
+{
+ /// [credits]
+ public class Credits
+ {
+ /// author
+ public string Author { get; set; }
+
+ /// version
+ public string Version { get; set; }
+
+ /// email
+ public string Email { get; set; }
+
+ /// homepage
+ public string Homepage { get; set; }
+
+ /// url
+ public string Url { get; set; }
+
+ /// date
+ public string Date { get; set; }
+
+ /// comment
+ public string Comment { get; set; }
+ }
+}
\ No newline at end of file
diff --git a/SabreTools.Models/RomCenter/Dat.cs b/SabreTools.Models/RomCenter/Dat.cs
new file mode 100644
index 00000000..733ceb62
--- /dev/null
+++ b/SabreTools.Models/RomCenter/Dat.cs
@@ -0,0 +1,18 @@
+namespace SabreTools.Models.RomCenter
+{
+ /// [dat]
+ public class Dat
+ {
+ /// version
+ public string Version { get; set; }
+
+ /// plugin
+ public string Plugin { get; set; }
+
+ /// split
+ public string Split { get; set; }
+
+ /// merge
+ public string Merge { get; set; }
+ }
+}
\ No newline at end of file
diff --git a/SabreTools.Models/RomCenter/Emulator.cs b/SabreTools.Models/RomCenter/Emulator.cs
new file mode 100644
index 00000000..cf850d89
--- /dev/null
+++ b/SabreTools.Models/RomCenter/Emulator.cs
@@ -0,0 +1,12 @@
+namespace SabreTools.Models.RomCenter
+{
+ /// [emulator]
+ public class Emulator
+ {
+ /// refname
+ public string RefName { get; set; }
+
+ /// version
+ public string Version { get; set; }
+ }
+}
\ No newline at end of file
diff --git a/SabreTools.Models/RomCenter/Games.cs b/SabreTools.Models/RomCenter/Games.cs
new file mode 100644
index 00000000..12338d48
--- /dev/null
+++ b/SabreTools.Models/RomCenter/Games.cs
@@ -0,0 +1,8 @@
+namespace SabreTools.Models.RomCenter
+{
+ /// [games]
+ public class Games
+ {
+ public Rom[]? Rom { get; set; }
+ }
+}
\ No newline at end of file
diff --git a/SabreTools.Models/RomCenter/Rom.cs b/SabreTools.Models/RomCenter/Rom.cs
new file mode 100644
index 00000000..3cdcdc2f
--- /dev/null
+++ b/SabreTools.Models/RomCenter/Rom.cs
@@ -0,0 +1,33 @@
+namespace SabreTools.Models.RomCenter
+{
+ /// ¬-delimited
+ public class Rom
+ {
+ /// 0
+ public string? ParentName { get; set; }
+
+ /// 1
+ public string? ParentDescription { get; set; }
+
+ /// 2
+ public string? GameName { get; set; }
+
+ /// 3
+ public string? GameDescription { get; set; }
+
+ /// 4
+ public string? RomName { get; set; }
+
+ /// 5
+ public string? RomCRC { get; set; }
+
+ /// 6
+ public long? RomSize { get; set; }
+
+ /// 7
+ public string? RomOf { get; set; }
+
+ /// 8
+ public string? MergeName { get; set; }
+ }
+}
\ No newline at end of file
diff --git a/SabreTools.Models/SabreTools.Models.csproj b/SabreTools.Models/SabreTools.Models.csproj
index 5d83bbdc..5e3ed4b4 100644
--- a/SabreTools.Models/SabreTools.Models.csproj
+++ b/SabreTools.Models/SabreTools.Models.csproj
@@ -2,6 +2,7 @@
net6.0;net7.0
+ enable