pub(crate) mod vdm_t1t2t3;
pub(crate) mod vdm_t4;
pub(crate) mod vdm_t5;
pub(crate) mod vdm_t6;
pub(crate) mod vdm_t9;
pub(crate) mod vdm_t10;
pub(crate) mod vdm_t11;
pub(crate) mod vdm_t12;
pub(crate) mod vdm_t13;
pub(crate) mod vdm_t14;
pub(crate) mod vdm_t15;
pub(crate) mod vdm_t16;
pub(crate) mod vdm_t17;
pub(crate) mod vdm_t18;
pub(crate) mod vdm_t19;
pub(crate) mod vdm_t20;
pub(crate) mod vdm_t21;
pub(crate) mod vdm_t22;
pub(crate) mod vdm_t23;
pub(crate) mod vdm_t24;
pub(crate) mod vdm_t25;
pub(crate) mod vdm_t26;
pub(crate) mod vdm_t27;
use super::*;
pub use vdm_t4::BaseStationReport;
pub use vdm_t6::BinaryAddressedMessage;
pub use vdm_t9::StandardSarAircraftPositionReport;
pub use vdm_t10::UtcDateInquiry;
pub use vdm_t12::AddressedSafetyRelatedMessage;
pub use vdm_t13::SafetyRelatedAcknowledgement;
pub use vdm_t14::SafetyRelatedBroadcastMessage;
pub use vdm_t15::{Interrogation, InterrogationCase};
pub use vdm_t16::AssignmentModeCommand;
pub use vdm_t17::DgnssBroadcastBinaryMessage;
pub use vdm_t20::{DataLinkManagementMessage};
pub use vdm_t21::{AidToNavigationReport, NavAidType};
pub use vdm_t22::{ChannelManagement};
pub use vdm_t23::{GroupAssignmentCommand};
pub use vdm_t25::{SingleSlotBinaryMessage};
pub use vdm_t26::{MultipleSlotBinaryMessage};
#[derive(Clone, Copy, Debug, PartialEq)]
pub enum Station {
BaseStation, DependentAisBaseStation, MobileStation, AidToNavigationStation, AisReceivingStation, LimitedBaseStation, AisTransmittingStation, RepeaterStation, Other, }
impl Default for Station {
fn default() -> Station {
Station::Other
}
}
impl core::fmt::Display for Station {
fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
match self {
Station::BaseStation => write!(f, "base station"),
Station::DependentAisBaseStation => write!(f, "dependent AIS base station"),
Station::MobileStation => write!(f, "mobile station"),
Station::AidToNavigationStation => write!(f, "aid to navigation station"),
Station::AisReceivingStation => write!(f, "ais receiving station"),
Station::LimitedBaseStation => write!(f, "limited base station"),
Station::AisTransmittingStation => write!(f, "AIS transmitting station"),
Station::RepeaterStation => write!(f, "repeater station"),
Station::Other => write!(f, "other"),
}
}
}
impl core::str::FromStr for Station {
type Err = ParseError;
fn from_str(talker_id: &str) -> Result<Self, Self::Err> {
if talker_id.len() < 2 {
return Err(ParseError::InvalidSentence(
"Invalid station identifier".to_string(),
));
}
match &talker_id[0..2] {
"AB" => Ok(Self::BaseStation),
"AD" => Ok(Self::DependentAisBaseStation),
"AI" => Ok(Self::MobileStation),
"AN" => Ok(Self::AidToNavigationStation),
"AR" => Ok(Self::AisReceivingStation),
"AS" => Ok(Self::LimitedBaseStation),
"AT" => Ok(Self::AisTransmittingStation),
"AX" => Ok(Self::RepeaterStation),
_ => Ok(Self::Other),
}
}
}
#[derive(Default, Clone, Debug, PartialEq)]
pub struct VesselDynamicData {
pub own_vessel: bool,
pub station: Station,
pub ais_type: AisClass,
pub mmsi: u32,
pub nav_status: NavigationStatus,
pub rot: Option<f64>,
pub rot_direction: Option<RotDirection>,
pub sog_knots: Option<f64>,
pub high_position_accuracy: bool,
pub latitude: Option<f64>,
pub longitude: Option<f64>,
pub cog: Option<f64>,
pub heading_true: Option<f64>,
pub timestamp_seconds: u8,
pub positioning_system_meta: Option<PositioningSystemMeta>,
pub current_gnss_position: Option<bool>,
pub special_manoeuvre: Option<bool>,
pub raim_flag: bool,
pub class_b_unit_flag: Option<bool>,
pub class_b_display: Option<bool>,
pub class_b_dsc: Option<bool>,
pub class_b_band_flag: Option<bool>,
pub class_b_msg22_flag: Option<bool>,
pub class_b_mode_flag: Option<bool>,
pub class_b_css_flag: Option<bool>,
pub radio_status: Option<u32>,
}
#[derive(Clone, Copy, Debug, PartialEq)]
pub enum AisClass {
Unknown,
ClassA,
ClassB, }
impl Default for AisClass {
fn default() -> AisClass {
AisClass::Unknown
}
}
impl core::fmt::Display for AisClass {
fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
match self {
AisClass::Unknown => write!(f, "unknown"),
AisClass::ClassA => write!(f, "Class A"),
AisClass::ClassB => write!(f, "Class B"),
}
}
}
impl LatLon for VesselDynamicData {
fn latitude(&self) -> Option<f64> {
self.latitude
}
fn longitude(&self) -> Option<f64> {
self.longitude
}
}
#[derive(Clone, Copy, Debug, PartialEq)]
pub enum NavigationStatus {
UnderWayUsingEngine = 0, AtAnchor = 1, NotUnderCommand = 2, RestrictedManoeuverability = 3, ConstrainedByDraught = 4, Moored = 5, Aground = 6, EngagedInFishing = 7, UnderWaySailing = 8, Reserved9 = 9, Reserved10 = 10, Reserved11 = 11, Reserved12 = 12, Reserved13 = 13, AisSartIsActive = 14, NotDefined = 15, }
impl NavigationStatus {
pub fn new(nav_status: u8) -> NavigationStatus {
match nav_status {
0 => NavigationStatus::UnderWayUsingEngine,
1 => NavigationStatus::AtAnchor,
2 => NavigationStatus::NotUnderCommand,
3 => NavigationStatus::RestrictedManoeuverability,
4 => NavigationStatus::ConstrainedByDraught,
5 => NavigationStatus::Moored,
6 => NavigationStatus::Aground,
7 => NavigationStatus::EngagedInFishing,
8 => NavigationStatus::UnderWaySailing,
9 => NavigationStatus::Reserved9,
10 => NavigationStatus::Reserved10,
11 => NavigationStatus::Reserved11,
12 => NavigationStatus::Reserved12,
13 => NavigationStatus::Reserved13,
14 => NavigationStatus::AisSartIsActive,
15 => NavigationStatus::NotDefined,
_ => NavigationStatus::NotDefined,
}
}
pub fn to_value(&self) -> u8 {
*self as u8
}
}
impl core::fmt::Display for NavigationStatus {
fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
match self {
NavigationStatus::UnderWayUsingEngine => write!(f, "under way using engine"),
NavigationStatus::AtAnchor => write!(f, "at anchor"),
NavigationStatus::NotUnderCommand => write!(f, "not under command"),
NavigationStatus::RestrictedManoeuverability => {
write!(f, "restricted manoeuverability")
}
NavigationStatus::ConstrainedByDraught => write!(f, "constrained by draught"),
NavigationStatus::Moored => write!(f, "moored"),
NavigationStatus::Aground => write!(f, "aground"),
NavigationStatus::EngagedInFishing => write!(f, "engaged in fishing"),
NavigationStatus::UnderWaySailing => write!(f, "under way sailing"),
NavigationStatus::Reserved9 => write!(f, "(reserved9)"),
NavigationStatus::Reserved10 => write!(f, "(reserved10)"),
NavigationStatus::Reserved11 => write!(f, "(reserved11)"),
NavigationStatus::Reserved12 => write!(f, "(reserved12)"),
NavigationStatus::Reserved13 => write!(f, "(reserved13)"),
NavigationStatus::AisSartIsActive => write!(f, "ais sart is active"),
NavigationStatus::NotDefined => write!(f, "(notDefined)"),
}
}
}
impl Default for NavigationStatus {
fn default() -> NavigationStatus {
NavigationStatus::NotDefined
}
}
#[derive(Clone, Copy, Debug, PartialEq)]
pub enum PositioningSystemMeta {
Operative, ManualInputMode,
DeadReckoningMode,
Inoperative,
}
impl core::fmt::Display for PositioningSystemMeta {
fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
match self {
PositioningSystemMeta::Operative => write!(f, "operative"),
PositioningSystemMeta::ManualInputMode => write!(f, "manual input mode"),
PositioningSystemMeta::DeadReckoningMode => write!(f, "dead reckoning mode"),
PositioningSystemMeta::Inoperative => write!(f, "inoperative"),
}
}
}
#[derive(Clone, Copy, Debug, PartialEq)]
pub enum RotDirection {
Port,
Center,
Starboard,
}
impl Default for RotDirection {
fn default() -> RotDirection {
RotDirection::Center
}
}
impl core::fmt::Display for RotDirection {
fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
match self {
RotDirection::Port => write!(f, "port"),
RotDirection::Center => write!(f, "center"),
RotDirection::Starboard => write!(f, "starboard"),
}
}
}
#[derive(Default, Clone, Debug, PartialEq)]
pub struct VesselStaticData {
pub own_vessel: bool,
pub ais_type: AisClass,
pub mmsi: u32,
pub ais_version_indicator: u8,
pub imo_number: Option<u32>,
pub call_sign: Option<String>,
pub name: Option<String>,
pub ship_type: ShipType,
pub cargo_type: CargoType,
pub equipment_vendor_id: Option<String>,
pub equipment_model: Option<u8>,
pub equipment_serial_number: Option<u32>,
pub dimension_to_bow: Option<u16>,
pub dimension_to_stern: Option<u16>,
pub dimension_to_port: Option<u16>,
pub dimension_to_starboard: Option<u16>,
pub position_fix_type: Option<PositionFixType>,
pub eta: Option<DateTime<Utc>>,
pub draught10: Option<u8>,
pub destination: Option<String>,
pub mothership_mmsi: Option<u32>,
}
#[derive(Clone, Copy, Debug, PartialEq)]
pub enum ShipType {
NotAvailable = 0, Reserved1 = 10, WingInGround = 20, Fishing = 30, Towing = 31, TowingLong = 32, DredgingOrUnderwaterOps = 33, DivingOps = 34, MilitaryOps = 35, Sailing = 36, PleasureCraft = 37, Reserved38 = 38, Reserved39 = 39, HighSpeedCraft = 40, Pilot = 50, SearchAndRescue = 51, Tug = 52, PortTender = 53, AntiPollutionEquipment = 54, LawEnforcement = 55, SpareLocal56 = 56, SpareLocal57 = 57, MedicalTransport = 58, Noncombatant = 59, Passenger = 60, Cargo = 70, Tanker = 80, Other = 90, }
impl ShipType {
pub fn new(raw: u8) -> ShipType {
match raw {
0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 => ShipType::NotAvailable,
10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 => ShipType::Reserved1,
20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 => ShipType::WingInGround,
30 => ShipType::Fishing,
31 => ShipType::Towing,
32 => ShipType::TowingLong,
33 => ShipType::DredgingOrUnderwaterOps,
34 => ShipType::DivingOps,
35 => ShipType::MilitaryOps,
36 => ShipType::Sailing,
37 => ShipType::PleasureCraft,
38 => ShipType::Reserved38,
39 => ShipType::Reserved39,
40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 => ShipType::HighSpeedCraft,
50 => ShipType::Pilot,
51 => ShipType::SearchAndRescue,
52 => ShipType::Tug,
53 => ShipType::PortTender,
54 => ShipType::AntiPollutionEquipment,
55 => ShipType::LawEnforcement,
56 => ShipType::SpareLocal56,
57 => ShipType::SpareLocal57,
58 => ShipType::MedicalTransport,
59 => ShipType::Noncombatant,
60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 => ShipType::Passenger,
70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 => ShipType::Cargo,
80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 => ShipType::Tanker,
90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 => ShipType::Other,
_ => {
warn!("Unexpected ship and cargo type: {}", raw);
ShipType::NotAvailable
}
}
}
pub fn to_value(&self) -> u8 {
*self as u8
}
}
impl Default for ShipType {
fn default() -> ShipType {
ShipType::NotAvailable
}
}
impl core::fmt::Display for ShipType {
fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
match self {
ShipType::NotAvailable => write!(f, "(not available)"),
ShipType::Reserved1 => write!(f, "(reserved)"),
ShipType::WingInGround => write!(f, "wing in ground"),
ShipType::Fishing => write!(f, "fishing"),
ShipType::Towing => write!(f, "towing"),
ShipType::TowingLong => write!(f, "towing, long"),
ShipType::DredgingOrUnderwaterOps => write!(f, "dredging or underwater ops"),
ShipType::DivingOps => write!(f, "diving ops"),
ShipType::MilitaryOps => write!(f, "military ops"),
ShipType::Sailing => write!(f, "sailing"),
ShipType::PleasureCraft => write!(f, "pleasure craft"),
ShipType::Reserved38 => write!(f, "(reserved)"),
ShipType::Reserved39 => write!(f, "(reserved)"),
ShipType::HighSpeedCraft => write!(f, "high-speed craft"),
ShipType::Pilot => write!(f, "pilot"),
ShipType::SearchAndRescue => write!(f, "search and rescue"),
ShipType::Tug => write!(f, "tug"),
ShipType::PortTender => write!(f, "port tender"),
ShipType::AntiPollutionEquipment => write!(f, "anti-pollution equipment"),
ShipType::LawEnforcement => write!(f, "law enforcement"),
ShipType::SpareLocal56 => write!(f, "(local)"),
ShipType::SpareLocal57 => write!(f, "(local)"),
ShipType::MedicalTransport => write!(f, "medical transport"),
ShipType::Noncombatant => write!(f, "noncombatant"),
ShipType::Passenger => write!(f, "passenger"),
ShipType::Cargo => write!(f, "cargo"),
ShipType::Tanker => write!(f, "tanker"),
ShipType::Other => write!(f, "other"),
}
}
}
#[derive(Clone, Copy, Debug, PartialEq)]
pub enum CargoType {
Undefined = 10, HazardousCategoryA = 11, HazardousCategoryB = 12, HazardousCategoryC = 13, HazardousCategoryD = 14, Reserved5 = 15, Reserved6 = 16, Reserved7 = 17, Reserved8 = 18, Reserved9 = 19, }
impl CargoType {
pub fn new(raw: u8) -> CargoType {
match raw {
10 | 20 | 40 | 60 | 70 | 80 | 90 => CargoType::Undefined,
11 | 21 | 41 | 61 | 71 | 81 | 91 => CargoType::HazardousCategoryA,
12 | 22 | 42 | 62 | 72 | 82 | 92 => CargoType::HazardousCategoryB,
13 | 23 | 43 | 63 | 73 | 83 | 93 => CargoType::HazardousCategoryC,
14 | 24 | 44 | 64 | 74 | 84 | 94 => CargoType::HazardousCategoryD,
15 | 25 | 45 | 65 | 75 | 85 | 95 => CargoType::Reserved5,
16 | 26 | 46 | 66 | 76 | 86 | 96 => CargoType::Reserved6,
17 | 27 | 47 | 67 | 77 | 87 | 97 => CargoType::Reserved7,
18 | 28 | 48 | 68 | 78 | 88 | 98 => CargoType::Reserved8,
19 | 29 | 49 | 69 | 79 | 89 | 99 => CargoType::Reserved9,
_ => {
warn!("Unexpected ship and cargo type: {}", raw);
CargoType::Undefined
}
}
}
pub fn to_value(&self) -> u8 {
*self as u8
}
}
impl core::fmt::Display for CargoType {
fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
match self {
CargoType::Undefined => write!(f, "undefined"),
CargoType::HazardousCategoryA => write!(f, "hazardous category A"),
CargoType::HazardousCategoryB => write!(f, "hazardous category B"),
CargoType::HazardousCategoryC => write!(f, "hazardous category C"),
CargoType::HazardousCategoryD => write!(f, "hazardous category D"),
CargoType::Reserved5 => write!(f, "(reserved)"),
CargoType::Reserved6 => write!(f, "(reserved)"),
CargoType::Reserved7 => write!(f, "(reserved)"),
CargoType::Reserved8 => write!(f, "(reserved)"),
CargoType::Reserved9 => write!(f, "(reserved)"),
}
}
}
impl Default for CargoType {
fn default() -> CargoType {
CargoType::Undefined
}
}
#[derive(Clone, Copy, Debug, PartialEq)]
pub enum PositionFixType {
Undefined = 0, GPS = 1, GLONASS = 2, GPSGLONASS = 3, LoranC = 4, Chayka = 5, IntegratedNavigationSystem = 6, Surveyed = 7, Galileo = 8, }
impl PositionFixType {
pub fn new(raw: u8) -> PositionFixType {
match raw {
0 => PositionFixType::Undefined,
1 => PositionFixType::GPS,
2 => PositionFixType::GLONASS,
3 => PositionFixType::GPSGLONASS,
4 => PositionFixType::LoranC,
5 => PositionFixType::Chayka,
6 => PositionFixType::IntegratedNavigationSystem,
7 => PositionFixType::Surveyed,
8 => PositionFixType::Galileo,
_ => {
warn!("Unrecognized position fix type: {}", raw);
PositionFixType::Undefined
}
}
}
pub fn to_value(&self) -> u8 {
*self as u8
}
}
impl core::fmt::Display for PositionFixType {
fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
match self {
PositionFixType::Undefined => write!(f, "undefined"),
PositionFixType::GPS => write!(f, "GPS"),
PositionFixType::GLONASS => write!(f, "GLONASS"),
PositionFixType::GPSGLONASS => write!(f, "GPS/GLONASS"),
PositionFixType::LoranC => write!(f, "Loran-C"),
PositionFixType::Chayka => write!(f, "Chayka"),
PositionFixType::IntegratedNavigationSystem => {
write!(f, "integrated navigation system")
}
PositionFixType::Surveyed => write!(f, "surveyed"),
PositionFixType::Galileo => write!(f, "Galileo"),
}
}
}
impl VesselStaticData {
pub fn country(&self) -> Option<&'static str> {
match self.mmsi / 1000000 {
201 => Some("AL"), 202 => Some("AD"), 203 => Some("AT"), 204 => Some("PT"), 205 => Some("BE"), 206 => Some("BY"), 207 => Some("BG"), 208 => Some("VA"), 209 => Some("CY"), 210 => Some("CY"), 211 => Some("DE"), 212 => Some("CY"), 213 => Some("GE"), 214 => Some("MD"), 215 => Some("MT"), 216 => Some("AM"), 218 => Some("DE"), 219 => Some("DK"), 220 => Some("DK"), 224 => Some("ES"), 225 => Some("ES"), 226 => Some("FR"), 227 => Some("FR"), 228 => Some("FR"), 229 => Some("MT"), 230 => Some("FI"), 231 => Some("FO"), 232 => Some("GB"), 233 => Some("GB"), 234 => Some("GB"), 235 => Some("GB"), 236 => Some("GI"), 237 => Some("GR"), 238 => Some("HR"), 239 => Some("GR"), 240 => Some("GR"), 241 => Some("GR"), 242 => Some("MA"), 243 => Some("HU"), 244 => Some("NL"), 245 => Some("NL"), 246 => Some("NL"), 247 => Some("IT"), 248 => Some("MT"), 249 => Some("MT"), 250 => Some("IE"), 251 => Some("IS"), 252 => Some("LI"), 253 => Some("LU"), 254 => Some("MC"), 255 => Some("PT"), 256 => Some("MT"), 257 => Some("NO"), 258 => Some("NO"), 259 => Some("NO"), 261 => Some("PL"), 262 => Some("ME"), 263 => Some("PT"), 264 => Some("RO"), 265 => Some("SE"), 266 => Some("SE"), 267 => Some("SK"), 268 => Some("SM"), 269 => Some("CH"), 270 => Some("CZ"), 271 => Some("TR"), 272 => Some("UA"), 273 => Some("RU"), 274 => Some("MK"), 275 => Some("LV"), 276 => Some("EE"), 277 => Some("LT"), 278 => Some("SI"), 279 => Some("RS"), 301 => Some("AI"), 303 => Some("US"), 304 => Some("AG"), 305 => Some("AG"), 306 => Some("BQ"), 307 => Some("AW"), 308 => Some("BS"), 309 => Some("BS"), 310 => Some("BM"), 311 => Some("BS"), 312 => Some("BZ"), 314 => Some("BB"), 316 => Some("CA"), 319 => Some("KY"), 321 => Some("CR"), 323 => Some("CU"), 325 => Some("DM"), 327 => Some("DO"), 329 => Some("GP"), 330 => Some("GD"), 331 => Some("GL"), 332 => Some("GT"), 334 => Some("HN"), 336 => Some("HT"), 338 => Some("US"), 339 => Some("JM"), 341 => Some("KN"), 343 => Some("LC"), 345 => Some("MX"), 347 => Some("MQ"), 348 => Some("MS"), 350 => Some("NI"), 351 => Some("PA"), 352 => Some("PA"), 353 => Some("PA"), 354 => Some("PA"), 355 => Some("PA"), 356 => Some("PA"), 357 => Some("PA"), 358 => Some("PR"), 359 => Some("SV"), 361 => Some("PM"), 362 => Some("TT"), 364 => Some("TC"), 366 => Some("US"), 367 => Some("US"), 368 => Some("US"), 369 => Some("US"), 370 => Some("PA"), 371 => Some("PA"), 372 => Some("PA"), 373 => Some("PA"), 374 => Some("PA"), 375 => Some("VC"), 376 => Some("VC"), 377 => Some("VC"), 378 => Some("VG"), 379 => Some("VI"), 401 => Some("AF"), 403 => Some("SA"), 405 => Some("BD"), 408 => Some("BH"), 410 => Some("BT"), 412 => Some("CN"), 413 => Some("CN"), 414 => Some("CN"), 416 => Some("TW"), 417 => Some("LK"), 419 => Some("IN"), 422 => Some("IR"), 423 => Some("AZ"), 425 => Some("IQ"), 428 => Some("IL"), 431 => Some("JP"), 432 => Some("JP"), 434 => Some("TM"), 436 => Some("KZ"), 437 => Some("UZ"), 438 => Some("JO"), 440 => Some("KR"), 441 => Some("KR"), 443 => Some("PS"), 445 => Some("KR"), 447 => Some("KW"), 450 => Some("LB"), 451 => Some("KG"), 453 => Some("MO"), 455 => Some("MV"), 457 => Some("MN"), 459 => Some("NP"), 461 => Some("OM"), 463 => Some("PK"), 466 => Some("QA"), 468 => Some("SY"), 470 => Some("AE"), 471 => Some("AE"), 472 => Some("TJ"), 473 => Some("YE"), 475 => Some("YE"), 477 => Some("HK"), 478 => Some("BA"), 501 => Some("TF"), 503 => Some("AU"), 506 => Some("MM"), 508 => Some("BN"), 510 => Some("FM"), 511 => Some("PW"), 512 => Some("NZ"), 514 => Some("KH"), 515 => Some("KH"), 516 => Some("CX"), 518 => Some("CK"), 520 => Some("FJ"), 523 => Some("CC"), 525 => Some("ID"), 529 => Some("KI"), 531 => Some("LA"), 533 => Some("MY"), 536 => Some("MP"), 538 => Some("MH"), 540 => Some("NC"), 542 => Some("NU"), 544 => Some("NR"), 546 => Some("PF"), 548 => Some("PH"), 550 => Some("TL"), 553 => Some("PG"), 555 => Some("PN"), 557 => Some("SB"), 559 => Some("AS"), 561 => Some("WS"), 563 => Some("SG"), 564 => Some("SG"), 565 => Some("SG"), 566 => Some("SG"), 567 => Some("TH"), 570 => Some("TO"), 572 => Some("TV"), 574 => Some("VN"), 576 => Some("VU"), 577 => Some("VU"), 578 => Some("WF"), 601 => Some("ZA"), 603 => Some("AO"), 605 => Some("DZ"), 607 => Some("TF"), 608 => Some("SH"), 609 => Some("BI"), 610 => Some("BJ"), 611 => Some("BW"), 612 => Some("CF"), 613 => Some("CM"), 615 => Some("CG"), 616 => Some("KM"), 617 => Some("CV"), 618 => Some("TF"), 619 => Some("CI"), 620 => Some("KM"), 621 => Some("DJ"), 622 => Some("EG"), 624 => Some("ET"), 625 => Some("ER"), 626 => Some("GA"), 627 => Some("GH"), 629 => Some("GM"), 630 => Some("GW"), 631 => Some("GQ"), 632 => Some("GN"), 633 => Some("BF"), 634 => Some("KE"), 635 => Some("TF"), 636 => Some("LR"), 637 => Some("LR"), 638 => Some("SS"), 642 => Some("LY"), 644 => Some("LS"), 645 => Some("MU"), 647 => Some("MG"), 649 => Some("ML"), 650 => Some("MZ"), 654 => Some("MR"), 655 => Some("MW"), 656 => Some("NE"), 657 => Some("NG"), 659 => Some("NA"), 660 => Some("TF"), 661 => Some("RW"), 662 => Some("SD"), 663 => Some("SN"), 664 => Some("SC"), 665 => Some("SH"), 666 => Some("SO"), 667 => Some("SL"), 668 => Some("ST"), 669 => Some("SZ"), 670 => Some("TD"), 671 => Some("TG"), 672 => Some("TN"), 674 => Some("TZ"), 675 => Some("UG"), 676 => Some("CG"), 677 => Some("TZ"), 678 => Some("ZM"), 679 => Some("ZW"), 701 => Some("AR"), 710 => Some("BR"), 720 => Some("BO"), 725 => Some("CL"), 730 => Some("CO"), 735 => Some("EC"), 740 => Some("FK"), 745 => Some("GF"), 750 => Some("GY"), 755 => Some("PY"), 760 => Some("PE"), 765 => Some("SR"), 770 => Some("UY"), 775 => Some("VE"), _ => None,
}
}
}