From 216d1bfc03779986a7b8d02f77432257ccc11a46 Mon Sep 17 00:00:00 2001 From: Dominic Nguyen Date: Sat, 29 Oct 2022 21:29:26 -0700 Subject: [PATCH 01/76] Add files via upload --- AuroraLabelItemsPlugin.cs | 499 +++++++++++++++++++++++++++++--------- 1 file changed, 385 insertions(+), 114 deletions(-) diff --git a/AuroraLabelItemsPlugin.cs b/AuroraLabelItemsPlugin.cs index 4fda7be..30511e5 100644 --- a/AuroraLabelItemsPlugin.cs +++ b/AuroraLabelItemsPlugin.cs @@ -1,114 +1,385 @@ -using System; -using System.Collections.Generic; -using System.Text.RegularExpressions; -using vatsys; -using vatsys.Plugin; -using System.Collections.Concurrent; -using System.ComponentModel.Composition; //<--Need to add a reference to System.ComponentModel.Composition - -//Note the reference to vatsys (set Copy Local to false) -----> - -namespace AuroraLabelItemsPlugin -{ - [Export(typeof(IPlugin))] - public class AuroraLabelItemsPlugin : ILabelPlugin - { - /// The name of the custom label item we've added to Labels.xml in the Profile - const string LABEL_ITEM_LEVEL = "AURORA_LEVEL"; - const string LABEL_ITEM_3DIGIT_GROUNDSPEED = "AURORA_GROUNDSPEED"; - readonly static CustomColour EastboundColour = new CustomColour(255, 125, 0); - readonly static CustomColour WestboundColour = new CustomColour(0, 125, 255); - readonly ConcurrentDictionary eastboundCallsigns = new ConcurrentDictionary(); - - /// Plugin Name - public string Name { get => "Aurora Label Items"; } - - /// This is called each time a flight data record is updated - /// Here we are updating the eastbound callsigns dictionary with each flight data record - public void OnFDRUpdate(FDP2.FDR updated) - { - if (FDP2.GetFDRIndex(updated.Callsign) == -1) //FDR was removed (that's what triggered the update) - eastboundCallsigns.TryRemove(updated.Callsign, out _); - else - { - if(updated.ParsedRoute.Count > 1) - { - //calculate track from first route point to last (Departure point to destination point) - var rte = updated.ParsedRoute; - double trk = Conversions.CalculateTrack(rte.First().Intersection.LatLong, rte.Last().Intersection.LatLong); - bool east = trk >= 0 && trk < 180; - eastboundCallsigns.AddOrUpdate(updated.Callsign, east, (c,e) => east); - } - } - } - - /// This is called each time a radar track is updated - public void OnRadarTrackUpdate(RDP.RadarTrack updated) - { - - } - - /// vatSys calls this function when it encounters a custom label item (defined in Labels.xml) during the label rendering. - /// itemType is the value of the Type attribute in Labels.xml - /// If it's not our item being called (another plugins, for example), return null. - /// As a general rule, don't do processing in here as you'll slow down the ASD refresh. In the case of parsing a level to a string though, that's fine. - public CustomLabelItem GetCustomLabelItem(string itemType, Track track, FDP2.FDR flightDataRecord, RDP.RadarTrack radarTrack) - { - if (flightDataRecord == null) - return null; - - switch (itemType) - { - case LABEL_ITEM_LEVEL: - int level = radarTrack == null ? flightDataRecord.PRL / 100 : radarTrack.CorrectedAltitude / 100; - string sLevel = level.ToString("D3"); - if (level > RDP.TRANSITION_ALTITUDE)//then flight level - sLevel = "F" + sLevel; - else - sLevel = "A" + sLevel; - - return new CustomLabelItem() - { - Text = sLevel - }; - case LABEL_ITEM_3DIGIT_GROUNDSPEED: - //get groundspeed value from either FDR or radarTrack if coupled - var gs = radarTrack == null ? flightDataRecord.PredictedPosition.Groundspeed : radarTrack.GroundSpeed; - return new CustomLabelItem() - { - Text = gs.ToString("000")//format as 3 digits (with leading zeros) - }; - default: - return null; - } - } - - public CustomColour SelectASDTrackColour(Track track) - { - //only apply East/West colour to jurisdiction state - if (track.State != MMI.HMIStates.Jurisdiction) - return null; - - var fdr = track.GetFDR(); - //if track doesn't have an FDR coupled do nothing - if (fdr == null) - return null; - - //read our dictionary of stored bools (true means is easterly) and return the correct colour - if (eastboundCallsigns.TryGetValue(fdr.Callsign, out bool east)) - { - if (east) - return EastboundColour; - else - return WestboundColour; - } - - return null; - } - - public CustomColour SelectGroundTrackColour(Track track) - { - return null; - } - } -} +using System; +using System.Collections.Generic; +using System.Text.RegularExpressions; +using vatsys; +using vatsys.Plugin; +using System.Collections.Concurrent; +using System.ComponentModel.Composition; //<--Need to add a reference to System.ComponentModel.Composition +using static vatsys.Performance; +using static vatsys.Network; + + +//Note the reference to vatsys (set Copy Local to false) -----> + +namespace AuroraLabelItemsPlugin +{ + [Export(typeof(IPlugin))] + + public class AuroraLabelItemsPlugin : ILabelPlugin, IStripPlugin + { + + /// The name of the custom label item we've added to Labels.xml in the Profile + const string LABEL_ITEM_COMM_ICON = "AURORA_COMM_ICON"; //field a(2) + const string LABEL_ITEM_ADSB_CPDLC = "AURORA_ADSB_CPDLC"; //field c(4) + const string LABEL_ITEM_SCC = "AURORA_SCC"; //field c(5) + const string LABEL_ITEM_ANNOT_IND = "AURORA_ANNOT_IND"; //field e(1) + const string LABEL_ITEM_RESTR = "AURORA_RESTR"; //field f(1) + const string LABEL_ITEM_VMI = "AURORA_VMI"; //field h(1) + const string LABEL_ITEM_RADAR_IND = "AURORA_RADAR_IND"; //field k(1) + const string LABEL_ITEM_3DIGIT_GROUNDSPEED = "AURORA_GROUNDSPEED"; + const string STRIP_ITEM_CALLSIGN = "AURORA_CALLSIGN"; + const string STRIP_ITEM_SEP_FLAG = "AURORA_SEP_FLAG"; + readonly static CustomColour FlagColour = new CustomColour(0, 255, 255); + readonly static CustomColour EastboundColour = new CustomColour(240, 255, 255); + readonly static CustomColour WestboundColour = new CustomColour(240, 231, 140); + readonly static CustomColour Fuchsia = new CustomColour(255, 0, 255); + readonly static CustomColour nonRVSMColour = new CustomColour(242, 133, 0); + readonly ConcurrentDictionary eastboundCallsigns = new ConcurrentDictionary(); + readonly ConcurrentDictionary pbnValues = new ConcurrentDictionary(); + + /// Plugin Name + public string Name { get => "Aurora Label Items"; } + + /// This is called each time a flight data record is updated + /// Here we are updating the eastbound callsigns dictionary with each flight data record + /// When the FDR is updated we check if it still exists in the Flight Data Processor and remove from our dictionary if not. Otherwise we do some simple regex matching to find + /// the flight planned PBN category and store the character we want to display in the label in the dictionary. + + public void OnFDRUpdate(FDP2.FDR updated) + { + if (FDP2.GetFDRIndex(updated.Callsign) == -1) //FDR was removed (that's what triggered the update) + eastboundCallsigns.TryRemove(updated.Callsign, out _); + + else + + { + + if (updated.ParsedRoute.Count > 1) + { + //calculate track from first route point to last (Departure point to destination point) + var rte = updated.ParsedRoute; + double trk = Conversions.CalculateTrack(rte.First().Intersection.LatLong, rte.Last().Intersection.LatLong); + bool east = trk >= 0 && trk < 180; + eastboundCallsigns.AddOrUpdate(updated.Callsign, east, (c, e) => east); + } + } + } + + //internal void SendContactMe(NetworkPilot pilot, VSCSFrequency freq) + //{ + // if (validATC && HaveConnection && !((DateTime.UtcNow - pilot.LastContactMe).TotalMinutes < 1.0)) + // { + // string text = "Please contact me on " + Conversions.FrequencyToString(freq.Frequency); + // if (freq.AliasFrequency != VSCSFrequency.None.Frequency) + // { + // text = text + " (" + Conversions.FrequencyToString(freq.AliasFrequency) + ")"; + // } + // + // SendTextMessage(pilot.Callsign, text); + // pilot.LastContactMe = DateTime.UtcNow; + // } + //} + + /// This is called each time a radar track is updated + public void OnRadarTrackUpdate(RDP.RadarTrack updated) + { + + } + + /// vatSys calls this function when it encounters a custom label item (defined in Labels.xml) during the label rendering. + /// itemType is the value of the Type attribute in Labels.xml + /// If it's not our item being called (another plugins, for example), return null. + /// As a general rule, don't do processing in here as you'll slow down the ASD refresh. In the case of parsing a level to a string though, that's fine. + public CustomLabelItem GetPrivateMessage(RadioMessage downLink, FDP2.FDR flightDataRecord) + { + + if (downLink.Request && downLink.Address == flightDataRecord.Callsign) + return new CustomLabelItem() + { + Type = LABEL_ITEM_ADSB_CPDLC, + Text = "⬜▼⟏" + }; + return null; + } + + public CustomLabelItem GetCustomLabelItem(string itemType, Track track, FDP2.FDR flightDataRecord, RDP.RadarTrack radarTrack) + { + Match pbn = Regex.Match(flightDataRecord.Remarks, @"PBN\/\w+\s"); + //bool inmarsat = updated.Remarks.Contains("NAV/RNP2") || updated.Remarks.Contains("NAV/GLS RNP2"); + bool cpdlc = Regex.IsMatch(flightDataRecord.AircraftEquip, @"J5") || Regex.IsMatch(flightDataRecord.AircraftEquip, @"J7"); + bool adsc = Regex.IsMatch(flightDataRecord.AircraftSurvEquip, @"D1"); + bool adsb = flightDataRecord.ADSB; //Regex.IsMatch(flightDataRecord.AircraftSurvEquip, @"B\d"); + bool rnp10 = Regex.IsMatch(pbn.Value, @"A1"); + bool rnp4 = Regex.IsMatch(pbn.Value, @"L1"); + bool rvsm = flightDataRecord.RVSM; + var ca = AlertTypes.STCA; + var la = AlertTypes.MSAW; + var ra = AlertTypes.DAIW; + var rcf = AlertTypes.RAD; + //var mti = transponder.TransponderCode = 7777; + var dup = AlertTypes.DAIW; + var pos = AlertTypes.MPR; + var spd = AlertTypes.ETO; + + + if (flightDataRecord == null) + return null; + + + switch (itemType) + { + case LABEL_ITEM_COMM_ICON: + + return new CustomLabelItem() + { + Text = "⬜" + }; + + case LABEL_ITEM_ADSB_CPDLC: + + + if (!adsb & cpdlc) + + return new CustomLabelItem() + { + Text = "⧆" + }; + + else if (!adsb) + + return new CustomLabelItem() + { + Text = "⎕" + }; + + else if (cpdlc & track.State is MMI.HMIStates.Preactive | track.State is MMI.HMIStates.Announced) + + return new CustomLabelItem() + { + CustomForeColour = Fuchsia, + Text = "*" + }; + else if (cpdlc) + + return new CustomLabelItem() + { + Text = "*" + }; + + return null; + + + //case LABEL_ITEM_SCC: + // + // if (pos) + // return new CustomLabelItem() + // { + // Text = "&" + // }; + // + // + // + // return null; + + case LABEL_ITEM_ANNOT_IND: + + if (flightDataRecord.GlobalOpData == "") + + return new CustomLabelItem() + { + Text = "◦" + //Action < CustomLabelItemMouseClickEventArgs > OnMouseClick; + }; + + else + + return new CustomLabelItem() + { + Text = "&" + }; + + case LABEL_ITEM_RESTR: + + if (Regex.IsMatch(flightDataRecord.GlobalOpData, @"AT \d\d\d\d")) + + return new CustomLabelItem() + { + Text = "x" + }; + + return null; + + case LABEL_ITEM_VMI: + int level = radarTrack == null ? flightDataRecord.PRL / 100 : radarTrack.CorrectedAltitude / 100; + string sLevel = level.ToString("D3"); + + + if (radarTrack.VerticalSpeed > 300)//Climbing + + return new CustomLabelItem() + { + Text = "↑" + }; + else if (radarTrack.VerticalSpeed < 300)//Descending + return new CustomLabelItem() + { + Text = "↓" + }; + + return null; + + case LABEL_ITEM_RADAR_IND: + + return new CustomLabelItem() + { + Text = "◦★" + OnMouseClick = (e) =>. + }; + + case LABEL_ITEM_3DIGIT_GROUNDSPEED: + //get groundspeed value from either FDR or radarTrack if coupled + var gs = radarTrack == null ? flightDataRecord.PredictedPosition.Groundspeed : radarTrack.GroundSpeed; + return new CustomLabelItem() + { + Text = "N" + gs.ToString("000")//format as 3 digits (with leading zeros) + }; + + default: + return null; + } + } + + + public CustomColour SelectASDTrackColour(Track track) + { + //only apply East/West colour to jurisdiction state + if (track.State != MMI.HMIStates.Jurisdiction) + return null; + + var fdr = track.GetFDR(); + //if track doesn't have an FDR coupled do nothing + if (fdr == null) + return null; + + //read our dictionary of stored bools (true means is easterly) and return the correct colour + return GetDirectionColour(fdr.Callsign); + } + + public CustomColour SelectGroundTrackColour(Track track) + { + return null; + } + + private CustomColour GetDirectionColour(string callsign) + { + if (eastboundCallsigns.TryGetValue(callsign, out bool east)) + { + if (east) + return EastboundColour; + else + return WestboundColour; + } + + return null; + } + public CustomStripItem MachNumberTech(string itemType, PerformanceData mnt) + { + + if (mnt.IsJet) + return new CustomStripItem() + { + Type = STRIP_ITEM_SEP_FLAG, + Text = "M R" + }; + return null; + } + public CustomStripItem GetCustomStripItem(string itemType, Track track, FDP2.FDR flightDataRecord, RDP.RadarTrack radarTrack) + + { + Match pbn = Regex.Match(flightDataRecord.Remarks, @"PBN\/\w+\s"); + //bool inmarsat = updated.Remarks.Contains("NAV/RNP2") || updated.Remarks.Contains("NAV/GLS RNP2"); + bool cpdlc = Regex.IsMatch(flightDataRecord.AircraftEquip, @"J5") || Regex.IsMatch(flightDataRecord.AircraftEquip, @"J7"); + bool adsc = Regex.IsMatch(flightDataRecord.AircraftSurvEquip, @"D1"); + bool adsb = Regex.IsMatch(flightDataRecord.AircraftSurvEquip, @"B\d"); + bool rnp10 = Regex.IsMatch(pbn.Value, @"A1"); + bool rnp4 = Regex.IsMatch(pbn.Value, @"L1"); + bool isEastBound = true; + + + if (flightDataRecord is null) + return null; + + switch (itemType) + { + case STRIP_ITEM_CALLSIGN: + + eastboundCallsigns.TryGetValue(flightDataRecord.Callsign, out isEastBound); + + if (isEastBound) + { + return new CustomStripItem() + { + BackColourIdentity = Colours.Identities.StripText, + ForeColourIdentity = Colours.Identities.StripBackground, + Text = flightDataRecord.Callsign + }; + } + else + { + return new CustomStripItem() + { + BackColourIdentity = Colours.Identities.StripBackground, + ForeColourIdentity = Colours.Identities.StripText, + Text = flightDataRecord.Callsign + }; + } + case LABEL_ITEM_ADSB_CPDLC: + + + if (!adsb & cpdlc) + + return new CustomStripItem() + { + Text = "⧆" + }; + + else if (isEastBound & !adsb & cpdlc) + + return new CustomStripItem() + { + BackColourIdentity = Colours.Identities.StripText, + ForeColourIdentity = Colours.Identities.StripBackground, + Text = "⧆" + }; + + else if (!adsb) + + return new CustomStripItem() + { + Text = "⎕" + }; + + else if (cpdlc) + + return new CustomStripItem() + { + Text = "*" + }; + + return null; + + case STRIP_ITEM_SEP_FLAG: + + if (flightDataRecord.RVSM) + return new CustomStripItem() + { + CustomBackColour = FlagColour, + Text = "W" + }; + return null; + + default: return null; + } + } +} +} \ No newline at end of file From 210c574fdfc5a3ae532a59565c48c18ec166d4aa Mon Sep 17 00:00:00 2001 From: Dominic Nguyen Date: Tue, 1 Nov 2022 21:24:55 -0700 Subject: [PATCH 02/76] Update AuroraLabelItemsPlugin.cs --- AuroraLabelItemsPlugin.cs | 67 +++++++++++++++++++++++++-------------- 1 file changed, 44 insertions(+), 23 deletions(-) diff --git a/AuroraLabelItemsPlugin.cs b/AuroraLabelItemsPlugin.cs index 30511e5..0b3c12b 100644 --- a/AuroraLabelItemsPlugin.cs +++ b/AuroraLabelItemsPlugin.cs @@ -29,11 +29,8 @@ public class AuroraLabelItemsPlugin : ILabelPlugin, IStripPlugin const string LABEL_ITEM_3DIGIT_GROUNDSPEED = "AURORA_GROUNDSPEED"; const string STRIP_ITEM_CALLSIGN = "AURORA_CALLSIGN"; const string STRIP_ITEM_SEP_FLAG = "AURORA_SEP_FLAG"; - readonly static CustomColour FlagColour = new CustomColour(0, 255, 255); readonly static CustomColour EastboundColour = new CustomColour(240, 255, 255); - readonly static CustomColour WestboundColour = new CustomColour(240, 231, 140); - readonly static CustomColour Fuchsia = new CustomColour(255, 0, 255); - readonly static CustomColour nonRVSMColour = new CustomColour(242, 133, 0); + readonly static CustomColour WestboundColour = new CustomColour(240, 231, 140); readonly ConcurrentDictionary eastboundCallsigns = new ConcurrentDictionary(); readonly ConcurrentDictionary pbnValues = new ConcurrentDictionary(); @@ -93,7 +90,7 @@ public void OnRadarTrackUpdate(RDP.RadarTrack updated) public CustomLabelItem GetPrivateMessage(RadioMessage downLink, FDP2.FDR flightDataRecord) { - if (downLink.Request && downLink.Address == flightDataRecord.Callsign) + if (downLink.Request & downLink.Address == flightDataRecord.Callsign) return new CustomLabelItem() { Type = LABEL_ITEM_ADSB_CPDLC, @@ -121,7 +118,6 @@ public CustomLabelItem GetCustomLabelItem(string itemType, Track track, FDP2.FDR var pos = AlertTypes.MPR; var spd = AlertTypes.ETO; - if (flightDataRecord == null) return null; @@ -156,7 +152,7 @@ public CustomLabelItem GetCustomLabelItem(string itemType, Track track, FDP2.FDR return new CustomLabelItem() { - CustomForeColour = Fuchsia, + BackColourIdentity = Colours.Identities.VSCSButtonDepressed, Text = "*" }; else if (cpdlc) @@ -211,16 +207,33 @@ public CustomLabelItem GetCustomLabelItem(string itemType, Track track, FDP2.FDR case LABEL_ITEM_VMI: int level = radarTrack == null ? flightDataRecord.PRL / 100 : radarTrack.CorrectedAltitude / 100; - string sLevel = level.ToString("D3"); + int cfl; + bool isCfl = Int32.TryParse(flightDataRecord.CFLString, out cfl); + string sLevel = level.ToString("D3"); + + if (radarTrack.CorrectedAltitude - flightDataRecord.PRL >= 300)//deviating above + + return new CustomLabelItem() + { + Text = "+" + }; + + else if (radarTrack.CorrectedAltitude - flightDataRecord.PRL <= 300)//deviating below + return new CustomLabelItem() + { + Text = "-" + }; - if (radarTrack.VerticalSpeed > 300)//Climbing + else if (radarTrack.VerticalSpeed > 300 | cfl > flightDataRecord.PRL)//Issued or trending climb return new CustomLabelItem() { Text = "↑" }; - else if (radarTrack.VerticalSpeed < 300)//Descending + + else if (radarTrack.VerticalSpeed < 300 | cfl < flightDataRecord.PRL)//Issued or trending descent + return new CustomLabelItem() { Text = "↓" @@ -233,7 +246,7 @@ public CustomLabelItem GetCustomLabelItem(string itemType, Track track, FDP2.FDR return new CustomLabelItem() { Text = "◦★" - OnMouseClick = (e) =>. + //OnMouseClick = (e) =>. }; case LABEL_ITEM_3DIGIT_GROUNDSPEED: @@ -336,22 +349,23 @@ public CustomStripItem GetCustomStripItem(string itemType, Track track, FDP2.FDR case LABEL_ITEM_ADSB_CPDLC: - if (!adsb & cpdlc) + if (isEastBound & !adsb & cpdlc) - return new CustomStripItem() - { - Text = "⧆" - }; + return new CustomStripItem() + { + BackColourIdentity = Colours.Identities.StripText, + ForeColourIdentity = Colours.Identities.StripBackground, + Text = "⧆" + }; + + else if (!adsb & cpdlc) - else if (isEastBound & !adsb & cpdlc) - return new CustomStripItem() { - BackColourIdentity = Colours.Identities.StripText, - ForeColourIdentity = Colours.Identities.StripBackground, Text = "⧆" }; - + + else if (!adsb) return new CustomStripItem() @@ -370,11 +384,18 @@ public CustomStripItem GetCustomStripItem(string itemType, Track track, FDP2.FDR case STRIP_ITEM_SEP_FLAG: + if (adsc & cpdlc & rnp4 | rnp10) + return new CustomStripItem() + { + Text = "D" + }; + return null; + if (flightDataRecord.RVSM) return new CustomStripItem() { - CustomBackColour = FlagColour, - Text = "W" + BackColourIdentity = Colours.Identities.JurisdictionIQL, + Text = " W" }; return null; From 2110c524c0940a028a4e7f57394d70a555238b74 Mon Sep 17 00:00:00 2001 From: Dominic Nguyen Date: Wed, 2 Nov 2022 09:28:04 -0700 Subject: [PATCH 03/76] Update AuroraLabelItemsPlugin.cs --- AuroraLabelItemsPlugin.cs | 76 ++++++++++++++++++++++++--------------- 1 file changed, 48 insertions(+), 28 deletions(-) diff --git a/AuroraLabelItemsPlugin.cs b/AuroraLabelItemsPlugin.cs index 0b3c12b..03a927d 100644 --- a/AuroraLabelItemsPlugin.cs +++ b/AuroraLabelItemsPlugin.cs @@ -25,12 +25,17 @@ public class AuroraLabelItemsPlugin : ILabelPlugin, IStripPlugin const string LABEL_ITEM_ANNOT_IND = "AURORA_ANNOT_IND"; //field e(1) const string LABEL_ITEM_RESTR = "AURORA_RESTR"; //field f(1) const string LABEL_ITEM_VMI = "AURORA_VMI"; //field h(1) + const string LABEL_ITEM_CLEARED_LEVEL = "AURORA_CLEARED_LEVEL"; //field i(7) const string LABEL_ITEM_RADAR_IND = "AURORA_RADAR_IND"; //field k(1) const string LABEL_ITEM_3DIGIT_GROUNDSPEED = "AURORA_GROUNDSPEED"; const string STRIP_ITEM_CALLSIGN = "AURORA_CALLSIGN"; const string STRIP_ITEM_SEP_FLAG = "AURORA_SEP_FLAG"; readonly static CustomColour EastboundColour = new CustomColour(240, 255, 255); - readonly static CustomColour WestboundColour = new CustomColour(240, 231, 140); + readonly static CustomColour WestboundColour = new CustomColour(240, 231, 140); + readonly static CustomColour NonRVSM = new CustomColour(242, 133, 0); + readonly static CustomColour SepFlags = new CustomColour(0, 196, 253); + readonly static CustomColour Probe = new CustomColour(0, 255, 0); + readonly static CustomColour NotCDA = new CustomColour(100, 0, 100); readonly ConcurrentDictionary eastboundCallsigns = new ConcurrentDictionary(); readonly ConcurrentDictionary pbnValues = new ConcurrentDictionary(); @@ -101,6 +106,9 @@ public CustomLabelItem GetPrivateMessage(RadioMessage downLink, FDP2.FDR flightD public CustomLabelItem GetCustomLabelItem(string itemType, Track track, FDP2.FDR flightDataRecord, RDP.RadarTrack radarTrack) { + if (flightDataRecord == null) + return null; + Match pbn = Regex.Match(flightDataRecord.Remarks, @"PBN\/\w+\s"); //bool inmarsat = updated.Remarks.Contains("NAV/RNP2") || updated.Remarks.Contains("NAV/GLS RNP2"); bool cpdlc = Regex.IsMatch(flightDataRecord.AircraftEquip, @"J5") || Regex.IsMatch(flightDataRecord.AircraftEquip, @"J7"); @@ -118,8 +126,7 @@ public CustomLabelItem GetCustomLabelItem(string itemType, Track track, FDP2.FDR var pos = AlertTypes.MPR; var spd = AlertTypes.ETO; - if (flightDataRecord == null) - return null; + switch (itemType) @@ -152,7 +159,7 @@ public CustomLabelItem GetCustomLabelItem(string itemType, Track track, FDP2.FDR return new CustomLabelItem() { - BackColourIdentity = Colours.Identities.VSCSButtonDepressed, + CustomForeColour = NotCDA, Text = "*" }; else if (cpdlc) @@ -179,20 +186,11 @@ public CustomLabelItem GetCustomLabelItem(string itemType, Track track, FDP2.FDR case LABEL_ITEM_ANNOT_IND: - if (flightDataRecord.GlobalOpData == "") - return new CustomLabelItem() { - Text = "◦" - //Action < CustomLabelItemMouseClickEventArgs > OnMouseClick; + Text = "◦&" }; - else - - return new CustomLabelItem() - { - Text = "&" - }; case LABEL_ITEM_RESTR: @@ -211,44 +209,58 @@ public CustomLabelItem GetCustomLabelItem(string itemType, Track track, FDP2.FDR bool isCfl = Int32.TryParse(flightDataRecord.CFLString, out cfl); string sLevel = level.ToString("D3"); - if (radarTrack.CorrectedAltitude - flightDataRecord.PRL >= 300)//deviating above + if (radarTrack.CorrectedAltitude - flightDataRecord.RFL >= 300)//deviating above return new CustomLabelItem() { Text = "+" }; - else if (radarTrack.CorrectedAltitude - flightDataRecord.PRL <= 300)//deviating below + else if (radarTrack.CorrectedAltitude - flightDataRecord.RFL <= -300)//deviating below return new CustomLabelItem() { Text = "-" }; - else if (radarTrack.VerticalSpeed > 300 | cfl > flightDataRecord.PRL)//Issued or trending climb + else if (cfl > flightDataRecord.RFL | radarTrack.VerticalSpeed > 300)//Issued or trending climb return new CustomLabelItem() { - Text = "↑" + Text = "↑", + CustomForeColour = flightDataRecord.RVSM ? NonRVSM : null, }; - else if (radarTrack.VerticalSpeed < 300 | cfl < flightDataRecord.PRL)//Issued or trending descent + else if (cfl < flightDataRecord.RFL | radarTrack.VerticalSpeed < -300 )//Issued or trending descent return new CustomLabelItem() { - Text = "↓" + Text = "↓", + CustomForeColour = flightDataRecord.RVSM ? NonRVSM : null, }; + //else if (Track.TrackTypes.TRACK_TYPE_FP & flightDataRecord.PRL > 0)//Manually entered PRL + // + // return new CustomLabelItem() + // { + // Text = "R" + // }; + + else if (radarTrack.CorrectedAltitude == cfl | radarTrack.CorrectedAltitude == flightDataRecord.RFL)//level + + return null; + return null; case LABEL_ITEM_RADAR_IND: return new CustomLabelItem() { - Text = "◦★" - //OnMouseClick = (e) =>. + Text = "◦★", + //OnMouseClick = e }; + case LABEL_ITEM_3DIGIT_GROUNDSPEED: //get groundspeed value from either FDR or radarTrack if coupled var gs = radarTrack == null ? flightDataRecord.PredictedPosition.Groundspeed : radarTrack.GroundSpeed; @@ -261,7 +273,12 @@ public CustomLabelItem GetCustomLabelItem(string itemType, Track track, FDP2.FDR return null; } } - + private void ItemMouseClick(CustomLabelItemMouseClickEventArgs e) + { + e.Track.IQL = !e.Track.IQL; + //MMI.ClickspotTypes.Label_Toggle; + e.Handled = true; + } public CustomColour SelectASDTrackColour(Track track) { @@ -318,7 +335,6 @@ public CustomStripItem GetCustomStripItem(string itemType, Track track, FDP2.FDR bool rnp4 = Regex.IsMatch(pbn.Value, @"L1"); bool isEastBound = true; - if (flightDataRecord is null) return null; @@ -387,14 +403,14 @@ public CustomStripItem GetCustomStripItem(string itemType, Track track, FDP2.FDR if (adsc & cpdlc & rnp4 | rnp10) return new CustomStripItem() { - Text = "D" + Text = rnp4 ? " 3" : " D" }; return null; - + if (flightDataRecord.RVSM) return new CustomStripItem() { - BackColourIdentity = Colours.Identities.JurisdictionIQL, + CustomBackColour = SepFlags, Text = " W" }; return null; @@ -402,5 +418,9 @@ public CustomStripItem GetCustomStripItem(string itemType, Track track, FDP2.FDR default: return null; } } -} + public void Test() + { + throw new NotImplementedException(); + } + } } \ No newline at end of file From 678744e4cae30a3d78948046cb623c114f12b87d Mon Sep 17 00:00:00 2001 From: Dominic Nguyen Date: Thu, 3 Nov 2022 19:59:15 -0700 Subject: [PATCH 04/76] For Rowan --- AuroraLabelItemsPlugin.cs | 190 +++++++++++++++++++++++--------------- 1 file changed, 118 insertions(+), 72 deletions(-) diff --git a/AuroraLabelItemsPlugin.cs b/AuroraLabelItemsPlugin.cs index 03a927d..225dc80 100644 --- a/AuroraLabelItemsPlugin.cs +++ b/AuroraLabelItemsPlugin.cs @@ -18,7 +18,8 @@ namespace AuroraLabelItemsPlugin public class AuroraLabelItemsPlugin : ILabelPlugin, IStripPlugin { - /// The name of the custom label item we've added to Labels.xml in the Profile + /// The name of the custom label item we've added to Labels + /// in the Profile const string LABEL_ITEM_COMM_ICON = "AURORA_COMM_ICON"; //field a(2) const string LABEL_ITEM_ADSB_CPDLC = "AURORA_ADSB_CPDLC"; //field c(4) const string LABEL_ITEM_SCC = "AURORA_SCC"; //field c(5) @@ -29,7 +30,9 @@ public class AuroraLabelItemsPlugin : ILabelPlugin, IStripPlugin const string LABEL_ITEM_RADAR_IND = "AURORA_RADAR_IND"; //field k(1) const string LABEL_ITEM_3DIGIT_GROUNDSPEED = "AURORA_GROUNDSPEED"; const string STRIP_ITEM_CALLSIGN = "AURORA_CALLSIGN"; - const string STRIP_ITEM_SEP_FLAG = "AURORA_SEP_FLAG"; + const string STRIP_ITEM_DIST_FLAG = "AURORA_DIST_FLAG"; + const string STRIP_ITEM_RVSM_FLAG = "AURORA_RVSM_FLAG"; + const string STRIP_ITEM_MAN_EST = "AURORA_MAN_EST"; readonly static CustomColour EastboundColour = new CustomColour(240, 255, 255); readonly static CustomColour WestboundColour = new CustomColour(240, 231, 140); readonly static CustomColour NonRVSM = new CustomColour(242, 133, 0); @@ -106,26 +109,29 @@ public CustomLabelItem GetPrivateMessage(RadioMessage downLink, FDP2.FDR flightD public CustomLabelItem GetCustomLabelItem(string itemType, Track track, FDP2.FDR flightDataRecord, RDP.RadarTrack radarTrack) { + if (flightDataRecord == null) return null; Match pbn = Regex.Match(flightDataRecord.Remarks, @"PBN\/\w+\s"); - //bool inmarsat = updated.Remarks.Contains("NAV/RNP2") || updated.Remarks.Contains("NAV/GLS RNP2"); bool cpdlc = Regex.IsMatch(flightDataRecord.AircraftEquip, @"J5") || Regex.IsMatch(flightDataRecord.AircraftEquip, @"J7"); bool adsc = Regex.IsMatch(flightDataRecord.AircraftSurvEquip, @"D1"); bool adsb = flightDataRecord.ADSB; //Regex.IsMatch(flightDataRecord.AircraftSurvEquip, @"B\d"); bool rnp10 = Regex.IsMatch(pbn.Value, @"A1"); bool rnp4 = Regex.IsMatch(pbn.Value, @"L1"); bool rvsm = flightDataRecord.RVSM; - var ca = AlertTypes.STCA; - var la = AlertTypes.MSAW; - var ra = AlertTypes.DAIW; - var rcf = AlertTypes.RAD; + int level = radarTrack == null ? flightDataRecord.PRL / 100 : radarTrack.CorrectedAltitude / 100; + int cfl; + bool isCfl = Int32.TryParse(flightDataRecord.CFLString, out cfl); + //string sLevel = level.ToString("D3"); + //string ca = AlertTypes.STCA.ToString(@"CA"); + //string la = AlertTypes.MSAW.ToString(@"LA"); + //string ra = AlertTypes.DAIW.ToString(@"RA"); + //string rcf = AlertTypes.RAD.ToString(@"RCF"); + //string dup = AlertTypes.DAIW.ToString(@"DUP"); + //string pos = AlertTypes.MPR.ToString("POS"); + //string spd = AlertTypes.ETO.ToString(@"SPD"); //var mti = transponder.TransponderCode = 7777; - var dup = AlertTypes.DAIW; - var pos = AlertTypes.MPR; - var spd = AlertTypes.ETO; - @@ -133,10 +139,10 @@ public CustomLabelItem GetCustomLabelItem(string itemType, Track track, FDP2.FDR { case LABEL_ITEM_COMM_ICON: - return new CustomLabelItem() - { - Text = "⬜" - }; + return new CustomLabelItem() + { + Text = "⬜" + }; case LABEL_ITEM_ADSB_CPDLC: @@ -155,10 +161,11 @@ public CustomLabelItem GetCustomLabelItem(string itemType, Track track, FDP2.FDR Text = "⎕" }; - else if (cpdlc & track.State is MMI.HMIStates.Preactive | track.State is MMI.HMIStates.Announced) + else if (cpdlc & track.State == MMI.HMIStates.Preactive | track.State is MMI.HMIStates.Announced) return new CustomLabelItem() { + ForeColourIdentity = Colours.Identities.Custom, CustomForeColour = NotCDA, Text = "*" }; @@ -174,21 +181,17 @@ public CustomLabelItem GetCustomLabelItem(string itemType, Track track, FDP2.FDR //case LABEL_ITEM_SCC: // - // if (pos) // return new CustomLabelItem() // { - // Text = "&" - // }; - // - // - // - // return null; - + // Text = pos //| ca | la | ra | rcf | dup | spd + // }; + + case LABEL_ITEM_ANNOT_IND: - + return new CustomLabelItem() { - Text = "◦&" + Text = "◦" //& }; @@ -204,60 +207,74 @@ public CustomLabelItem GetCustomLabelItem(string itemType, Track track, FDP2.FDR return null; case LABEL_ITEM_VMI: - int level = radarTrack == null ? flightDataRecord.PRL / 100 : radarTrack.CorrectedAltitude / 100; - int cfl; - bool isCfl = Int32.TryParse(flightDataRecord.CFLString, out cfl); - string sLevel = level.ToString("D3"); - if (radarTrack.CorrectedAltitude - flightDataRecord.RFL >= 300)//deviating above + + if (level == cfl || level == flightDataRecord.RFL)//level return new CustomLabelItem() { - Text = "+" + Text = null }; - else if (radarTrack.CorrectedAltitude - flightDataRecord.RFL <= -300)//deviating below + else if (cfl > level && track.NewCFL || radarTrack.VerticalSpeed > 300)//Issued or trending climb return new CustomLabelItem() { - Text = "-" + Text = "↑", + ForeColourIdentity = Colours.Identities.Custom, + CustomForeColour = !flightDataRecord.RVSM ? NonRVSM : track.NewCFL ? Probe : null, }; - else if (cfl > flightDataRecord.RFL | radarTrack.VerticalSpeed > 300)//Issued or trending climb + else if (cfl > 0 && cfl < level && track.NewCFL || radarTrack.VerticalSpeed < -300)//Issued or trending descent return new CustomLabelItem() { - Text = "↑", - CustomForeColour = flightDataRecord.RVSM ? NonRVSM : null, + Text = "↓", + ForeColourIdentity = Colours.Identities.Custom, + CustomForeColour = !flightDataRecord.RVSM ? NonRVSM : track.NewCFL ? Probe : null, }; - else if (cfl < flightDataRecord.RFL | radarTrack.VerticalSpeed < -300 )//Issued or trending descent + else if (level - flightDataRecord.RFL / 100 >= 3)//deviating above return new CustomLabelItem() { - Text = "↓", - CustomForeColour = flightDataRecord.RVSM ? NonRVSM : null, + Text = "+" }; - //else if (Track.TrackTypes.TRACK_TYPE_FP & flightDataRecord.PRL > 0)//Manually entered PRL - // - // return new CustomLabelItem() - // { - // Text = "R" - // }; - - else if (radarTrack.CorrectedAltitude == cfl | radarTrack.CorrectedAltitude == flightDataRecord.RFL)//level + else if (level - flightDataRecord.RFL / 100 <= -3)//deviating below - return null; + return new CustomLabelItem() + { + Text = "-" + }; return null; + //else if (Track.TrackTypes.TRACK_TYPE_FP & flightDataRecord.PRL > 0)//Manually entered PRL + // + // return new CustomLabelItem() + // { + // Text = "R" + // }; + + + + + case LABEL_ITEM_CLEARED_LEVEL: + + return new CustomLabelItem() + { + Text = level == cfl ? null : flightDataRecord.CFLString, // flightDataRecord.CFLLower + "B" + flightDataRecord.CFLUpper + ForeColourIdentity = Colours.Identities.Custom, + CustomForeColour = !flightDataRecord.RVSM ? NonRVSM : track.NewCFL ? Probe : null, + }; + case LABEL_ITEM_RADAR_IND: return new CustomLabelItem() { - Text = "◦★", - //OnMouseClick = e + Text = "◦",//★ + //OnMouseClick = }; @@ -279,7 +296,15 @@ private void ItemMouseClick(CustomLabelItemMouseClickEventArgs e) //MMI.ClickspotTypes.Label_Toggle; e.Handled = true; } - + public CustomLabelItem TrackSelectBox(Track a, MMI.ClickspotCategories b) //box around selected tracks + { + //if (MMI.ClickspotTypes.Track_Select) + return new CustomLabelItem() + { + Border = MMI.SelectedTrack != null ? BorderFlags.All : BorderFlags.None, + }; + } + public CustomColour SelectASDTrackColour(Track track) { //only apply East/West colour to jurisdiction state @@ -312,27 +337,29 @@ private CustomColour GetDirectionColour(string callsign) return null; } - public CustomStripItem MachNumberTech(string itemType, PerformanceData mnt) + public void MachNumberTech(string itemType, PerformanceData mnt) { + mnt.IsJet = true; - if (mnt.IsJet) - return new CustomStripItem() - { - Type = STRIP_ITEM_SEP_FLAG, - Text = "M R" - }; - return null; } + + //public void Estimates(FDP2.FDR.ExtractedRoute.Segment estimate) + //{ + // estimate.IsPETO = true; + //} public CustomStripItem GetCustomStripItem(string itemType, Track track, FDP2.FDR flightDataRecord, RDP.RadarTrack radarTrack) { Match pbn = Regex.Match(flightDataRecord.Remarks, @"PBN\/\w+\s"); - //bool inmarsat = updated.Remarks.Contains("NAV/RNP2") || updated.Remarks.Contains("NAV/GLS RNP2"); bool cpdlc = Regex.IsMatch(flightDataRecord.AircraftEquip, @"J5") || Regex.IsMatch(flightDataRecord.AircraftEquip, @"J7"); bool adsc = Regex.IsMatch(flightDataRecord.AircraftSurvEquip, @"D1"); - bool adsb = Regex.IsMatch(flightDataRecord.AircraftSurvEquip, @"B\d"); + bool adsb = flightDataRecord.ADSB; //Regex.IsMatch(flightDataRecord.AircraftSurvEquip, @"B\d"); bool rnp10 = Regex.IsMatch(pbn.Value, @"A1"); bool rnp4 = Regex.IsMatch(pbn.Value, @"L1"); + bool rvsm = flightDataRecord.RVSM; + int level = radarTrack == null ? flightDataRecord.PRL / 100 : radarTrack.CorrectedAltitude / 100; + int cfl; + bool isCfl = Int32.TryParse(flightDataRecord.CFLString, out cfl); bool isEastBound = true; if (flightDataRecord is null) @@ -398,29 +425,48 @@ public CustomStripItem GetCustomStripItem(string itemType, Track track, FDP2.FDR return null; - case STRIP_ITEM_SEP_FLAG: + case STRIP_ITEM_DIST_FLAG: + + + //if (MachNumberTech.isJet;) + // return new CustomStripItem() + // { + // Text = "M" + "R" + // }; + //return null; + + if (adsc & cpdlc & rnp4 || rnp10) - if (adsc & cpdlc & rnp4 | rnp10) return new CustomStripItem() { - Text = rnp4 ? " 3" : " D" + Text = rnp4 ? "3" : "D" }; + return null; - if (flightDataRecord.RVSM) + case STRIP_ITEM_RVSM_FLAG: + + if (rvsm) + return new CustomStripItem() { + BackColourIdentity = Colours.Identities.Custom, CustomBackColour = SepFlags, - Text = " W" + Text = "W" }; return null; + //case STRIP_ITEM_MAN_EST: + + //if (Estimates) + // return new CustomStripItem() + // { + // BackColourIdentity = Colours.Identities.HighlightedText + // }; + //return null; + default: return null; - } + } } - public void Test() - { - throw new NotImplementedException(); - } } } \ No newline at end of file From dcfd9935fa2baf3bad7b8eb0e49efe0394a93ad3 Mon Sep 17 00:00:00 2001 From: Maxim Salikhov Date: Sat, 5 Nov 2022 11:50:36 -0400 Subject: [PATCH 05/76] Fix MNT flags --- AuroraLabelItemsPlugin.cs | 31 +++++++++++++++---------------- 1 file changed, 15 insertions(+), 16 deletions(-) diff --git a/AuroraLabelItemsPlugin.cs b/AuroraLabelItemsPlugin.cs index 225dc80..85248da 100644 --- a/AuroraLabelItemsPlugin.cs +++ b/AuroraLabelItemsPlugin.cs @@ -337,10 +337,10 @@ private CustomColour GetDirectionColour(string callsign) return null; } - public void MachNumberTech(string itemType, PerformanceData mnt) + public static bool MachNumberTech(PerformanceData mnt) { - mnt.IsJet = true; - + if (mnt == null) return false; + return mnt.IsJet; } //public void Estimates(FDP2.FDR.ExtractedRoute.Segment estimate) @@ -426,23 +426,22 @@ public CustomStripItem GetCustomStripItem(string itemType, Track track, FDP2.FDR return null; case STRIP_ITEM_DIST_FLAG: + string stripText = ""; - - //if (MachNumberTech.isJet;) - // return new CustomStripItem() - // { - // Text = "M" + "R" - // }; - //return null; + if (MachNumberTech(flightDataRecord.PerformanceData)) + { + stripText += "MR"; + } if (adsc & cpdlc & rnp4 || rnp10) + { + stripText += rnp4 ? "3" : "D"; + } - return new CustomStripItem() - { - Text = rnp4 ? "3" : "D" - }; - - return null; + return new CustomStripItem() + { + Text = stripText + }; case STRIP_ITEM_RVSM_FLAG: From c93414b48751b4bf13a00fd102789940843ec617 Mon Sep 17 00:00:00 2001 From: Maxim Salikhov Date: Sat, 5 Nov 2022 15:13:18 -0400 Subject: [PATCH 06/76] Fix error when activating FDR --- AuroraLabelItemsPlugin.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/AuroraLabelItemsPlugin.cs b/AuroraLabelItemsPlugin.cs index 85248da..2ba707b 100644 --- a/AuroraLabelItemsPlugin.cs +++ b/AuroraLabelItemsPlugin.cs @@ -213,7 +213,7 @@ public CustomLabelItem GetCustomLabelItem(string itemType, Track track, FDP2.FDR return new CustomLabelItem() { - Text = null + Text = "" }; else if (cfl > level && track.NewCFL || radarTrack.VerticalSpeed > 300)//Issued or trending climb From 21883a88de9d3fd8063216cfaa9523e1ed360a72 Mon Sep 17 00:00:00 2001 From: Maxim Salikhov Date: Sat, 5 Nov 2022 17:49:16 -0400 Subject: [PATCH 07/76] Fix CFL label --- AuroraLabelItemsPlugin.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/AuroraLabelItemsPlugin.cs b/AuroraLabelItemsPlugin.cs index 2ba707b..cbe698a 100644 --- a/AuroraLabelItemsPlugin.cs +++ b/AuroraLabelItemsPlugin.cs @@ -264,7 +264,7 @@ public CustomLabelItem GetCustomLabelItem(string itemType, Track track, FDP2.FDR return new CustomLabelItem() { - Text = level == cfl ? null : flightDataRecord.CFLString, // flightDataRecord.CFLLower + "B" + flightDataRecord.CFLUpper + Text = level == cfl ? "" : flightDataRecord.CFLString, // flightDataRecord.CFLLower + "B" + flightDataRecord.CFLUpper ForeColourIdentity = Colours.Identities.Custom, CustomForeColour = !flightDataRecord.RVSM ? NonRVSM : track.NewCFL ? Probe : null, }; From ac6235a9e7a499838d7bf37a9ad6a6cb0da8b6f6 Mon Sep 17 00:00:00 2001 From: Dominic Nguyen Date: Thu, 10 Nov 2022 17:52:55 -0800 Subject: [PATCH 08/76] Track Rendering Error --- AuroraLabelItemsPlugin.cs | 424 ++++++------------ AuroraLabelItemsPlugin.csproj | 3 +- AuroraStripItemPlugin.cs | 276 ++++++++++++ bin/Release/AuroraLabelItemsPlugin.dll | Bin 6656 -> 10752 bytes bin/Release/AuroraLabelItemsPlugin.pdb | Bin 22016 -> 26112 bytes ...lItemsPlugin.csprojAssemblyReference.cache | Bin 424 -> 0 bytes ...gnTimeResolveAssemblyReferencesInput.cache | Bin 6889 -> 6879 bytes ...ItemsPlugin.csproj.CoreCompileInputs.cache | 2 +- ...belItemsPlugin.csproj.FileListAbsolute.txt | 6 + obj/Release/AuroraLabelItemsPlugin.dll | Bin 6656 -> 10752 bytes obj/Release/AuroraLabelItemsPlugin.pdb | Bin 22016 -> 26112 bytes ...gnTimeResolveAssemblyReferencesInput.cache | Bin 6893 -> 6883 bytes 12 files changed, 427 insertions(+), 284 deletions(-) create mode 100644 AuroraStripItemPlugin.cs delete mode 100644 obj/Debug/AuroraLabelItemsPlugin.csprojAssemblyReference.cache diff --git a/AuroraLabelItemsPlugin.cs b/AuroraLabelItemsPlugin.cs index cbe698a..7c30cae 100644 --- a/AuroraLabelItemsPlugin.cs +++ b/AuroraLabelItemsPlugin.cs @@ -15,7 +15,7 @@ namespace AuroraLabelItemsPlugin { [Export(typeof(IPlugin))] - public class AuroraLabelItemsPlugin : ILabelPlugin, IStripPlugin + public class AuroraLabelItemsPlugin : ILabelPlugin { /// The name of the custom label item we've added to Labels @@ -29,10 +29,6 @@ public class AuroraLabelItemsPlugin : ILabelPlugin, IStripPlugin const string LABEL_ITEM_CLEARED_LEVEL = "AURORA_CLEARED_LEVEL"; //field i(7) const string LABEL_ITEM_RADAR_IND = "AURORA_RADAR_IND"; //field k(1) const string LABEL_ITEM_3DIGIT_GROUNDSPEED = "AURORA_GROUNDSPEED"; - const string STRIP_ITEM_CALLSIGN = "AURORA_CALLSIGN"; - const string STRIP_ITEM_DIST_FLAG = "AURORA_DIST_FLAG"; - const string STRIP_ITEM_RVSM_FLAG = "AURORA_RVSM_FLAG"; - const string STRIP_ITEM_MAN_EST = "AURORA_MAN_EST"; readonly static CustomColour EastboundColour = new CustomColour(240, 255, 255); readonly static CustomColour WestboundColour = new CustomColour(240, 231, 140); readonly static CustomColour NonRVSM = new CustomColour(242, 133, 0); @@ -40,8 +36,6 @@ public class AuroraLabelItemsPlugin : ILabelPlugin, IStripPlugin readonly static CustomColour Probe = new CustomColour(0, 255, 0); readonly static CustomColour NotCDA = new CustomColour(100, 0, 100); readonly ConcurrentDictionary eastboundCallsigns = new ConcurrentDictionary(); - readonly ConcurrentDictionary pbnValues = new ConcurrentDictionary(); - /// Plugin Name public string Name { get => "Aurora Label Items"; } @@ -49,7 +43,7 @@ public class AuroraLabelItemsPlugin : ILabelPlugin, IStripPlugin /// Here we are updating the eastbound callsigns dictionary with each flight data record /// When the FDR is updated we check if it still exists in the Flight Data Processor and remove from our dictionary if not. Otherwise we do some simple regex matching to find /// the flight planned PBN category and store the character we want to display in the label in the dictionary. - + public void OnFDRUpdate(FDP2.FDR updated) { if (FDP2.GetFDRIndex(updated.Callsign) == -1) //FDR was removed (that's what triggered the update) @@ -95,17 +89,9 @@ public void OnRadarTrackUpdate(RDP.RadarTrack updated) /// itemType is the value of the Type attribute in Labels.xml /// If it's not our item being called (another plugins, for example), return null. /// As a general rule, don't do processing in here as you'll slow down the ASD refresh. In the case of parsing a level to a string though, that's fine. - public CustomLabelItem GetPrivateMessage(RadioMessage downLink, FDP2.FDR flightDataRecord) - { - if (downLink.Request & downLink.Address == flightDataRecord.Callsign) - return new CustomLabelItem() - { - Type = LABEL_ITEM_ADSB_CPDLC, - Text = "⬜▼⟏" - }; - return null; - } + //public static event EventHandler PrivateMessagesChanged; + public CustomLabelItem GetCustomLabelItem(string itemType, Track track, FDP2.FDR flightDataRecord, RDP.RadarTrack radarTrack) { @@ -113,6 +99,9 @@ public CustomLabelItem GetCustomLabelItem(string itemType, Track track, FDP2.FDR if (flightDataRecord == null) return null; + if (track == null) + return null; + Match pbn = Regex.Match(flightDataRecord.Remarks, @"PBN\/\w+\s"); bool cpdlc = Regex.IsMatch(flightDataRecord.AircraftEquip, @"J5") || Regex.IsMatch(flightDataRecord.AircraftEquip, @"J7"); bool adsc = Regex.IsMatch(flightDataRecord.AircraftSurvEquip, @"D1"); @@ -138,144 +127,145 @@ public CustomLabelItem GetCustomLabelItem(string itemType, Track track, FDP2.FDR switch (itemType) { case LABEL_ITEM_COMM_ICON: - - return new CustomLabelItem() - { - Text = "⬜" - }; - - case LABEL_ITEM_ADSB_CPDLC: - - - if (!adsb & cpdlc) - - return new CustomLabelItem() - { - Text = "⧆" - }; - - else if (!adsb) - - return new CustomLabelItem() - { - Text = "⎕" - }; - - else if (cpdlc & track.State == MMI.HMIStates.Preactive | track.State is MMI.HMIStates.Announced) - - return new CustomLabelItem() - { - ForeColourIdentity = Colours.Identities.Custom, - CustomForeColour = NotCDA, - Text = "*" - }; - else if (cpdlc) - - return new CustomLabelItem() - { - Text = "*" - }; - - return null; - - - //case LABEL_ITEM_SCC: - // - // return new CustomLabelItem() - // { - // Text = pos //| ca | la | ra | rcf | dup | spd - // }; - - - case LABEL_ITEM_ANNOT_IND: - + return new CustomLabelItem() { - Text = "◦" //& + Text = "⬜" //⬜▼⟏ }; - - - case LABEL_ITEM_RESTR: - - if (Regex.IsMatch(flightDataRecord.GlobalOpData, @"AT \d\d\d\d")) - - return new CustomLabelItem() - { - Text = "x" - }; - - return null; - - case LABEL_ITEM_VMI: - + + case LABEL_ITEM_ADSB_CPDLC: + + + if (!adsb & cpdlc) + + return new CustomLabelItem() + { + Text = "⧆" + }; + + else if (!adsb) + + return new CustomLabelItem() + { + Text = "⎕" + }; + + else if (cpdlc & track.State == MMI.HMIStates.Preactive | track.State is MMI.HMIStates.Announced) + + return new CustomLabelItem() + { + ForeColourIdentity = Colours.Identities.Custom, + CustomForeColour = NotCDA, + Text = "*" + }; + + else if (cpdlc) + + return new CustomLabelItem() + { + Text = "*" + }; + + return null; + + + //case LABEL_ITEM_SCC: + // + // return new CustomLabelItem() + // { + // Text = pos //| ca | la | ra | rcf | dup | spd + // }; + + + case LABEL_ITEM_ANNOT_IND: + + return new CustomLabelItem() + { + Text = "◦" //& + }; + + + case LABEL_ITEM_RESTR: + + if (Regex.IsMatch(flightDataRecord.GlobalOpData, @"AT \d\d\d\d")) + + return new CustomLabelItem() + { + Text = "x" + }; + + return null; + + case LABEL_ITEM_VMI: + var vs = radarTrack == null ? flightDataRecord.PredictedPosition.VerticalSpeed : radarTrack.VerticalSpeed; if (level == cfl || level == flightDataRecord.RFL)//level - - return new CustomLabelItem() - { - Text = "" - }; - - else if (cfl > level && track.NewCFL || radarTrack.VerticalSpeed > 300)//Issued or trending climb - - return new CustomLabelItem() - { - Text = "↑", - ForeColourIdentity = Colours.Identities.Custom, - CustomForeColour = !flightDataRecord.RVSM ? NonRVSM : track.NewCFL ? Probe : null, - }; - - else if (cfl > 0 && cfl < level && track.NewCFL || radarTrack.VerticalSpeed < -300)//Issued or trending descent - - return new CustomLabelItem() - { - Text = "↓", - ForeColourIdentity = Colours.Identities.Custom, - CustomForeColour = !flightDataRecord.RVSM ? NonRVSM : track.NewCFL ? Probe : null, - }; - - else if (level - flightDataRecord.RFL / 100 >= 3)//deviating above - - return new CustomLabelItem() - { - Text = "+" - }; - - else if (level - flightDataRecord.RFL / 100 <= -3)//deviating below - - return new CustomLabelItem() - { - Text = "-" - }; + + return new CustomLabelItem() + { + Text = "" + }; + + else if (cfl > level && track.NewCFL || vs > 300)//Issued or trending climb + + return new CustomLabelItem() + { + Text = "↑", + ForeColourIdentity = Colours.Identities.Custom, + CustomForeColour = !rvsm ? NonRVSM : track.NewCFL ? Probe : default + }; + + else if (cfl > 0 && cfl < level && track.NewCFL || vs < -300)//Issued or trending descent + + return new CustomLabelItem() + { + Text = "↓", + ForeColourIdentity = Colours.Identities.Custom, + CustomForeColour = !rvsm ? NonRVSM : track.NewCFL ? Probe : default + }; + + else if (level - flightDataRecord.RFL / 100 >= 3)//deviating above + + return new CustomLabelItem() + { + Text = "+" + }; + + else if (level - flightDataRecord.RFL / 100 <= -3)//deviating below + + return new CustomLabelItem() + { + Text = "-" + }; + + + //else if (Track.TrackTypes.TRACK_TYPE_FP)//Manually entered PRL + // + // return new CustomLabelItem() + // { + // Text = "R" + // }; return null; - //else if (Track.TrackTypes.TRACK_TYPE_FP & flightDataRecord.PRL > 0)//Manually entered PRL - // - // return new CustomLabelItem() - // { - // Text = "R" - // }; - - case LABEL_ITEM_CLEARED_LEVEL: - - return new CustomLabelItem() - { - Text = level == cfl ? "" : flightDataRecord.CFLString, // flightDataRecord.CFLLower + "B" + flightDataRecord.CFLUpper - ForeColourIdentity = Colours.Identities.Custom, - CustomForeColour = !flightDataRecord.RVSM ? NonRVSM : track.NewCFL ? Probe : null, - }; - - case LABEL_ITEM_RADAR_IND: - - return new CustomLabelItem() - { - Text = "◦",//★ - //OnMouseClick = - }; + + return new CustomLabelItem() + { + Text = level == cfl ? "" : flightDataRecord.CFLString, + ForeColourIdentity = Colours.Identities.Custom, + CustomForeColour = !rvsm ? NonRVSM : Probe + }; + + case LABEL_ITEM_RADAR_IND: + + return new CustomLabelItem() + { + Text = "◦"//★ + //OnMouseClick = + }; case LABEL_ITEM_3DIGIT_GROUNDSPEED: @@ -290,12 +280,12 @@ public CustomLabelItem GetCustomLabelItem(string itemType, Track track, FDP2.FDR return null; } } - private void ItemMouseClick(CustomLabelItemMouseClickEventArgs e) - { - e.Track.IQL = !e.Track.IQL; - //MMI.ClickspotTypes.Label_Toggle; - e.Handled = true; - } + // private void ItemMouseClick(CustomLabelItemMouseClickEventArgs e) + // { + // e.Track.IQL = !e.Track.IQL; + // //MMI.ClickspotTypes.Label_Toggle; + // e.Handled = true; + // } public CustomLabelItem TrackSelectBox(Track a, MMI.ClickspotCategories b) //box around selected tracks { //if (MMI.ClickspotTypes.Track_Select) @@ -304,7 +294,7 @@ public CustomLabelItem TrackSelectBox(Track a, MMI.ClickspotCategories b) //box Border = MMI.SelectedTrack != null ? BorderFlags.All : BorderFlags.None, }; } - + public CustomColour SelectASDTrackColour(Track track) { //only apply East/West colour to jurisdiction state @@ -337,135 +327,5 @@ private CustomColour GetDirectionColour(string callsign) return null; } - public static bool MachNumberTech(PerformanceData mnt) - { - if (mnt == null) return false; - return mnt.IsJet; - } - - //public void Estimates(FDP2.FDR.ExtractedRoute.Segment estimate) - //{ - // estimate.IsPETO = true; - //} - public CustomStripItem GetCustomStripItem(string itemType, Track track, FDP2.FDR flightDataRecord, RDP.RadarTrack radarTrack) - - { - Match pbn = Regex.Match(flightDataRecord.Remarks, @"PBN\/\w+\s"); - bool cpdlc = Regex.IsMatch(flightDataRecord.AircraftEquip, @"J5") || Regex.IsMatch(flightDataRecord.AircraftEquip, @"J7"); - bool adsc = Regex.IsMatch(flightDataRecord.AircraftSurvEquip, @"D1"); - bool adsb = flightDataRecord.ADSB; //Regex.IsMatch(flightDataRecord.AircraftSurvEquip, @"B\d"); - bool rnp10 = Regex.IsMatch(pbn.Value, @"A1"); - bool rnp4 = Regex.IsMatch(pbn.Value, @"L1"); - bool rvsm = flightDataRecord.RVSM; - int level = radarTrack == null ? flightDataRecord.PRL / 100 : radarTrack.CorrectedAltitude / 100; - int cfl; - bool isCfl = Int32.TryParse(flightDataRecord.CFLString, out cfl); - bool isEastBound = true; - - if (flightDataRecord is null) - return null; - - switch (itemType) - { - case STRIP_ITEM_CALLSIGN: - - eastboundCallsigns.TryGetValue(flightDataRecord.Callsign, out isEastBound); - - if (isEastBound) - { - return new CustomStripItem() - { - BackColourIdentity = Colours.Identities.StripText, - ForeColourIdentity = Colours.Identities.StripBackground, - Text = flightDataRecord.Callsign - }; - } - else - { - return new CustomStripItem() - { - BackColourIdentity = Colours.Identities.StripBackground, - ForeColourIdentity = Colours.Identities.StripText, - Text = flightDataRecord.Callsign - }; - } - case LABEL_ITEM_ADSB_CPDLC: - - - if (isEastBound & !adsb & cpdlc) - - return new CustomStripItem() - { - BackColourIdentity = Colours.Identities.StripText, - ForeColourIdentity = Colours.Identities.StripBackground, - Text = "⧆" - }; - - else if (!adsb & cpdlc) - - return new CustomStripItem() - { - Text = "⧆" - }; - - - else if (!adsb) - - return new CustomStripItem() - { - Text = "⎕" - }; - - else if (cpdlc) - - return new CustomStripItem() - { - Text = "*" - }; - - return null; - - case STRIP_ITEM_DIST_FLAG: - string stripText = ""; - - if (MachNumberTech(flightDataRecord.PerformanceData)) - { - stripText += "MR"; - } - - if (adsc & cpdlc & rnp4 || rnp10) - { - stripText += rnp4 ? "3" : "D"; - } - - return new CustomStripItem() - { - Text = stripText - }; - - case STRIP_ITEM_RVSM_FLAG: - - if (rvsm) - - return new CustomStripItem() - { - BackColourIdentity = Colours.Identities.Custom, - CustomBackColour = SepFlags, - Text = "W" - }; - return null; - - //case STRIP_ITEM_MAN_EST: - - //if (Estimates) - // return new CustomStripItem() - // { - // BackColourIdentity = Colours.Identities.HighlightedText - // }; - //return null; - - default: return null; - } - } } } \ No newline at end of file diff --git a/AuroraLabelItemsPlugin.csproj b/AuroraLabelItemsPlugin.csproj index 2a68913..a4fcae4 100644 --- a/AuroraLabelItemsPlugin.csproj +++ b/AuroraLabelItemsPlugin.csproj @@ -43,12 +43,13 @@ - ..\..\..\..\..\Program Files (x86)\vatSys\bin\vatSys.exe + E:\vatsys\bin\vatSys.exe False + diff --git a/AuroraStripItemPlugin.cs b/AuroraStripItemPlugin.cs new file mode 100644 index 0000000..577ca0e --- /dev/null +++ b/AuroraStripItemPlugin.cs @@ -0,0 +1,276 @@ +using System; +using System.Collections.Generic; +using System.Text.RegularExpressions; +using vatsys; +using vatsys.Plugin; +using System.Collections.Concurrent; +using System.ComponentModel.Composition; //<--Need to add a reference to System.ComponentModel.Composition +using static vatsys.Performance; +using static vatsys.Network; + +namespace AuroraStripItemsPlugin +{ + [Export(typeof(IPlugin))] + + public class AuroraStripItemsPlugin : IStripPlugin + { + + /// The name of the custom label item we've added to Labels + /// in the Profile + const string LABEL_ITEM_ADSB_CPDLC = "AURORA_ADSB_CPDLC"; //field c(4) + const string STRIP_ITEM_CALLSIGN = "AURORA_CALLSIGN"; + const string STRIP_ITEM_T10_FLAG = "AURORA_T10_FLAG"; + const string STRIP_ITEM_MNT_FLAG = "AURORA_MNT_FLAG"; + const string STRIP_ITEM_DIST_FLAG = "AURORA_DIST_FLAG"; + const string STRIP_ITEM_RVSM_FLAG = "AURORA_RVSM_FLAG"; + const string STRIP_ITEM_VMI = "AURORA_STRIP_VMI"; + const string STRIP_ITEM_MAN_EST = "AURORA_MAN_EST"; + const string STRIP_ITEM_LATERAL_FLAG = "AURORA_LATERAL_FLAG"; + const string STRIP_ITEM_ANNOT_IND = "AURORA_ANNOT_STRIP"; + readonly static CustomColour EastboundColour = new CustomColour(240, 255, 255); + readonly static CustomColour WestboundColour = new CustomColour(240, 231, 140); + readonly static CustomColour NonRVSM = new CustomColour(242, 133, 0); + readonly static CustomColour SepFlags = new CustomColour(0, 196, 253); + readonly static CustomColour Probe = new CustomColour(0, 255, 0); + readonly static CustomColour NotCDA = new CustomColour(100, 0, 100); + readonly ConcurrentDictionary eastboundCallsigns = new ConcurrentDictionary(); + /// Plugin Name + public string Name { get => "Aurora Label Items"; } + + public void OnFDRUpdate(FDP2.FDR updated) + { + if (FDP2.GetFDRIndex(updated.Callsign) == -1) //FDR was removed (that's what triggered the update) + eastboundCallsigns.TryRemove(updated.Callsign, out _); + + else + + { + + if (updated.ParsedRoute.Count > 1) + { + //calculate track from first route point to last (Departure point to destination point) + var rte = updated.ParsedRoute; + double trk = Conversions.CalculateTrack(rte.First().Intersection.LatLong, rte.Last().Intersection.LatLong); + bool east = trk >= 0 && trk < 180; + eastboundCallsigns.AddOrUpdate(updated.Callsign, east, (c, e) => east); + } + } + } + + //internal void SendContactMe(NetworkPilot pilot, VSCSFrequency freq) + //{ + // if (validATC && HaveConnection && !((DateTime.UtcNow - pilot.LastContactMe).TotalMinutes < 1.0)) + // { + // string text = "Please contact me on " + Conversions.FrequencyToString(freq.Frequency); + // if (freq.AliasFrequency != VSCSFrequency.None.Frequency) + // { + // text = text + " (" + Conversions.FrequencyToString(freq.AliasFrequency) + ")"; + // } + // + // SendTextMessage(pilot.Callsign, text); + // pilot.LastContactMe = DateTime.UtcNow; + // } + //} + + /// This is called each time a radar track is updated + public void OnRadarTrackUpdate(RDP.RadarTrack updated) + { + + } + + public static bool MachNumberTech(PerformanceData mnt) + { + if (mnt == null) return false; + return mnt.IsJet; + } + + //public void Estimates(FDP2.FDR.ExtractedRoute.Segment estimate) + //{ + // estimate.IsPETO = true; + //} + public CustomStripItem GetCustomStripItem(string itemType, Track track, FDP2.FDR flightDataRecord, RDP.RadarTrack radarTrack) + + { + Match pbn = Regex.Match(flightDataRecord.Remarks, @"PBN\/\w+\s"); + bool cpdlc = Regex.IsMatch(flightDataRecord.AircraftEquip, @"J5") || Regex.IsMatch(flightDataRecord.AircraftEquip, @"J7"); + bool adsc = Regex.IsMatch(flightDataRecord.AircraftSurvEquip, @"D1"); + bool adsb = flightDataRecord.ADSB; //Regex.IsMatch(flightDataRecord.AircraftSurvEquip, @"B\d"); + bool rnp10 = Regex.IsMatch(pbn.Value, @"A1"); + bool rnp4 = Regex.IsMatch(pbn.Value, @"L1"); + bool rvsm = flightDataRecord.RVSM; + int level = radarTrack == null ? flightDataRecord.PRL / 100 : radarTrack.CorrectedAltitude / 100; + int cfl; + bool isCfl = Int32.TryParse(flightDataRecord.CFLString, out cfl); + bool isEastBound = true; + + if (flightDataRecord is null) + return null; + + switch (itemType) + { + case STRIP_ITEM_CALLSIGN: + + eastboundCallsigns.TryGetValue(flightDataRecord.Callsign, out isEastBound); + + if (isEastBound) + { + return new CustomStripItem() + { + BackColourIdentity = Colours.Identities.StripText, + ForeColourIdentity = Colours.Identities.StripBackground, + Text = flightDataRecord.Callsign + }; + } + else + { + return new CustomStripItem() + { + BackColourIdentity = Colours.Identities.StripBackground, + ForeColourIdentity = Colours.Identities.StripText, + Text = flightDataRecord.Callsign + }; + } + case LABEL_ITEM_ADSB_CPDLC: + + + if (isEastBound & !adsb & cpdlc) + + return new CustomStripItem() + { + BackColourIdentity = Colours.Identities.StripText, + ForeColourIdentity = Colours.Identities.StripBackground, + Text = "⧆" + }; + + else if (!adsb & cpdlc) + + return new CustomStripItem() + { + Text = "⧆" + }; + + + else if (!adsb) + + return new CustomStripItem() + { + Text = "⎕" + }; + + else if (cpdlc) + + return new CustomStripItem() + { + Text = "*" + }; + + return null; + + case STRIP_ITEM_T10_FLAG: + + if (MachNumberTech(flightDataRecord.PerformanceData)) + + return new CustomStripItem() + { + //BackColourIdentity = Colours.Identities.Custom, + Text = "M" + }; + + return null; + + case STRIP_ITEM_MNT_FLAG: + + if (MachNumberTech(flightDataRecord.PerformanceData)) + + return new CustomStripItem() + { + //BackColourIdentity = Colours.Identities.Custom, + Text = "R" + }; + + return null; + + case STRIP_ITEM_DIST_FLAG: + + if (adsc & cpdlc & rnp4 || rnp10) + + + return new CustomStripItem() + { + //BackColourIdentity = Colours.Identities.Custom, + Text = rnp4 ? "3" : "D" + }; + return null; + + case STRIP_ITEM_RVSM_FLAG: + + if (rvsm) + + return new CustomStripItem() + { + BackColourIdentity = Colours.Identities.Custom, + CustomBackColour = SepFlags, + Text = "W" + }; + + return null; + + case STRIP_ITEM_VMI: + var vs = radarTrack == null ? flightDataRecord.PredictedPosition.VerticalSpeed : radarTrack.VerticalSpeed; + + if (level == cfl || level == flightDataRecord.RFL)//level + + return new CustomStripItem() + { + Text = "" + }; + else if (cfl > level && track.NewCFL || vs > 300)//Issued or trending climb + + return new CustomStripItem() + { + Text = "↑", + }; + + else if (cfl > 0 && cfl < level && track.NewCFL || vs < -300)//Issued or trending descent + + return new CustomStripItem() + { + Text = "↓", + }; + + return null; + + //case STRIP_ITEM_MAN_EST: + + //if (Estimates) + // return new CustomStripItem() + // { + // BackColourIdentity = Colours.Identities.HighlightedText + // }; + //return null; + + case STRIP_ITEM_ANNOT_IND: + + return new CustomStripItem() + { + Text = "." //& + }; + + + case STRIP_ITEM_LATERAL_FLAG: + + if (adsc & cpdlc & rnp4 || rnp10) + + + return new CustomStripItem() + { + //BackColourIdentity = Colours.Identities.Custom, + Text = rnp4 ? "4" : "R" + }; + return null; + + default: return null; + } + } + } +} diff --git a/bin/Release/AuroraLabelItemsPlugin.dll b/bin/Release/AuroraLabelItemsPlugin.dll index 65015bb8f6e7d27d018f060adad481aaf0058cbd..d97d583dd83b2e296a7173c9477a24e0ae74c5f8 100644 GIT binary patch literal 10752 zcmeHNeRLdGb-y#SvtPE>*6Pc49D8j?j;xQ3EZL46C&8=Tm8^Irt+lcsiD5n39m|V% zch)nzwuP!3`9Pe|q_l3JB%I?O0!bTFph*gcq-}ZvAt?vQfs|5CO4BB!0ZvH@p`4yT zi__nIGrQWA6F9W}uN`^r+^=`vefQmW-vaTBc-xNQ5)3`dRV;~>E2OQEB; zvnu~vemW$xaHU~)l98iCKjc8Hyq1VogZJ=$qM?gJbvKyEd2-QK_3+`c?WAOn_=ujAkN#R}i3WuuWcQ!6|(Th-xf0}j4)Z2u)! zkJP>hv#$DXJqyh7Tympxw{->D8yf+(ce}g4rz~6vR53OIx@^Zc15NjCv_g1xnpb0d zi(3SGkkPF`yIZ@_JCFJ22pmG+toF&R-Kqhn{ALPjU6?b!YIHK4V|qKVzM#V~s+=CF z16t_9Z&s?j?W%!E@vrJMb})aT#<%ISHCi>`g@3!!g>buD)MhpG5Pi|uy&uRQe(N*w z-B$v+_o~(__Pq>e9p=7!fe*#uH5jKaeB=1OM{FTC4d;e>Y>E5g-#@jx11guEj9B3= zAj}C{L#u50!%s!Nx$l0vW#@M<{d;)B(CY|;V&1{taR9Fq9sPq~atLkahq?E^7R-w^ z=FgbjjkeOou&eRql zvFFp%eo1ntdz&4>$z?%bl~<|p+^&TljBwp0Dc$F@@ePAcy4;3Tb}jZo+-c4)x2RcO z=CyV^oh{bXRHF|K&9h*Le5tj%ucp%49dPxo4!DdkG&g5&?eVF`H8#3hHBdwSL8WUa z9^1XDF<=XBUO!MB#D$unI`QUT_E+Wi*W|Fv%`eHWg+V;ieL-}(3)nVH4AGP3{ykSa z19-67sMF5KKBcusy=_f35ZzT%uD3Jwd3ZWSBw$SX9I26_W(C=O2?sebR1X1^G0fw#JTU{NC5$Lj0HA|t# zv5HhK0RJoH3Lz8q3s&u{UA?k!HLWOIEv}9hRTNCc{35sFdeOIA5vA6y6K6Rr=1W!K zbuS89k{#vi-T*!HZvb`-R1qXp*Zr`xy;<$uYDIx{ZeF_>6VEk^aemr*izC3h9gQ`P z#@fp@npH36GL5>h<*m(`qD}~FtSJhJ=(k>g0%G$-0TIe>ENq)6%7Nguc6;3EW>?yG z6g!U)HoN*f=4K4JM>Tu!u-$IOyl${YF@pD<$HR_0&gWU&Q5V8Pu0wt({|^i$^D4$y8hc|o^_zRcWT)--X{0+a1J zTG)$Ro3rhkvv#8(NVo!DWI|Qsb6d0Adv)mP3meb++gJ6p${r&DU));g9*Lw|{GN_? zt@6mmICujuySq0zquC^jJ-mB3b<;5PV97rFoZ1!c4-fVa?!=nptj+`WdWg2&MszQp z5BPwm%4V)OXR*fh@NWn^z_!CFDkE_4pSF!29z&YY2SDesu(l27jagR41y$*tn?K?6 z0ij<=gM`Bg_l`9$j%GMm5Sr0C+zM{^EzV@sdqp0`J|VD@WXJdR4$@1uVFjvqQjP0e?&I4=H~F3)cwvu;6@DdD-Qr$K^Lv zKW%fjxdZfW*8^z#BQJA$!12?NfM+~y;G??x{B&4;!Rx0#RT*AGFL+PTLvYfd&%td! z-7mf1JxvQJAAb6_$``=Hr>>uzM%%`7TBqw3SLk1Ro*qocmB%YM3BP~VphdcGsCrY9WgD5xfS(rI_Q z=bz*Nz2>yrsJ7!xWcha6msixE$w7MhYNpQ79-kWvje_%eK$*^i zqX>?R&HAdumi}54UgXEI}%0;xj4tf1Ny(sOV*GZE{flo^ee+kX|rDxvHTd|I{Gufjr0}35WNm~6$P!-9-qv4nWIpdc)vH5#-BEDS zqnm$p&gTCe@_nV=18BLDXV+F2Rsyc;Z_K3Av7A-PYxB{(W?2IR>3+I?vN#f(I$X+X zW&Ot4G&p0$^56iC#F7IPHHw*vY3jvtESD+gjG|`FA041b&a_HeMu%3Vm^nH~*N+?7 zN?yN_u1}h|Q?N8vDCPA6+G*S>rkAx`-nx+{jB+#J;Kl!y$+6X~((_;@-M zjnJUQj?W>VuAU~!6{ zb$vx6i9~8_bfUhW=;Zi#dMr9QK^8(WW+mg(lQb1e(x_g>Y}Bhx#bK-7-gsmp4IU+R z^O#{4v|>h&X=P3LHHu@AmY*yMM#0J$W5A zt>o&cm_A#Xo73RivIZK@@MHYzesFjIP7|+1z1N0Ntc;rfe`2kGN))XSp~=jl5AY z>76JT^|T%25yM2<3I%(zBdM5}-Ug;!N9*}^YexxF7RzykL^P`H?4*t5w7H^zN|mvy zVW{S@h^0|V>E@|iM!!tV;o%}yliS4#Y0u%aNFa7jptM?o>yM z4vde9vS?9hwkXyX`qE1yc@1yocHnG$Mb<5+Z~PR@Mog&lQpKu7sk2D0#n(wY_+%7M z*)^>;oN4_05}wlMux?D06B8Q-f@E8Y9!JebBaXh!L49WpLIPve^8hXpO&|sgV$b&K^;IVL*SCd|-UyGK~m$6Oc>` zoeB6r>lc)js1@FE3}Ql){S$p7 ziuLgs6|p)jWGO@_E^Lyru}4y#*&!((*(NFY0;YVwQ|gGo#}HzaZMaD}137+DQ2Izx z&To;FdvGHTo_@Sf;G4c@Sm@K{#-5|_D}lchJR3#-E9EJ8lEmmnpc8=xUD?=v9NY=W z?by+(5Pai5#J7eIB5it3U)Xc|snp~he_N0qy5s)u;@hAkd6f`JDv;)8CIbv)rh^f$ z$0Y~X22VCYCEy~-8*sM;-z^7ZZ%CF~Xl;w+3Q_PRq+S)s(tR#>aOon0&-h4g!UO-j zZNa6_D*+icWohHOmXOjSwNQ&B*o?GDvRhV3mIDFV9q@YGvh4LX`8*^Cm!1v;U|n{( zo0pzd+`*gOthSb2ZW29yTXr|W;XnZG1Ay$s?f7y4$ZcM5d8A+gg9#R7#UshWxQvU1 zuh@f8+#y9$Rn_H@eO}m7yxuRo@5s#hT`ztx)EMT=6MSoo?>AhBenivnKB`Tc(re`K7N+uvzwCA_fJ4iVGGP2;pBK~Lsd zOjk(M{x%05vOf!VNEED{hC^Sv7zz#a51@eVkm#!2dv{*jKdWW>b`I>#^zG7Shx&$w zc4hmH?H(G`ckSudv^`k5t0nU6#0PTx;j^Yh8^aUv>Dt>suXBXG0Uyz?4G+NUKx<9t zyvp-?QY*I#)g&RIeN>`b8_suO=X}>2vUkniP}O{YcvpC6=gwW>!Ckut_x6UOl{~*~ z-B8pkIHl%$LrJ`rXUc8}L!SRz^k_Z#PZ$I(k^Ne%cPUHUJe%xDu)Lr}? zzy6v^#Zn*t(w!GiKX-BeL(hKs;9mrP`bjnzz3#|i3ul8Px#7xu(m1V~M=Wgn8U2W< zmkjI3ThGYA5o7kfNANy_!-oDgI^j}wmhOlwJ8?hbp=G)ryQfYM|0xA8wy}JET+0ggNAe6t>D)K zn!#R_28?4*($0nXPGt{-2rze;freA!R@;wdf{puIjE1|Bio60B-Cw~XM6 zX&xt)F)GqAoMiaAN_^9r7N?pb&L4SbmZ4`r$G#qRy$Yied@4gL2mah!So(_4vG-ht zyKp)}3}^#dN+`bu&PN6GU4#{!a>TW@PF6y{MViN$HKFII!1E4hRXvZvf`zXp>_@4= z&-&BZ^4VZrW10|imV|u+BduV*%5{&|Nr%WE&~4r D0qYKR delta 2543 zcmZ`*ZA_cj6@Ko$@B8`#aNxBerVua~5@S9DX|*H`i{fAcrX~zN&#uCS+%uM)GgC~ELHzhtENWErlEFU|JGINcJ4LJ znjgDxpL5Q0&OP_M=ib+LVXW}jcP;?WJmK(gKPXnc750hi3Y~XG3Fx%!Hs~{>s)0WS%pldH_ zDxXjOjMclICXF_LU;dFbR(GiVY4p?NFfr8#d|USX7MTGs{htW^0H^*Ai?ETVZdffuHK6s4&~PFDx?KfcelC^0(U}6M0}v z>^x6#9;2<)W2EcIT|YI^>N3;yMb&L1Gp&LH$irP?ooyh#%afTU&Jm(=-6gH1nUnvs zvO(gS9ZO9l!j#rUX`4xJEiuzuNiI?y?$TnE%`*!scZjIs0$-Sl@pcOAAt`_gvDiY+ zEgkd-c~O-nx7%&02P!tg(v7fLx|JMln;dP{Sz2X;&r-*YurKWPg$H=HP32d8fA=n+%492v^vs@s`3o&T8Yb#=AP`$Lu}@ zJ)_ao{Ku?ASO~Ed;l_L79pS+W@28k~Q!yV9Hx!VqFYsU9fW9vq4(t!okA#@DkxvoWaqeIF>hV!9&e^m(Yoi=;oGC0UhvS zoUjHt!XTCiTXBW(QH{Gb_GtbITqAx|GZPvou|~{s+#}55Z>$H4=;o6+hpRk*^SD8W zL8pg$*3a@v71)j`7=_|nO`eUhPA5ti{lU0{UvB6IR_Z@`wrEV~oBwcJzcvMJq(}Fj z$wVSLlbt`2JkxU`na%Djm3rzBqH&#*w}cq7lVT_ z#3TE9#=~ON;JQBx9bQpc9-2Ui@?Dy5W`ZDQ-xvA`YN-|uSRaGY+aqGe2dBE&7E>`bA`OUxm5;&RkGRdm&1Oaob?B_ zz3M+MQ`PPAht-eEe^e)({e!X5Tr!uEzkj4bcGT3$;hL>qDsHndmqR?6%^{^=|4fE( zEOk1!QC@6rDs>v^`9$x@h2)8u+!^_4O~_vz!8k_fOMC;l+n88XsMkl69M|-1ao?xF#^ov z;g*vuk5W98tIVWag{#~uGacMca>J@9TsH%ZR4X8uX`0TpZyY&P{n&>W{r~4N(e$vR zkNO~I0`_)c+2f9lhu{{ctdv&cY)QbdPkQVHJ892awA;A7pgwX|hZ<6BGyZkziu!!g zS1v>H0(Ib1j EzkD63wg3PC diff --git a/bin/Release/AuroraLabelItemsPlugin.pdb b/bin/Release/AuroraLabelItemsPlugin.pdb index c4db67b410929ba63472a94f1020acfba05e6f0e..3ab2de7b2bd28121d179a21051c7ab9899224cdf 100644 GIT binary patch literal 26112 zcmeHP3vg7|c|I#E3gF5h41|Y`SAYNuX|=nOki^S+f~gV6NccgN!tUxyT3GEWcXyF+ z+{{i42~C=o@wj!}sWWsOH~3MH-OzDu<0)=viXAd_;-tk>(or)WH|}(TlW7_}C2qg( zJa(^ED~cCkW3$Kn`<=&s&VSB-{`0v1y>e$bWXIyM{)D@&rft%TzqitYwvvZxcBi_x2#w{ zw&(8W`_}F}`&V@>-}}xjov-}3pzNz#18;m<_0Qnd-P=O%rb+|6=kFBj%4Pz!2_RN1 zPKkNqP_S*OyV_mn@q4`0`1Ski{T_eas=9_yU&yyQ;P(ZC!Nx#cAkfzzT)ldA(ChPA zes6t~tQ^90pc6un`ur64*?nN0sXtqV?IOXNkgRzzaNzb7X8%gI^z(Y zHBpX|+)=(EDgm(`t$=|uz7oW?H>{og>>%PSr**K*0+~R|Fubpo|Kk{WX*uL&nUj~6 zWq4PfYkrZuPOEeBn)VBLaSiY}@4rBF&{LNT)PEsd8yevJuMw4H9IbKEJ9pAv~hE_|@C~9dw(2vIk7ks_q4?#5i69y zH7oAfWJN7I91=?$li-fuS4Dm&?xd7K&-z+xXXwjx!)iv+Pasm+t9dcS0ok+MB-kw=`KUHaXfay zlKH%AIO`_ty%lxmKm><^19Hr+lG~5>nA&+J3zq2gR7Y~x3HZdP(+5%X|m4*5vG9S&1%O8j{oxd%ZH88AoRgU&efL)jT6av{_!3W>Y z7@ld{u)_D|H7`ciSuM+)d2Aj>ZOL`Wm$Ib6b>rbNlxU5O<|S)`UfT!cE-pj`h3J5@ zv}BQyrNp#!w@abeO7Y+iKF-@1c)C!Zbqzn~hRtAp(st0_XUjRr$5vZ)KQHKh(k4v6 zK2_2@zMq@ySTfo-zN>lZ$E?Y3>PwGv-e*8=tC5Q}*&epl5vH|6-EhK&L9AzZ%^HEp zq;&(g15P4kqxtB^*vu?_0W$X>wu$Gil91_VXCO4VH8~Wt>>evLn3qn>ePA?)EZpNt z_8M6o@kDqCyA;-5K4UVvf0hRk!VA*qRlF2(;zka1ulA>Icw~mT0;OHvkN(|{x~yk- zjqXu3t^4f#$ytW|iCb5CAId6|dl%c}KIAO3qr*O2e`P)HMOkHa$in@{U55N|W#M=S zETNUwoA+Ar=(REj2Fjq9jEvuaWEJdDs0Lkh`9hI!Ut(=PmHbVdD`eYYCV8Wo~RK9?LuK6%LdB#?pK zJ0N2McO{X6j(Mj^Edl=g-217e!1YM`bei{_W~4U&TY!DQR^UNk8}JF>MqnwPyvoET zq-d80xUiVIXZBCXkv7#8!}63&duZ+5$`h zyMgqx20r()&XMhhQ{V%{rkp55LH;^tu-;SW~ zi-C_LT@L&f%KgBnk*)*2fOH4&6{PP5eh2A6;3=f{0KW%30Q^4iLE!7aBfuYm?>XQ< zBYgt+Cel9u{wvbI0**oMO&IvwNH+t2hV%gNS4dMKzXpB@_#5Ou3H+2x9C!(MgG;1- z44ml_5BwT97wJ+_37y|8O2t;tS3uiAHJ~-1CK-o{Feje@tq=>uBJ4NIG>(i*bKVr+ zT^gC*2V%NK^KR0(M`J|eeZUG`kFvg?F zRZXl1?<~Y`1F|p8KVAb&i%;?Qs=iT?cZR3s56GmsEe&o z+#%b@=#=%;S)9AxHeIhv)?1dIi(U*;otLiknY##Wflr1W@N+CXfZQMM0&j#GQ$Bz^@d(m?2z(rfxcCc~jba4;bC2a+51N}CrbAtaZ1^z}*7ibW40Q6^|6Clp< zjDQY+z6m-G8UyhRabtjupk7b{^bqK2&`Ho)5I30lpej&1=pN88=n$w7rcML=1E_`5 zYkt8wI|RKSMAL|hKSG@Ns7}A4@$YqhxlX?aCi49r=7rdy@lIX-InCdsaY*x%mvpb@ zr{jQWtYL{i(fsdeK9}ZuS(n#qtk(HWnh$%1tp9nP&wUD6;@@=sUz+}F?9};hYQCh- zU!d!|icv5jq|!MoM->y?CgMa#`8a0sxQd&dtP|o6`Kbwo$l%x}3*5t1{b`f2=<-R6 zFR=jar@-paRkNA9SU{Vo@QVlR0%oV&V&)dE!<_xp%b}!BM}Cv`*ex4 z<00c1b;wjax^8_&<}`Vy%yJYu>Zx*F4;L)c*MzK><@9sZQ{}o|L#D4|vR-Zno*Ad& z(RCYn2T=3DJz}z8&W6d#3;7>^4IC<=oh#ePrdp zcy!%B#@>(0x>*iOM?F=p>jg7=&Kw*!E|GCQ8aXOo^M^8hq@U2SmNQO7hb+aT>-Gt} zYgFsw7#=iTLOIfm9F?betqkvcIEq|CIm8UF%G134nK9h2d6oApqbrrK_@#sK3Y!?$ z_{emhi$_eESo{aG#k(VXe*GCT#z0kwH?vR&K3^}8@t>d2S@>F9#n={OCarR3i7||o zp-axUiksiupA>p>XA56jTdl9Qfd?>xk&|2QO!}Z?;92b$g3QY;U=q2WbsIvvcD0A` zbz)$DTLfRf`Th9#p`*6Gp`)c0r;Q31@6U93PcXdMSn1}g=y1fc`I(-(QZ%mKSnu~X z@LtPs@wRVBU%lpo7suteu&zB29f*XZ1MRU;atQCfZZQ_fY0me_XV2jH;9Ift?e!Tc0M~+zv%ge(IK{s34vwIe{w>J(*3i@H}#z? z%zF-mBWXfl**hTTdrQN_GWw*-O@;$mMqd+kksVk@-%>?(0n#j^KPX#&WMvusKjlnh z1(wl&gKcI)U>SWhlayZ zOJ#-&wx+C&e+xKGE5qawi>0;EXI2Eguu_qD4ZkFY5m3J0tzPC=y7`K|$mg>8HaW=- zgHMUgH`iL-QfKmq%2i>8oCFomlwX0^LmsvFvoA)tK|X`jYzasAa!V35J)LcMw`hr) zC_Vv-i<-C{su{EbeU=@>*Bg6PMnAT&cui=^zxtNaF0b*+{1ST#dT^01sJSNjUWxN? z1b2G|p2KFXVw(^%P>A=Uc$QN836E9o4~IZ}K3xT(Kb+z0o$!8NLYM=dmE;FE_u$7M z$hjBahxLC3`M45EzCoZNH{!=Z$7bVs7tc$)D;xo`&lMm>94*C#655^$PJ>Oy&O~sm#%^3 zm(E(?`~+&C@csWMa8f_Oka*S?{QvSjzdU;j{{IhPJZaWxa8x6~173$_jgDujoc9q& zxv84fLRNO}$H)mxnT%8>`v1h-7b)lcg!d2LW9WXMPvLe@4`??i0vZJ!038M$1swyO z0G$T$4)qr3UC;&4)#Cr>`Y-r@%%8Ged;TBZ!zT;oY?!RPkpJ=5K*9f)nL{2>1^-`u z{y(F|?TEYzntHEUzAavT9>uH8|M%6G$KIsvANjjOPmKKFiRPoGk7{VL8UO&JX9Kh^iK(Tq)my=yS7 zRIQYxOwPFtl7O&`jmq7px7M4}{$f)Z5~Qd`>ZyK`sv z+N>#AuOe*jvCcg+XU@FNyw02*H%7un+>Cc7N`hs<6)Q>_o9j!e{eggY%G^-10OSeb z0a*b&#W-NOB<^=2Xkf?CRdMCNF5IFTSc5ryi+0`ZHZ*Xheb%Ozt^sh|bc6Rz-mOc6l->gkv`TD_Wk34>CPKmt- zKGyU1wcnZj^TM|(j{mN&`PtXrZFyqx{DHd*8$NCd{P^vj_b0+uIT8DitMPC59d7y3 z;J@Z*mpre2_wn-Z?{}Vh;hhK0d}GG+u75_Jy4*JrbvF_El&kSSa=Q4Db?4su+L^#J zuQV*V@8bT?z0k34--Vx6)&1c&_cXrr=0wodMC`-VbLAe|0AhxXAUqiJEjkHb8P7zm zME5hUHQoRP#4X^a)j+24pY4wSO*>w>Zdk7DKiB@x^~iiW z<>hMpUHkvj8LwQ|a`p1n%k=NhgP&gn*S5Bpx?#5N*Lrlb)r|KWVZGJR`{HJ6UB3}G zv<9tRk8Vroz2?qne^(?n3fmtxg$S>0?H{c)%_=R*(jqLaPnMRM&C;@HTD*OKYm*+; zHB)c(Z{NJT-q3pWgK?v0>3oMoSz z|L2R{2y=dL?l4UURlqr=WS3svc$%`DUzBB;8?kEYiNMuzg8^wvA4=euhubnQ?R_>#C))(MD31PeW)YGf z0z&vje*P;P-hcULd;hxa%%Z})Up{y0^UT*MLZSjR9~p^vAPiEFhuz|1gcky3xt`R% z!8$$*Bw(E< zR5LaY^clKI3(b_}9nccyAydqxybSxL`6-5#;jAMVkA?dULyskdSnQ}L81L2!mXlEbtGM|#Au0H@j3jR^>pSR1H3q2ypaZc$vsvpp! z;4zKk;7l_cWTMi)Gp!33BI-C>J+HUtS2q_OV7(;P_crwVK{ST#5zV-NgcEhmAxqO( z61c>H%|0GQ|EiFmd6hid%4|qV^|7 zXdNiuGj0NH1Erh>8bZ7mv|fmZz5v>Q__shC5q}P}32`r8Jo?1lhza!L0B|j^M%*dN zEFNi*_zduiHl3f+zg%aY)OvO5e=o`|L<##qdB1K2odx#J}0}8JqtfJ6>eRYZSHlXYF{zj;lKd*cl+1;*CfzNhORHP!rxx z_vDWzDEW@^lbIwP>6wx(U8HX<*NXhV{MY8l#K8$eaP(!P#jxxXJ2but?~mLIxtDOC z;l8&OxEn}&Yyil;g7cXB1AbY} zJtD(pz>!zV*m`fhK)du#EBxV*&BALD8Dd!sskr1$7soI^374$3D8uTT`DaCc zX0|8~1}n=et9bwbR6UvNohA}e%sML^U9h;BD;T9-f9?8kTU#iCpDDFN!6<$ktA_8h zzN#j;DYPnRm3RHNcvD9+&#)0Dh^P%|v94$&))k6}`+MP=GM86WR9041ws(|jYgW~i zR+Vd&r8R+YptPo=Q!5XYcb024tJaI^`c0v_iV(I+QF_|{k?LcC)uQ1arjbt{(@0?2 z382dFOegOo@VJv{hndFv4ewbafoZ&BjO;7rn8rH=?*b!%X}m+I`-3x`X|xM*XSaZH z1$n5+YcV{S7jiT%AWpv;LGef@S);+b4{w!umW?oENeN+qX7M}h7=LTdqQ>j|@|#6z zqbvvf3=U9l1Z?%%ngXFRB@{Zs>2x=A(`(?{e!2H^Y}H^Yx);o{hDfZ3PYOiY?#7@N z?$$+F3_k&wqRceHW!<{gp&RY+JoiXOXC$hdW#L>t{je&^y4*3o$rxMZ*LhIEO^nVr zD*lJ?pb<#uAfgjUZE`$2$>Zid7s#vLLqIx=n3)$N!i8OxEb5a2t11Eh5t(TsHpA|8 znu@L1KhJ}|6xi*+5`@nH-#~lbg$(V44^ReuarBg_=H7+yJRrNnrh0+wHoHOJ7rVx; zOb5~y%l7TmkQzv^#iyx{x~!6z8rex1@2b0oqCgMP0D#&#+tB|Eoq3Z+^s!z?}L|vncGQawbC`uK!ofkcmg> z|GjeX@Y~!263f2#)fcDVw)Ok@N1iCS^y>!K|7&}>vvxj@5C1RU$>hraOMfDL#q|Hu yR$mNU0(AO+=ObPMq^}t6WgK-`OW+X@Il1{ zyy4kCzvp{r7BI#>JZL5C?|6E=6|GiA^_E{aAv?YRvogF=8q?VlwGnD4^MdC*<5@bZ zoU~43IiRx|WIDTdjTG%QZWd~VL)m2WzUWW;JnxDO<`7e}liz#P8)I=@Td+u~NiQUR zoxP1p&i;`8EC%mB&_A4&iK delta 82 zcmca_`qFfQ6QkMWKo-r7ITqafY0g$Lp~b01#W7il*{Q{o7l^BDzQe7-%BVB>BcC`+ WSz<}>W*)&tHhx*6Pc49D8j?j;xQ3EZL46C&8=Tm8^Irt+lcsiD5n39m|V% zch)nzwuP!3`9Pe|q_l3JB%I?O0!bTFph*gcq-}ZvAt?vQfs|5CO4BB!0ZvH@p`4yT zi__nIGrQWA6F9W}uN`^r+^=`vefQmW-vaTBc-xNQ5)3`dRV;~>E2OQEB; zvnu~vemW$xaHU~)l98iCKjc8Hyq1VogZJ=$qM?gJbvKyEd2-QK_3+`c?WAOn_=ujAkN#R}i3WuuWcQ!6|(Th-xf0}j4)Z2u)! zkJP>hv#$DXJqyh7Tympxw{->D8yf+(ce}g4rz~6vR53OIx@^Zc15NjCv_g1xnpb0d zi(3SGkkPF`yIZ@_JCFJ22pmG+toF&R-Kqhn{ALPjU6?b!YIHK4V|qKVzM#V~s+=CF z16t_9Z&s?j?W%!E@vrJMb})aT#<%ISHCi>`g@3!!g>buD)MhpG5Pi|uy&uRQe(N*w z-B$v+_o~(__Pq>e9p=7!fe*#uH5jKaeB=1OM{FTC4d;e>Y>E5g-#@jx11guEj9B3= zAj}C{L#u50!%s!Nx$l0vW#@M<{d;)B(CY|;V&1{taR9Fq9sPq~atLkahq?E^7R-w^ z=FgbjjkeOou&eRql zvFFp%eo1ntdz&4>$z?%bl~<|p+^&TljBwp0Dc$F@@ePAcy4;3Tb}jZo+-c4)x2RcO z=CyV^oh{bXRHF|K&9h*Le5tj%ucp%49dPxo4!DdkG&g5&?eVF`H8#3hHBdwSL8WUa z9^1XDF<=XBUO!MB#D$unI`QUT_E+Wi*W|Fv%`eHWg+V;ieL-}(3)nVH4AGP3{ykSa z19-67sMF5KKBcusy=_f35ZzT%uD3Jwd3ZWSBw$SX9I26_W(C=O2?sebR1X1^G0fw#JTU{NC5$Lj0HA|t# zv5HhK0RJoH3Lz8q3s&u{UA?k!HLWOIEv}9hRTNCc{35sFdeOIA5vA6y6K6Rr=1W!K zbuS89k{#vi-T*!HZvb`-R1qXp*Zr`xy;<$uYDIx{ZeF_>6VEk^aemr*izC3h9gQ`P z#@fp@npH36GL5>h<*m(`qD}~FtSJhJ=(k>g0%G$-0TIe>ENq)6%7Nguc6;3EW>?yG z6g!U)HoN*f=4K4JM>Tu!u-$IOyl${YF@pD<$HR_0&gWU&Q5V8Pu0wt({|^i$^D4$y8hc|o^_zRcWT)--X{0+a1J zTG)$Ro3rhkvv#8(NVo!DWI|Qsb6d0Adv)mP3meb++gJ6p${r&DU));g9*Lw|{GN_? zt@6mmICujuySq0zquC^jJ-mB3b<;5PV97rFoZ1!c4-fVa?!=nptj+`WdWg2&MszQp z5BPwm%4V)OXR*fh@NWn^z_!CFDkE_4pSF!29z&YY2SDesu(l27jagR41y$*tn?K?6 z0ij<=gM`Bg_l`9$j%GMm5Sr0C+zM{^EzV@sdqp0`J|VD@WXJdR4$@1uVFjvqQjP0e?&I4=H~F3)cwvu;6@DdD-Qr$K^Lv zKW%fjxdZfW*8^z#BQJA$!12?NfM+~y;G??x{B&4;!Rx0#RT*AGFL+PTLvYfd&%td! z-7mf1JxvQJAAb6_$``=Hr>>uzM%%`7TBqw3SLk1Ro*qocmB%YM3BP~VphdcGsCrY9WgD5xfS(rI_Q z=bz*Nz2>yrsJ7!xWcha6msixE$w7MhYNpQ79-kWvje_%eK$*^i zqX>?R&HAdumi}54UgXEI}%0;xj4tf1Ny(sOV*GZE{flo^ee+kX|rDxvHTd|I{Gufjr0}35WNm~6$P!-9-qv4nWIpdc)vH5#-BEDS zqnm$p&gTCe@_nV=18BLDXV+F2Rsyc;Z_K3Av7A-PYxB{(W?2IR>3+I?vN#f(I$X+X zW&Ot4G&p0$^56iC#F7IPHHw*vY3jvtESD+gjG|`FA041b&a_HeMu%3Vm^nH~*N+?7 zN?yN_u1}h|Q?N8vDCPA6+G*S>rkAx`-nx+{jB+#J;Kl!y$+6X~((_;@-M zjnJUQj?W>VuAU~!6{ zb$vx6i9~8_bfUhW=;Zi#dMr9QK^8(WW+mg(lQb1e(x_g>Y}Bhx#bK-7-gsmp4IU+R z^O#{4v|>h&X=P3LHHu@AmY*yMM#0J$W5A zt>o&cm_A#Xo73RivIZK@@MHYzesFjIP7|+1z1N0Ntc;rfe`2kGN))XSp~=jl5AY z>76JT^|T%25yM2<3I%(zBdM5}-Ug;!N9*}^YexxF7RzykL^P`H?4*t5w7H^zN|mvy zVW{S@h^0|V>E@|iM!!tV;o%}yliS4#Y0u%aNFa7jptM?o>yM z4vde9vS?9hwkXyX`qE1yc@1yocHnG$Mb<5+Z~PR@Mog&lQpKu7sk2D0#n(wY_+%7M z*)^>;oN4_05}wlMux?D06B8Q-f@E8Y9!JebBaXh!L49WpLIPve^8hXpO&|sgV$b&K^;IVL*SCd|-UyGK~m$6Oc>` zoeB6r>lc)js1@FE3}Ql){S$p7 ziuLgs6|p)jWGO@_E^Lyru}4y#*&!((*(NFY0;YVwQ|gGo#}HzaZMaD}137+DQ2Izx z&To;FdvGHTo_@Sf;G4c@Sm@K{#-5|_D}lchJR3#-E9EJ8lEmmnpc8=xUD?=v9NY=W z?by+(5Pai5#J7eIB5it3U)Xc|snp~he_N0qy5s)u;@hAkd6f`JDv;)8CIbv)rh^f$ z$0Y~X22VCYCEy~-8*sM;-z^7ZZ%CF~Xl;w+3Q_PRq+S)s(tR#>aOon0&-h4g!UO-j zZNa6_D*+icWohHOmXOjSwNQ&B*o?GDvRhV3mIDFV9q@YGvh4LX`8*^Cm!1v;U|n{( zo0pzd+`*gOthSb2ZW29yTXr|W;XnZG1Ay$s?f7y4$ZcM5d8A+gg9#R7#UshWxQvU1 zuh@f8+#y9$Rn_H@eO}m7yxuRo@5s#hT`ztx)EMT=6MSoo?>AhBenivnKB`Tc(re`K7N+uvzwCA_fJ4iVGGP2;pBK~Lsd zOjk(M{x%05vOf!VNEED{hC^Sv7zz#a51@eVkm#!2dv{*jKdWW>b`I>#^zG7Shx&$w zc4hmH?H(G`ckSudv^`k5t0nU6#0PTx;j^Yh8^aUv>Dt>suXBXG0Uyz?4G+NUKx<9t zyvp-?QY*I#)g&RIeN>`b8_suO=X}>2vUkniP}O{YcvpC6=gwW>!Ckut_x6UOl{~*~ z-B8pkIHl%$LrJ`rXUc8}L!SRz^k_Z#PZ$I(k^Ne%cPUHUJe%xDu)Lr}? zzy6v^#Zn*t(w!GiKX-BeL(hKs;9mrP`bjnzz3#|i3ul8Px#7xu(m1V~M=Wgn8U2W< zmkjI3ThGYA5o7kfNANy_!-oDgI^j}wmhOlwJ8?hbp=G)ryQfYM|0xA8wy}JET+0ggNAe6t>D)K zn!#R_28?4*($0nXPGt{-2rze;freA!R@;wdf{puIjE1|Bio60B-Cw~XM6 zX&xt)F)GqAoMiaAN_^9r7N?pb&L4SbmZ4`r$G#qRy$Yied@4gL2mah!So(_4vG-ht zyKp)}3}^#dN+`bu&PN6GU4#{!a>TW@PF6y{MViN$HKFII!1E4hRXvZvf`zXp>_@4= z&-&BZ^4VZrW10|imV|u+BduV*%5{&|Nr%WE&~4r D0qYKR delta 2543 zcmZ`*ZA_cj6@Ko$@B8`#aNxBerVua~5@S9DX|*H`i{fAcrX~zN&#uCS+%uM)GgC~ELHzhtENWErlEFU|JGINcJ4LJ znjgDxpL5Q0&OP_M=ib+LVXW}jcP;?WJmK(gKPXnc750hi3Y~XG3Fx%!Hs~{>s)0WS%pldH_ zDxXjOjMclICXF_LU;dFbR(GiVY4p?NFfr8#d|USX7MTGs{htW^0H^*Ai?ETVZdffuHK6s4&~PFDx?KfcelC^0(U}6M0}v z>^x6#9;2<)W2EcIT|YI^>N3;yMb&L1Gp&LH$irP?ooyh#%afTU&Jm(=-6gH1nUnvs zvO(gS9ZO9l!j#rUX`4xJEiuzuNiI?y?$TnE%`*!scZjIs0$-Sl@pcOAAt`_gvDiY+ zEgkd-c~O-nx7%&02P!tg(v7fLx|JMln;dP{Sz2X;&r-*YurKWPg$H=HP32d8fA=n+%492v^vs@s`3o&T8Yb#=AP`$Lu}@ zJ)_ao{Ku?ASO~Ed;l_L79pS+W@28k~Q!yV9Hx!VqFYsU9fW9vq4(t!okA#@DkxvoWaqeIF>hV!9&e^m(Yoi=;oGC0UhvS zoUjHt!XTCiTXBW(QH{Gb_GtbITqAx|GZPvou|~{s+#}55Z>$H4=;o6+hpRk*^SD8W zL8pg$*3a@v71)j`7=_|nO`eUhPA5ti{lU0{UvB6IR_Z@`wrEV~oBwcJzcvMJq(}Fj z$wVSLlbt`2JkxU`na%Djm3rzBqH&#*w}cq7lVT_ z#3TE9#=~ON;JQBx9bQpc9-2Ui@?Dy5W`ZDQ-xvA`YN-|uSRaGY+aqGe2dBE&7E>`bA`OUxm5;&RkGRdm&1Oaob?B_ zz3M+MQ`PPAht-eEe^e)({e!X5Tr!uEzkj4bcGT3$;hL>qDsHndmqR?6%^{^=|4fE( zEOk1!QC@6rDs>v^`9$x@h2)8u+!^_4O~_vz!8k_fOMC;l+n88XsMkl69M|-1ao?xF#^ov z;g*vuk5W98tIVWag{#~uGacMca>J@9TsH%ZR4X8uX`0TpZyY&P{n&>W{r~4N(e$vR zkNO~I0`_)c+2f9lhu{{ctdv&cY)QbdPkQVHJ892awA;A7pgwX|hZ<6BGyZkziu!!g zS1v>H0(Ib1j EzkD63wg3PC diff --git a/obj/Release/AuroraLabelItemsPlugin.pdb b/obj/Release/AuroraLabelItemsPlugin.pdb index c4db67b410929ba63472a94f1020acfba05e6f0e..3ab2de7b2bd28121d179a21051c7ab9899224cdf 100644 GIT binary patch literal 26112 zcmeHP3vg7|c|I#E3gF5h41|Y`SAYNuX|=nOki^S+f~gV6NccgN!tUxyT3GEWcXyF+ z+{{i42~C=o@wj!}sWWsOH~3MH-OzDu<0)=viXAd_;-tk>(or)WH|}(TlW7_}C2qg( zJa(^ED~cCkW3$Kn`<=&s&VSB-{`0v1y>e$bWXIyM{)D@&rft%TzqitYwvvZxcBi_x2#w{ zw&(8W`_}F}`&V@>-}}xjov-}3pzNz#18;m<_0Qnd-P=O%rb+|6=kFBj%4Pz!2_RN1 zPKkNqP_S*OyV_mn@q4`0`1Ski{T_eas=9_yU&yyQ;P(ZC!Nx#cAkfzzT)ldA(ChPA zes6t~tQ^90pc6un`ur64*?nN0sXtqV?IOXNkgRzzaNzb7X8%gI^z(Y zHBpX|+)=(EDgm(`t$=|uz7oW?H>{og>>%PSr**K*0+~R|Fubpo|Kk{WX*uL&nUj~6 zWq4PfYkrZuPOEeBn)VBLaSiY}@4rBF&{LNT)PEsd8yevJuMw4H9IbKEJ9pAv~hE_|@C~9dw(2vIk7ks_q4?#5i69y zH7oAfWJN7I91=?$li-fuS4Dm&?xd7K&-z+xXXwjx!)iv+Pasm+t9dcS0ok+MB-kw=`KUHaXfay zlKH%AIO`_ty%lxmKm><^19Hr+lG~5>nA&+J3zq2gR7Y~x3HZdP(+5%X|m4*5vG9S&1%O8j{oxd%ZH88AoRgU&efL)jT6av{_!3W>Y z7@ld{u)_D|H7`ciSuM+)d2Aj>ZOL`Wm$Ib6b>rbNlxU5O<|S)`UfT!cE-pj`h3J5@ zv}BQyrNp#!w@abeO7Y+iKF-@1c)C!Zbqzn~hRtAp(st0_XUjRr$5vZ)KQHKh(k4v6 zK2_2@zMq@ySTfo-zN>lZ$E?Y3>PwGv-e*8=tC5Q}*&epl5vH|6-EhK&L9AzZ%^HEp zq;&(g15P4kqxtB^*vu?_0W$X>wu$Gil91_VXCO4VH8~Wt>>evLn3qn>ePA?)EZpNt z_8M6o@kDqCyA;-5K4UVvf0hRk!VA*qRlF2(;zka1ulA>Icw~mT0;OHvkN(|{x~yk- zjqXu3t^4f#$ytW|iCb5CAId6|dl%c}KIAO3qr*O2e`P)HMOkHa$in@{U55N|W#M=S zETNUwoA+Ar=(REj2Fjq9jEvuaWEJdDs0Lkh`9hI!Ut(=PmHbVdD`eYYCV8Wo~RK9?LuK6%LdB#?pK zJ0N2McO{X6j(Mj^Edl=g-217e!1YM`bei{_W~4U&TY!DQR^UNk8}JF>MqnwPyvoET zq-d80xUiVIXZBCXkv7#8!}63&duZ+5$`h zyMgqx20r()&XMhhQ{V%{rkp55LH;^tu-;SW~ zi-C_LT@L&f%KgBnk*)*2fOH4&6{PP5eh2A6;3=f{0KW%30Q^4iLE!7aBfuYm?>XQ< zBYgt+Cel9u{wvbI0**oMO&IvwNH+t2hV%gNS4dMKzXpB@_#5Ou3H+2x9C!(MgG;1- z44ml_5BwT97wJ+_37y|8O2t;tS3uiAHJ~-1CK-o{Feje@tq=>uBJ4NIG>(i*bKVr+ zT^gC*2V%NK^KR0(M`J|eeZUG`kFvg?F zRZXl1?<~Y`1F|p8KVAb&i%;?Qs=iT?cZR3s56GmsEe&o z+#%b@=#=%;S)9AxHeIhv)?1dIi(U*;otLiknY##Wflr1W@N+CXfZQMM0&j#GQ$Bz^@d(m?2z(rfxcCc~jba4;bC2a+51N}CrbAtaZ1^z}*7ibW40Q6^|6Clp< zjDQY+z6m-G8UyhRabtjupk7b{^bqK2&`Ho)5I30lpej&1=pN88=n$w7rcML=1E_`5 zYkt8wI|RKSMAL|hKSG@Ns7}A4@$YqhxlX?aCi49r=7rdy@lIX-InCdsaY*x%mvpb@ zr{jQWtYL{i(fsdeK9}ZuS(n#qtk(HWnh$%1tp9nP&wUD6;@@=sUz+}F?9};hYQCh- zU!d!|icv5jq|!MoM->y?CgMa#`8a0sxQd&dtP|o6`Kbwo$l%x}3*5t1{b`f2=<-R6 zFR=jar@-paRkNA9SU{Vo@QVlR0%oV&V&)dE!<_xp%b}!BM}Cv`*ex4 z<00c1b;wjax^8_&<}`Vy%yJYu>Zx*F4;L)c*MzK><@9sZQ{}o|L#D4|vR-Zno*Ad& z(RCYn2T=3DJz}z8&W6d#3;7>^4IC<=oh#ePrdp zcy!%B#@>(0x>*iOM?F=p>jg7=&Kw*!E|GCQ8aXOo^M^8hq@U2SmNQO7hb+aT>-Gt} zYgFsw7#=iTLOIfm9F?betqkvcIEq|CIm8UF%G134nK9h2d6oApqbrrK_@#sK3Y!?$ z_{emhi$_eESo{aG#k(VXe*GCT#z0kwH?vR&K3^}8@t>d2S@>F9#n={OCarR3i7||o zp-axUiksiupA>p>XA56jTdl9Qfd?>xk&|2QO!}Z?;92b$g3QY;U=q2WbsIvvcD0A` zbz)$DTLfRf`Th9#p`*6Gp`)c0r;Q31@6U93PcXdMSn1}g=y1fc`I(-(QZ%mKSnu~X z@LtPs@wRVBU%lpo7suteu&zB29f*XZ1MRU;atQCfZZQ_fY0me_XV2jH;9Ift?e!Tc0M~+zv%ge(IK{s34vwIe{w>J(*3i@H}#z? z%zF-mBWXfl**hTTdrQN_GWw*-O@;$mMqd+kksVk@-%>?(0n#j^KPX#&WMvusKjlnh z1(wl&gKcI)U>SWhlayZ zOJ#-&wx+C&e+xKGE5qawi>0;EXI2Eguu_qD4ZkFY5m3J0tzPC=y7`K|$mg>8HaW=- zgHMUgH`iL-QfKmq%2i>8oCFomlwX0^LmsvFvoA)tK|X`jYzasAa!V35J)LcMw`hr) zC_Vv-i<-C{su{EbeU=@>*Bg6PMnAT&cui=^zxtNaF0b*+{1ST#dT^01sJSNjUWxN? z1b2G|p2KFXVw(^%P>A=Uc$QN836E9o4~IZ}K3xT(Kb+z0o$!8NLYM=dmE;FE_u$7M z$hjBahxLC3`M45EzCoZNH{!=Z$7bVs7tc$)D;xo`&lMm>94*C#655^$PJ>Oy&O~sm#%^3 zm(E(?`~+&C@csWMa8f_Oka*S?{QvSjzdU;j{{IhPJZaWxa8x6~173$_jgDujoc9q& zxv84fLRNO}$H)mxnT%8>`v1h-7b)lcg!d2LW9WXMPvLe@4`??i0vZJ!038M$1swyO z0G$T$4)qr3UC;&4)#Cr>`Y-r@%%8Ged;TBZ!zT;oY?!RPkpJ=5K*9f)nL{2>1^-`u z{y(F|?TEYzntHEUzAavT9>uH8|M%6G$KIsvANjjOPmKKFiRPoGk7{VL8UO&JX9Kh^iK(Tq)my=yS7 zRIQYxOwPFtl7O&`jmq7px7M4}{$f)Z5~Qd`>ZyK`sv z+N>#AuOe*jvCcg+XU@FNyw02*H%7un+>Cc7N`hs<6)Q>_o9j!e{eggY%G^-10OSeb z0a*b&#W-NOB<^=2Xkf?CRdMCNF5IFTSc5ryi+0`ZHZ*Xheb%Ozt^sh|bc6Rz-mOc6l->gkv`TD_Wk34>CPKmt- zKGyU1wcnZj^TM|(j{mN&`PtXrZFyqx{DHd*8$NCd{P^vj_b0+uIT8DitMPC59d7y3 z;J@Z*mpre2_wn-Z?{}Vh;hhK0d}GG+u75_Jy4*JrbvF_El&kSSa=Q4Db?4su+L^#J zuQV*V@8bT?z0k34--Vx6)&1c&_cXrr=0wodMC`-VbLAe|0AhxXAUqiJEjkHb8P7zm zME5hUHQoRP#4X^a)j+24pY4wSO*>w>Zdk7DKiB@x^~iiW z<>hMpUHkvj8LwQ|a`p1n%k=NhgP&gn*S5Bpx?#5N*Lrlb)r|KWVZGJR`{HJ6UB3}G zv<9tRk8Vroz2?qne^(?n3fmtxg$S>0?H{c)%_=R*(jqLaPnMRM&C;@HTD*OKYm*+; zHB)c(Z{NJT-q3pWgK?v0>3oMoSz z|L2R{2y=dL?l4UURlqr=WS3svc$%`DUzBB;8?kEYiNMuzg8^wvA4=euhubnQ?R_>#C))(MD31PeW)YGf z0z&vje*P;P-hcULd;hxa%%Z})Up{y0^UT*MLZSjR9~p^vAPiEFhuz|1gcky3xt`R% z!8$$*Bw(E< zR5LaY^clKI3(b_}9nccyAydqxybSxL`6-5#;jAMVkA?dULyskdSnQ}L81L2!mXlEbtGM|#Au0H@j3jR^>pSR1H3q2ypaZc$vsvpp! z;4zKk;7l_cWTMi)Gp!33BI-C>J+HUtS2q_OV7(;P_crwVK{ST#5zV-NgcEhmAxqO( z61c>H%|0GQ|EiFmd6hid%4|qV^|7 zXdNiuGj0NH1Erh>8bZ7mv|fmZz5v>Q__shC5q}P}32`r8Jo?1lhza!L0B|j^M%*dN zEFNi*_zduiHl3f+zg%aY)OvO5e=o`|L<##qdB1K2odx#J}0}8JqtfJ6>eRYZSHlXYF{zj;lKd*cl+1;*CfzNhORHP!rxx z_vDWzDEW@^lbIwP>6wx(U8HX<*NXhV{MY8l#K8$eaP(!P#jxxXJ2but?~mLIxtDOC z;l8&OxEn}&Yyil;g7cXB1AbY} zJtD(pz>!zV*m`fhK)du#EBxV*&BALD8Dd!sskr1$7soI^374$3D8uTT`DaCc zX0|8~1}n=et9bwbR6UvNohA}e%sML^U9h;BD;T9-f9?8kTU#iCpDDFN!6<$ktA_8h zzN#j;DYPnRm3RHNcvD9+&#)0Dh^P%|v94$&))k6}`+MP=GM86WR9041ws(|jYgW~i zR+Vd&r8R+YptPo=Q!5XYcb024tJaI^`c0v_iV(I+QF_|{k?LcC)uQ1arjbt{(@0?2 z382dFOegOo@VJv{hndFv4ewbafoZ&BjO;7rn8rH=?*b!%X}m+I`-3x`X|xM*XSaZH z1$n5+YcV{S7jiT%AWpv;LGef@S);+b4{w!umW?oENeN+qX7M}h7=LTdqQ>j|@|#6z zqbvvf3=U9l1Z?%%ngXFRB@{Zs>2x=A(`(?{e!2H^Y}H^Yx);o{hDfZ3PYOiY?#7@N z?$$+F3_k&wqRceHW!<{gp&RY+JoiXOXC$hdW#L>t{je&^y4*3o$rxMZ*LhIEO^nVr zD*lJ?pb<#uAfgjUZE`$2$>Zid7s#vLLqIx=n3)$N!i8OxEb5a2t11Eh5t(TsHpA|8 znu@L1KhJ}|6xi*+5`@nH-#~lbg$(V44^ReuarBg_=H7+yJRrNnrh0+wHoHOJ7rVx; zOb5~y%l7TmkQzv^#iyx{x~!6z8rex1@2b0oqCgMP0D#&#+tB|Eoq3Z+^s!z?}L|vncGQawbC`uK!ofkcmg> z|GjeX@Y~!263f2#)fcDVw)Ok@N1iCS^y>!K|7&}>vvxj@5C1RU$>hraOMfDL#q|Hu yR$mNU0(AO+=ObPMq^}t6W%BVBhP)wYq VEU_ebGoN518^1jkg~!EZm;sP18>j#P From 7328d470842c209d537aa12ed2b14a16754375fb Mon Sep 17 00:00:00 2001 From: Dominic Nguyen Date: Fri, 11 Nov 2022 11:19:10 -0800 Subject: [PATCH 09/76] Labels to dictionary --- AuroraLabelItemsPlugin.cs | 234 ++++++++++++++++++-------------------- AuroraStripItemPlugin.cs | 18 ++- 2 files changed, 124 insertions(+), 128 deletions(-) diff --git a/AuroraLabelItemsPlugin.cs b/AuroraLabelItemsPlugin.cs index 7c30cae..4396234 100644 --- a/AuroraLabelItemsPlugin.cs +++ b/AuroraLabelItemsPlugin.cs @@ -28,14 +28,17 @@ public class AuroraLabelItemsPlugin : ILabelPlugin const string LABEL_ITEM_VMI = "AURORA_VMI"; //field h(1) const string LABEL_ITEM_CLEARED_LEVEL = "AURORA_CLEARED_LEVEL"; //field i(7) const string LABEL_ITEM_RADAR_IND = "AURORA_RADAR_IND"; //field k(1) - const string LABEL_ITEM_3DIGIT_GROUNDSPEED = "AURORA_GROUNDSPEED"; + const string LABEL_ITEM_FIELD_SPEED = "AURORA_FILEDSPEED"; //field m(4) + const string LABEL_ITEM_3DIGIT_GROUNDSPEED = "AURORA_GROUNDSPEED"; //field n(5) readonly static CustomColour EastboundColour = new CustomColour(240, 255, 255); readonly static CustomColour WestboundColour = new CustomColour(240, 231, 140); readonly static CustomColour NonRVSM = new CustomColour(242, 133, 0); - readonly static CustomColour SepFlags = new CustomColour(0, 196, 253); readonly static CustomColour Probe = new CustomColour(0, 255, 0); readonly static CustomColour NotCDA = new CustomColour(100, 0, 100); readonly ConcurrentDictionary eastboundCallsigns = new ConcurrentDictionary(); + readonly ConcurrentDictionary adsbcpdlcValues = new ConcurrentDictionary(); + readonly ConcurrentDictionary rvsmValues = new ConcurrentDictionary(); + readonly ConcurrentDictionary altValues = new ConcurrentDictionary(); /// Plugin Name public string Name { get => "Aurora Label Items"; } @@ -48,10 +51,63 @@ public void OnFDRUpdate(FDP2.FDR updated) { if (FDP2.GetFDRIndex(updated.Callsign) == -1) //FDR was removed (that's what triggered the update) eastboundCallsigns.TryRemove(updated.Callsign, out _); + + if (FDP2.GetFDRIndex(updated.Callsign) == -1) + adsbcpdlcValues.TryRemove(updated.Callsign, out _); + + if (FDP2.GetFDRIndex(updated.Callsign) == -1) + altValues.TryRemove(updated.Callsign, out _); else { + bool cpdlc = Regex.IsMatch(updated.AircraftEquip, @"J5") || Regex.IsMatch(updated.AircraftEquip, @"J7"); + bool adsc = Regex.IsMatch(updated.AircraftSurvEquip, @"D1"); + int cfl; + bool isCfl = Int32.TryParse(updated.CFLString, out cfl); + var vs = updated.PredictedPosition.VerticalSpeed; + int level = updated.PRL / 100; + + + char c4 = '\0'; + + if (!updated.ADSB & cpdlc) + + c4 = '⧆'; + + else if (!updated.ADSB) + + c4 = '⎕'; + + else if (cpdlc) + + c4 = '*'; + + + adsbcpdlcValues.AddOrUpdate(updated.Callsign, c4, (k, v) => c4); + + char h1 = '\0'; + + if (level == updated.RFL)//level + h1 = '\0'; + + else if (cfl > level || vs > 300)//Issued or trending climb + h1 = '↑'; + + else if (cfl > 0 && cfl < level || vs < -300)//Issued or trending descent + h1 = '↓'; + + else if (level - updated.RFL / 100 >= 3)//deviating above + h1 = '+'; + + else if (level - updated.RFL / 100 <= -3)//deviating below + h1 = '-'; + + //Track.TrackTypes.TRACK_TYPE_FP + + altValues.AddOrUpdate(updated.Callsign, h1, (k, v) => h1); + + if (updated.ParsedRoute.Count > 1) { @@ -79,8 +135,9 @@ public void OnFDRUpdate(FDP2.FDR updated) // } //} - /// This is called each time a radar track is updated + /// Could use the new position of the radar track or its change in state (cancelled, etc.) to do some processing. public void OnRadarTrackUpdate(RDP.RadarTrack updated) + { } @@ -102,16 +159,12 @@ public CustomLabelItem GetCustomLabelItem(string itemType, Track track, FDP2.FDR if (track == null) return null; - Match pbn = Regex.Match(flightDataRecord.Remarks, @"PBN\/\w+\s"); - bool cpdlc = Regex.IsMatch(flightDataRecord.AircraftEquip, @"J5") || Regex.IsMatch(flightDataRecord.AircraftEquip, @"J7"); - bool adsc = Regex.IsMatch(flightDataRecord.AircraftSurvEquip, @"D1"); - bool adsb = flightDataRecord.ADSB; //Regex.IsMatch(flightDataRecord.AircraftSurvEquip, @"B\d"); - bool rnp10 = Regex.IsMatch(pbn.Value, @"A1"); - bool rnp4 = Regex.IsMatch(pbn.Value, @"L1"); - bool rvsm = flightDataRecord.RVSM; - int level = radarTrack == null ? flightDataRecord.PRL / 100 : radarTrack.CorrectedAltitude / 100; - int cfl; - bool isCfl = Int32.TryParse(flightDataRecord.CFLString, out cfl); + + + char c4; + adsbcpdlcValues.TryGetValue(flightDataRecord.Callsign, out c4); + char h1; + altValues.TryGetValue(flightDataRecord.Callsign, out h1); //string sLevel = level.ToString("D3"); //string ca = AlertTypes.STCA.ToString(@"CA"); //string la = AlertTypes.MSAW.ToString(@"LA"); @@ -134,39 +187,13 @@ public CustomLabelItem GetCustomLabelItem(string itemType, Track track, FDP2.FDR }; case LABEL_ITEM_ADSB_CPDLC: - - - if (!adsb & cpdlc) - - return new CustomLabelItem() - { - Text = "⧆" - }; - - else if (!adsb) - - return new CustomLabelItem() - { - Text = "⎕" - }; - - else if (cpdlc & track.State == MMI.HMIStates.Preactive | track.State is MMI.HMIStates.Announced) - - return new CustomLabelItem() - { - ForeColourIdentity = Colours.Identities.Custom, - CustomForeColour = NotCDA, - Text = "*" - }; - - else if (cpdlc) - - return new CustomLabelItem() - { - Text = "*" - }; - - return null; + + return new CustomLabelItem() + { + ForeColourIdentity = Colours.Identities.Custom, + CustomForeColour = track.State == MMI.HMIStates.Preactive | track.State is MMI.HMIStates.Announced ? NotCDA : default, + Text = c4.ToString() + }; //case LABEL_ITEM_SCC: @@ -185,79 +212,35 @@ public CustomLabelItem GetCustomLabelItem(string itemType, Track track, FDP2.FDR }; - case LABEL_ITEM_RESTR: - - if (Regex.IsMatch(flightDataRecord.GlobalOpData, @"AT \d\d\d\d")) - - return new CustomLabelItem() - { - Text = "x" - }; - - return null; - - case LABEL_ITEM_VMI: - var vs = radarTrack == null ? flightDataRecord.PredictedPosition.VerticalSpeed : radarTrack.VerticalSpeed; - - if (level == cfl || level == flightDataRecord.RFL)//level - - return new CustomLabelItem() - { - Text = "" - }; - - else if (cfl > level && track.NewCFL || vs > 300)//Issued or trending climb - - return new CustomLabelItem() - { - Text = "↑", - ForeColourIdentity = Colours.Identities.Custom, - CustomForeColour = !rvsm ? NonRVSM : track.NewCFL ? Probe : default - }; - - else if (cfl > 0 && cfl < level && track.NewCFL || vs < -300)//Issued or trending descent - - return new CustomLabelItem() - { - Text = "↓", - ForeColourIdentity = Colours.Identities.Custom, - CustomForeColour = !rvsm ? NonRVSM : track.NewCFL ? Probe : default - }; - - else if (level - flightDataRecord.RFL / 100 >= 3)//deviating above - - return new CustomLabelItem() - { - Text = "+" - }; - - else if (level - flightDataRecord.RFL / 100 <= -3)//deviating below - - return new CustomLabelItem() - { - Text = "-" - }; - - - //else if (Track.TrackTypes.TRACK_TYPE_FP)//Manually entered PRL - // - // return new CustomLabelItem() - // { - // Text = "R" - // }; - - return null; - - - - case LABEL_ITEM_CLEARED_LEVEL: + //case LABEL_ITEM_RESTR: + // + // if (Regex.IsMatch(flightDataRecord.GlobalOpData, @"AT \d\d\d\d")) + // + // return new CustomLabelItem() + // { + // Text = "x" + // }; + // + // return null; - return new CustomLabelItem() - { - Text = level == cfl ? "" : flightDataRecord.CFLString, - ForeColourIdentity = Colours.Identities.Custom, - CustomForeColour = !rvsm ? NonRVSM : Probe - }; + case LABEL_ITEM_VMI: + + + return new CustomLabelItem() + { + Text = h1.ToString(), + ForeColourIdentity = Colours.Identities.Custom, + CustomForeColour = !flightDataRecord.RVSM ? NonRVSM : track.NewCFL ? Probe : default + }; + + case LABEL_ITEM_CLEARED_LEVEL: + + return new CustomLabelItem() + { + Text = track.NewCFL && radarTrack.ReachedCFL ? "" : flightDataRecord.CFLString, + ForeColourIdentity = Colours.Identities.Custom, + CustomForeColour = !flightDataRecord.RVSM ? NonRVSM : Probe + }; case LABEL_ITEM_RADAR_IND: @@ -267,6 +250,11 @@ public CustomLabelItem GetCustomLabelItem(string itemType, Track track, FDP2.FDR //OnMouseClick = }; + case LABEL_ITEM_FIELD_SPEED: + return new CustomLabelItem() + { + Text = "N" + flightDataRecord.TAS + }; case LABEL_ITEM_3DIGIT_GROUNDSPEED: //get groundspeed value from either FDR or radarTrack if coupled @@ -280,12 +268,10 @@ public CustomLabelItem GetCustomLabelItem(string itemType, Track track, FDP2.FDR return null; } } - // private void ItemMouseClick(CustomLabelItemMouseClickEventArgs e) - // { - // e.Track.IQL = !e.Track.IQL; - // //MMI.ClickspotTypes.Label_Toggle; - // e.Handled = true; - // } + private void ItemMouseClick(CustomLabelItemMouseClickEventArgs e) + { + + } public CustomLabelItem TrackSelectBox(Track a, MMI.ClickspotCategories b) //box around selected tracks { //if (MMI.ClickspotTypes.Track_Select) diff --git a/AuroraStripItemPlugin.cs b/AuroraStripItemPlugin.cs index 577ca0e..b771ca5 100644 --- a/AuroraStripItemPlugin.cs +++ b/AuroraStripItemPlugin.cs @@ -88,6 +88,12 @@ public static bool MachNumberTech(PerformanceData mnt) //{ // estimate.IsPETO = true; //} + + private void ItemMouseClick(CustomLabelItemMouseClickEventArgs e) + { + e.Item.CustomForeColour = SepFlags; + e.Handled = true; + } public CustomStripItem GetCustomStripItem(string itemType, Track track, FDP2.FDR flightDataRecord, RDP.RadarTrack radarTrack) { @@ -173,7 +179,8 @@ public CustomStripItem GetCustomStripItem(string itemType, Track track, FDP2.FDR return new CustomStripItem() { //BackColourIdentity = Colours.Identities.Custom, - Text = "M" + Text = "M", + OnMouseClick = ItemMouseClick }; return null; @@ -185,7 +192,8 @@ public CustomStripItem GetCustomStripItem(string itemType, Track track, FDP2.FDR return new CustomStripItem() { //BackColourIdentity = Colours.Identities.Custom, - Text = "R" + Text = "R", + OnMouseClick = ItemMouseClick }; return null; @@ -198,7 +206,8 @@ public CustomStripItem GetCustomStripItem(string itemType, Track track, FDP2.FDR return new CustomStripItem() { //BackColourIdentity = Colours.Identities.Custom, - Text = rnp4 ? "3" : "D" + Text = rnp4 ? "3" : "D", + OnMouseClick = ItemMouseClick }; return null; @@ -265,7 +274,8 @@ public CustomStripItem GetCustomStripItem(string itemType, Track track, FDP2.FDR return new CustomStripItem() { //BackColourIdentity = Colours.Identities.Custom, - Text = rnp4 ? "4" : "R" + Text = rnp4 ? "4" : "R", + OnMouseClick = ItemMouseClick }; return null; From a6eb8e9a52019a2e496d6cbb50a2e746d1d5fbc6 Mon Sep 17 00:00:00 2001 From: Maxim Salikhov Date: Sat, 12 Nov 2022 14:13:30 -0500 Subject: [PATCH 10/76] Stop sending null (default) custom color --- AuroraLabelItemsPlugin.cs | 117 +++++++++++++++----------------------- 1 file changed, 46 insertions(+), 71 deletions(-) diff --git a/AuroraLabelItemsPlugin.cs b/AuroraLabelItemsPlugin.cs index 4396234..506192d 100644 --- a/AuroraLabelItemsPlugin.cs +++ b/AuroraLabelItemsPlugin.cs @@ -46,20 +46,14 @@ public class AuroraLabelItemsPlugin : ILabelPlugin /// Here we are updating the eastbound callsigns dictionary with each flight data record /// When the FDR is updated we check if it still exists in the Flight Data Processor and remove from our dictionary if not. Otherwise we do some simple regex matching to find /// the flight planned PBN category and store the character we want to display in the label in the dictionary. - public void OnFDRUpdate(FDP2.FDR updated) { - if (FDP2.GetFDRIndex(updated.Callsign) == -1) //FDR was removed (that's what triggered the update) - eastboundCallsigns.TryRemove(updated.Callsign, out _); - if (FDP2.GetFDRIndex(updated.Callsign) == -1) + { + eastboundCallsigns.TryRemove(updated.Callsign, out _); adsbcpdlcValues.TryRemove(updated.Callsign, out _); - - if (FDP2.GetFDRIndex(updated.Callsign) == -1) altValues.TryRemove(updated.Callsign, out _); - - else - + } else { bool cpdlc = Regex.IsMatch(updated.AircraftEquip, @"J5") || Regex.IsMatch(updated.AircraftEquip, @"J7"); bool adsc = Regex.IsMatch(updated.AircraftSurvEquip, @"D1"); @@ -69,9 +63,9 @@ public void OnFDRUpdate(FDP2.FDR updated) int level = updated.PRL / 100; - char c4 = '\0'; + char c4 = default; - if (!updated.ADSB & cpdlc) + if (!updated.ADSB && cpdlc) c4 = '⧆'; @@ -86,10 +80,10 @@ public void OnFDRUpdate(FDP2.FDR updated) adsbcpdlcValues.AddOrUpdate(updated.Callsign, c4, (k, v) => c4); - char h1 = '\0'; + char h1 = default; if (level == updated.RFL)//level - h1 = '\0'; + h1 = default; else if (cfl > level || vs > 300)//Issued or trending climb h1 = '↑'; @@ -120,24 +114,8 @@ public void OnFDRUpdate(FDP2.FDR updated) } } - //internal void SendContactMe(NetworkPilot pilot, VSCSFrequency freq) - //{ - // if (validATC && HaveConnection && !((DateTime.UtcNow - pilot.LastContactMe).TotalMinutes < 1.0)) - // { - // string text = "Please contact me on " + Conversions.FrequencyToString(freq.Frequency); - // if (freq.AliasFrequency != VSCSFrequency.None.Frequency) - // { - // text = text + " (" + Conversions.FrequencyToString(freq.AliasFrequency) + ")"; - // } - // - // SendTextMessage(pilot.Callsign, text); - // pilot.LastContactMe = DateTime.UtcNow; - // } - //} - /// Could use the new position of the radar track or its change in state (cancelled, etc.) to do some processing. public void OnRadarTrackUpdate(RDP.RadarTrack updated) - { } @@ -146,36 +124,16 @@ public void OnRadarTrackUpdate(RDP.RadarTrack updated) /// itemType is the value of the Type attribute in Labels.xml /// If it's not our item being called (another plugins, for example), return null. /// As a general rule, don't do processing in here as you'll slow down the ASD refresh. In the case of parsing a level to a string though, that's fine. - - //public static event EventHandler PrivateMessagesChanged; - - public CustomLabelItem GetCustomLabelItem(string itemType, Track track, FDP2.FDR flightDataRecord, RDP.RadarTrack radarTrack) { - if (flightDataRecord == null) + if (flightDataRecord == null || track == null) return null; - if (track == null) - return null; - - - char c4; adsbcpdlcValues.TryGetValue(flightDataRecord.Callsign, out c4); char h1; altValues.TryGetValue(flightDataRecord.Callsign, out h1); - //string sLevel = level.ToString("D3"); - //string ca = AlertTypes.STCA.ToString(@"CA"); - //string la = AlertTypes.MSAW.ToString(@"LA"); - //string ra = AlertTypes.DAIW.ToString(@"RA"); - //string rcf = AlertTypes.RAD.ToString(@"RCF"); - //string dup = AlertTypes.DAIW.ToString(@"DUP"); - //string pos = AlertTypes.MPR.ToString("POS"); - //string spd = AlertTypes.ETO.ToString(@"SPD"); - //var mti = transponder.TransponderCode = 7777; - - switch (itemType) { @@ -187,15 +145,25 @@ public CustomLabelItem GetCustomLabelItem(string itemType, Track track, FDP2.FDR }; case LABEL_ITEM_ADSB_CPDLC: - - return new CustomLabelItem() + + bool useCustomForeColour = track.State == MMI.HMIStates.Preactive || track.State == MMI.HMIStates.Announced; + + if (useCustomForeColour) { - ForeColourIdentity = Colours.Identities.Custom, - CustomForeColour = track.State == MMI.HMIStates.Preactive | track.State is MMI.HMIStates.Announced ? NotCDA : default, - Text = c4.ToString() - }; - - + return new CustomLabelItem() + { + ForeColourIdentity = Colours.Identities.Custom, + CustomForeColour = NotCDA, + Text = c4.ToString() + }; + } else + { + return new CustomLabelItem() + { + Text = c4.ToString() + }; + } + //case LABEL_ITEM_SCC: // // return new CustomLabelItem() @@ -224,20 +192,31 @@ public CustomLabelItem GetCustomLabelItem(string itemType, Track track, FDP2.FDR // return null; case LABEL_ITEM_VMI: - - - return new CustomLabelItem() - { - Text = h1.ToString(), - ForeColourIdentity = Colours.Identities.Custom, - CustomForeColour = !flightDataRecord.RVSM ? NonRVSM : track.NewCFL ? Probe : default - }; + bool isNonRVSMOrNewCFL = !flightDataRecord.RVSM || track.NewCFL; + if (isNonRVSMOrNewCFL) + { + return new CustomLabelItem() + { + Text = h1.ToString(), + ForeColourIdentity = Colours.Identities.Custom, + CustomForeColour = !flightDataRecord.RVSM ? NonRVSM : Probe + }; + } + else + { + return new CustomLabelItem() + { + Text = h1.ToString() + }; + } + + case LABEL_ITEM_CLEARED_LEVEL: return new CustomLabelItem() { - Text = track.NewCFL && radarTrack.ReachedCFL ? "" : flightDataRecord.CFLString, + Text = (track.NewCFL && radarTrack.ReachedCFL) ? string.Empty : flightDataRecord.CFLString, ForeColourIdentity = Colours.Identities.Custom, CustomForeColour = !flightDataRecord.RVSM ? NonRVSM : Probe }; @@ -247,7 +226,6 @@ public CustomLabelItem GetCustomLabelItem(string itemType, Track track, FDP2.FDR return new CustomLabelItem() { Text = "◦"//★ - //OnMouseClick = }; case LABEL_ITEM_FIELD_SPEED: @@ -268,10 +246,7 @@ public CustomLabelItem GetCustomLabelItem(string itemType, Track track, FDP2.FDR return null; } } - private void ItemMouseClick(CustomLabelItemMouseClickEventArgs e) - { - } public CustomLabelItem TrackSelectBox(Track a, MMI.ClickspotCategories b) //box around selected tracks { //if (MMI.ClickspotTypes.Track_Select) From fda6f466d76caa4044e1d88429618b147328acd1 Mon Sep 17 00:00:00 2001 From: Maxim Salikhov Date: Sat, 12 Nov 2022 14:15:15 -0500 Subject: [PATCH 11/76] Format code --- AuroraLabelItemsPlugin.cs | 107 ++++++++++++++++++------------------- AuroraStripItemPlugin.cs | 6 +-- Properties/AssemblyInfo.cs | 1 - 3 files changed, 55 insertions(+), 59 deletions(-) diff --git a/AuroraLabelItemsPlugin.cs b/AuroraLabelItemsPlugin.cs index 506192d..7ef70c2 100644 --- a/AuroraLabelItemsPlugin.cs +++ b/AuroraLabelItemsPlugin.cs @@ -1,12 +1,9 @@ using System; -using System.Collections.Generic; +using System.Collections.Concurrent; +using System.ComponentModel.Composition; //<--Need to add a reference to System.ComponentModel.Composition using System.Text.RegularExpressions; using vatsys; using vatsys.Plugin; -using System.Collections.Concurrent; -using System.ComponentModel.Composition; //<--Need to add a reference to System.ComponentModel.Composition -using static vatsys.Performance; -using static vatsys.Network; //Note the reference to vatsys (set Copy Local to false) -----> @@ -53,7 +50,8 @@ public void OnFDRUpdate(FDP2.FDR updated) eastboundCallsigns.TryRemove(updated.Callsign, out _); adsbcpdlcValues.TryRemove(updated.Callsign, out _); altValues.TryRemove(updated.Callsign, out _); - } else + } + else { bool cpdlc = Regex.IsMatch(updated.AircraftEquip, @"J5") || Regex.IsMatch(updated.AircraftEquip, @"J7"); bool adsc = Regex.IsMatch(updated.AircraftSurvEquip, @"D1"); @@ -138,12 +136,12 @@ public CustomLabelItem GetCustomLabelItem(string itemType, Track track, FDP2.FDR switch (itemType) { case LABEL_ITEM_COMM_ICON: - + return new CustomLabelItem() { Text = "⬜" //⬜▼⟏ }; - + case LABEL_ITEM_ADSB_CPDLC: bool useCustomForeColour = track.State == MMI.HMIStates.Preactive || track.State == MMI.HMIStates.Announced; @@ -156,7 +154,8 @@ public CustomLabelItem GetCustomLabelItem(string itemType, Track track, FDP2.FDR CustomForeColour = NotCDA, Text = c4.ToString() }; - } else + } + else { return new CustomLabelItem() { @@ -164,34 +163,34 @@ public CustomLabelItem GetCustomLabelItem(string itemType, Track track, FDP2.FDR }; } - //case LABEL_ITEM_SCC: - // - // return new CustomLabelItem() - // { - // Text = pos //| ca | la | ra | rcf | dup | spd - // }; - - - case LABEL_ITEM_ANNOT_IND: - - return new CustomLabelItem() - { - Text = "◦" //& - }; - - - //case LABEL_ITEM_RESTR: - // - // if (Regex.IsMatch(flightDataRecord.GlobalOpData, @"AT \d\d\d\d")) - // - // return new CustomLabelItem() - // { - // Text = "x" - // }; - // - // return null; - - case LABEL_ITEM_VMI: + //case LABEL_ITEM_SCC: + // + // return new CustomLabelItem() + // { + // Text = pos //| ca | la | ra | rcf | dup | spd + // }; + + + case LABEL_ITEM_ANNOT_IND: + + return new CustomLabelItem() + { + Text = "◦" //& + }; + + + //case LABEL_ITEM_RESTR: + // + // if (Regex.IsMatch(flightDataRecord.GlobalOpData, @"AT \d\d\d\d")) + // + // return new CustomLabelItem() + // { + // Text = "x" + // }; + // + // return null; + + case LABEL_ITEM_VMI: bool isNonRVSMOrNewCFL = !flightDataRecord.RVSM || track.NewCFL; if (isNonRVSMOrNewCFL) @@ -210,23 +209,23 @@ public CustomLabelItem GetCustomLabelItem(string itemType, Track track, FDP2.FDR Text = h1.ToString() }; } - - - case LABEL_ITEM_CLEARED_LEVEL: - - return new CustomLabelItem() - { - Text = (track.NewCFL && radarTrack.ReachedCFL) ? string.Empty : flightDataRecord.CFLString, - ForeColourIdentity = Colours.Identities.Custom, - CustomForeColour = !flightDataRecord.RVSM ? NonRVSM : Probe - }; - - case LABEL_ITEM_RADAR_IND: - - return new CustomLabelItem() - { - Text = "◦"//★ - }; + + + case LABEL_ITEM_CLEARED_LEVEL: + + return new CustomLabelItem() + { + Text = (track.NewCFL && radarTrack.ReachedCFL) ? string.Empty : flightDataRecord.CFLString, + ForeColourIdentity = Colours.Identities.Custom, + CustomForeColour = !flightDataRecord.RVSM ? NonRVSM : Probe + }; + + case LABEL_ITEM_RADAR_IND: + + return new CustomLabelItem() + { + Text = "◦"//★ + }; case LABEL_ITEM_FIELD_SPEED: return new CustomLabelItem() diff --git a/AuroraStripItemPlugin.cs b/AuroraStripItemPlugin.cs index b771ca5..45cb3e1 100644 --- a/AuroraStripItemPlugin.cs +++ b/AuroraStripItemPlugin.cs @@ -1,12 +1,10 @@ using System; -using System.Collections.Generic; +using System.Collections.Concurrent; +using System.ComponentModel.Composition; //<--Need to add a reference to System.ComponentModel.Composition using System.Text.RegularExpressions; using vatsys; using vatsys.Plugin; -using System.Collections.Concurrent; -using System.ComponentModel.Composition; //<--Need to add a reference to System.ComponentModel.Composition using static vatsys.Performance; -using static vatsys.Network; namespace AuroraStripItemsPlugin { diff --git a/Properties/AssemblyInfo.cs b/Properties/AssemblyInfo.cs index cad189d..b2c5e45 100644 --- a/Properties/AssemblyInfo.cs +++ b/Properties/AssemblyInfo.cs @@ -1,5 +1,4 @@ using System.Reflection; -using System.Runtime.CompilerServices; using System.Runtime.InteropServices; // General Information about an assembly is controlled through the following From ea7237105e9a5b8662f7523900fc395f12079233 Mon Sep 17 00:00:00 2001 From: Dominic Nguyen Date: Sat, 17 Dec 2022 21:59:41 -0800 Subject: [PATCH 12/76] Update AuroraLabelItemsPlugin.cs --- AuroraLabelItemsPlugin.cs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/AuroraLabelItemsPlugin.cs b/AuroraLabelItemsPlugin.cs index 7ef70c2..838288d 100644 --- a/AuroraLabelItemsPlugin.cs +++ b/AuroraLabelItemsPlugin.cs @@ -5,7 +5,6 @@ using vatsys; using vatsys.Plugin; - //Note the reference to vatsys (set Copy Local to false) -----> namespace AuroraLabelItemsPlugin @@ -25,7 +24,7 @@ public class AuroraLabelItemsPlugin : ILabelPlugin const string LABEL_ITEM_VMI = "AURORA_VMI"; //field h(1) const string LABEL_ITEM_CLEARED_LEVEL = "AURORA_CLEARED_LEVEL"; //field i(7) const string LABEL_ITEM_RADAR_IND = "AURORA_RADAR_IND"; //field k(1) - const string LABEL_ITEM_FIELD_SPEED = "AURORA_FILEDSPEED"; //field m(4) + const string LABEL_ITEM_FILED_SPEED = "AURORA_FILEDSPEED"; //field m(4) const string LABEL_ITEM_3DIGIT_GROUNDSPEED = "AURORA_GROUNDSPEED"; //field n(5) readonly static CustomColour EastboundColour = new CustomColour(240, 255, 255); readonly static CustomColour WestboundColour = new CustomColour(240, 231, 140); @@ -112,6 +111,7 @@ public void OnFDRUpdate(FDP2.FDR updated) } } + /// Could use the new position of the radar track or its change in state (cancelled, etc.) to do some processing. public void OnRadarTrackUpdate(RDP.RadarTrack updated) { @@ -227,7 +227,7 @@ public CustomLabelItem GetCustomLabelItem(string itemType, Track track, FDP2.FDR Text = "◦"//★ }; - case LABEL_ITEM_FIELD_SPEED: + case LABEL_ITEM_FILED_SPEED: return new CustomLabelItem() { Text = "N" + flightDataRecord.TAS From 12877864db5b6cfce2c64372f79048795d7013a4 Mon Sep 17 00:00:00 2001 From: Dominic Nguyen Date: Sun, 18 Dec 2022 19:16:56 -0800 Subject: [PATCH 13/76] downlink --- AuroraLabelItemsPlugin.cs | 305 ++++++++++++++++++++++++++++++++------ AuroraStripItemPlugin.cs | 90 +++++++---- 2 files changed, 326 insertions(+), 69 deletions(-) diff --git a/AuroraLabelItemsPlugin.cs b/AuroraLabelItemsPlugin.cs index 838288d..efc1e6e 100644 --- a/AuroraLabelItemsPlugin.cs +++ b/AuroraLabelItemsPlugin.cs @@ -5,6 +5,7 @@ using vatsys; using vatsys.Plugin; + //Note the reference to vatsys (set Copy Local to false) -----> namespace AuroraLabelItemsPlugin @@ -16,8 +17,12 @@ public class AuroraLabelItemsPlugin : ILabelPlugin /// The name of the custom label item we've added to Labels /// in the Profile + const string LABEL_ITEM_SELECT_HORI = "SELECT_HORI"; + const string LABEL_ITEM_SELECT_VERT = "SELECT_VERT"; const string LABEL_ITEM_COMM_ICON = "AURORA_COMM_ICON"; //field a(2) const string LABEL_ITEM_ADSB_CPDLC = "AURORA_ADSB_CPDLC"; //field c(4) + const string LABEL_ITEM_ADS_FLAGS = "AURORA_ADS_FLAGS"; //field c(4) + const string LABEL_ITEM_MNT_FLAGS = "AURORA_MNT_FLAGS"; //field c(4) const string LABEL_ITEM_SCC = "AURORA_SCC"; //field c(5) const string LABEL_ITEM_ANNOT_IND = "AURORA_ANNOT_IND"; //field e(1) const string LABEL_ITEM_RESTR = "AURORA_RESTR"; //field f(1) @@ -33,8 +38,56 @@ public class AuroraLabelItemsPlugin : ILabelPlugin readonly static CustomColour NotCDA = new CustomColour(100, 0, 100); readonly ConcurrentDictionary eastboundCallsigns = new ConcurrentDictionary(); readonly ConcurrentDictionary adsbcpdlcValues = new ConcurrentDictionary(); - readonly ConcurrentDictionary rvsmValues = new ConcurrentDictionary(); + readonly ConcurrentDictionary adsflagValues = new ConcurrentDictionary(); + readonly ConcurrentDictionary mntflagValues = new ConcurrentDictionary(); readonly ConcurrentDictionary altValues = new ConcurrentDictionary(); + readonly ConcurrentDictionary radartoggle = new ConcurrentDictionary(); + readonly ConcurrentDictionary adsflagtoggle = new ConcurrentDictionary(); + readonly ConcurrentDictionary mntflagtoggle = new ConcurrentDictionary(); + readonly ConcurrentDictionary downlink = new ConcurrentDictionary(); + readonly ConcurrentDictionary trackselect = new ConcurrentDictionary(); + + public AuroraLabelItemsPlugin() + { + Network.PrivateMessagesChanged += Network_PrivateMessagesChanged; + Network.RadioMessageAcknowledged += Network_RadioMessageAcknowledged; + //MMI.SelectedTrackChanged += MMI_SelectedTrackChanged; + } + + //private void MMI_SelectedTrackChanged(object sender, EventArgs e) + //{ + // var callsign = MMI.SelectedTrack?.GetFDR()?.Callsign; + // if (callsign != null) + // { + // trackselect.TryRemove(callsign, out _); + // + // } + // else + // { + // trackselect.TryAdd(callsign, 0); + // } + //} + + private void Network_RadioMessageAcknowledged(object sender, RadioMessageEventArgs e) + { + throw new NotImplementedException(); + } + + private void Network_PrivateMessagesChanged(object sender, Network.GenericMessageEventArgs e) + { + bool downLink = e.Message.Sent == true; + + if (downLink) + { + downlink.TryRemove(e.Message.Address, out _); + } + else + { + downlink.TryAdd(e.Message.Address, 0); + } + + } + /// Plugin Name public string Name { get => "Aurora Label Items"; } @@ -48,10 +101,20 @@ public void OnFDRUpdate(FDP2.FDR updated) { eastboundCallsigns.TryRemove(updated.Callsign, out _); adsbcpdlcValues.TryRemove(updated.Callsign, out _); + adsflagValues.TryRemove(updated.Callsign, out _); + mntflagValues.TryRemove(updated.Callsign, out _); altValues.TryRemove(updated.Callsign, out _); + radartoggle.TryRemove(updated.Callsign, out _); + adsflagtoggle.TryRemove(updated.Callsign, out _); + mntflagtoggle.TryRemove(updated.Callsign, out _); + downlink.TryRemove(updated.Callsign, out _); + trackselect.TryRemove(updated.Callsign, out _); } else { + Match pbn = Regex.Match(updated.Remarks, @"PBN\/\w+\s"); + bool rnp10 = Regex.IsMatch(pbn.Value, @"A1"); + bool rnp4 = Regex.IsMatch(pbn.Value, @"L1"); bool cpdlc = Regex.IsMatch(updated.AircraftEquip, @"J5") || Regex.IsMatch(updated.AircraftEquip, @"J7"); bool adsc = Regex.IsMatch(updated.AircraftSurvEquip, @"D1"); int cfl; @@ -59,27 +122,44 @@ public void OnFDRUpdate(FDP2.FDR updated) var vs = updated.PredictedPosition.VerticalSpeed; int level = updated.PRL / 100; - - char c4 = default; + char c1 = default; if (!updated.ADSB && cpdlc) - c4 = '⧆'; + c1 = '⧆'; else if (!updated.ADSB) - c4 = '⎕'; + c1 = '⎕'; else if (cpdlc) - c4 = '*'; + c1 = '*'; - adsbcpdlcValues.AddOrUpdate(updated.Callsign, c4, (k, v) => c4); + adsbcpdlcValues.AddOrUpdate(updated.Callsign, c1, (k, v) => c1); + + char c2 = default; + + if (adsc & cpdlc & rnp4) + c2 = '3'; + + else if (adsc & cpdlc & rnp10) + c2 = 'D'; + + adsflagValues.AddOrUpdate(updated.Callsign, c2, (k, v) => c2); + + char c3 = default; + + if (AuroraStripItemsPlugin.AuroraStripItemsPlugin.MachNumberTech(updated.PerformanceData)) + c3 = 'M'; + + mntflagValues.AddOrUpdate(updated.Callsign, c3, (k, v) => c3); + char h1 = default; - if (level == updated.RFL)//level + if (level == cfl || level == updated.RFL)//level h1 = default; else if (cfl > level || vs > 300)//Issued or trending climb @@ -94,7 +174,6 @@ public void OnFDRUpdate(FDP2.FDR updated) else if (level - updated.RFL / 100 <= -3)//deviating below h1 = '-'; - //Track.TrackTypes.TRACK_TYPE_FP altValues.AddOrUpdate(updated.Callsign, h1, (k, v) => h1); @@ -118,6 +197,50 @@ public void OnRadarTrackUpdate(RDP.RadarTrack updated) } + + private void HandleRadarFlagClick(CustomLabelItemMouseClickEventArgs e) + { + bool radarToggled = radartoggle.TryGetValue(e.Track.GetFDR().Callsign, out _); + + if (radarToggled) + { + radartoggle.TryRemove(e.Track.GetFDR().Callsign, out _); + } + else + { + radartoggle.TryAdd(e.Track.GetFDR().Callsign, 0); + } + e.Handled = true; + } + private void HandleADSFlagClick(CustomLabelItemMouseClickEventArgs e) + { + bool adsflagToggled = radartoggle.TryGetValue(e.Track.GetFDR().Callsign, out _); + + if (adsflagToggled) + { + adsflagtoggle.TryRemove(e.Track.GetFDR().Callsign, out _); + } + else + { + adsflagtoggle.TryAdd(e.Track.GetFDR().Callsign, 0); + } + e.Handled = true; + } + + private void HandleMNTFlagClick(CustomLabelItemMouseClickEventArgs e) + { + bool mntflagToggled = radartoggle.TryGetValue(e.Track.GetFDR().Callsign, out _); + + if (mntflagToggled) + { + mntflagtoggle.TryRemove(e.Track.GetFDR().Callsign, out _); + } + else + { + mntflagtoggle.TryAdd(e.Track.GetFDR().Callsign, 0); + } + e.Handled = true; + } /// vatSys calls this function when it encounters a custom label item (defined in Labels.xml) during the label rendering. /// itemType is the value of the Type attribute in Labels.xml /// If it's not our item being called (another plugins, for example), return null. @@ -128,20 +251,65 @@ public CustomLabelItem GetCustomLabelItem(string itemType, Track track, FDP2.FDR if (flightDataRecord == null || track == null) return null; - char c4; - adsbcpdlcValues.TryGetValue(flightDataRecord.Callsign, out c4); + char c1; + adsbcpdlcValues.TryGetValue(flightDataRecord.Callsign, out c1); + char c2; + adsflagValues.TryGetValue(flightDataRecord.Callsign, out c2); + char c3; + mntflagValues.TryGetValue(flightDataRecord.Callsign, out c3); char h1; altValues.TryGetValue(flightDataRecord.Callsign, out h1); + bool radarToggled = radartoggle.TryGetValue(flightDataRecord.Callsign, out _); + bool adsflagToggled = adsflagtoggle.TryGetValue(flightDataRecord.Callsign, out _); + bool mntflagToggled = mntflagtoggle.TryGetValue(flightDataRecord.Callsign, out _); + bool downLink = downlink.TryGetValue(flightDataRecord.Callsign, out _); + bool trackSelect = trackselect.TryGetValue(flightDataRecord.Callsign, out _); + + switch (itemType) { - case LABEL_ITEM_COMM_ICON: + case LABEL_ITEM_SELECT_HORI: - return new CustomLabelItem() + if (trackSelect) { - Text = "⬜" //⬜▼⟏ - }; + return new CustomLabelItem() + { + Border = BorderFlags.Horizontal + }; + } + + else return null; + + case LABEL_ITEM_SELECT_VERT: + + if (trackSelect) + { + return new CustomLabelItem() + { + Border = BorderFlags.Vertical + }; + } + else return null; + + case LABEL_ITEM_COMM_ICON: + + if (downLink) + { + return new CustomLabelItem() + { + Text = "▼", + Border = BorderFlags.All + }; + } + else + { + return new CustomLabelItem() + { + Text = "⬜" + }; + } case LABEL_ITEM_ADSB_CPDLC: bool useCustomForeColour = track.State == MMI.HMIStates.Preactive || track.State == MMI.HMIStates.Announced; @@ -152,17 +320,54 @@ public CustomLabelItem GetCustomLabelItem(string itemType, Track track, FDP2.FDR { ForeColourIdentity = Colours.Identities.Custom, CustomForeColour = NotCDA, - Text = c4.ToString() + Text = c1.ToString() }; } else { return new CustomLabelItem() { - Text = c4.ToString() + Text = c1.ToString() }; } + case LABEL_ITEM_ADS_FLAGS: + + if (adsflagToggled) + { + return new CustomLabelItem() + { + Text = c2.ToString(), + OnMouseClick = HandleADSFlagClick, + }; + } + + else + return new CustomLabelItem() + { + Text = "", + OnMouseClick = HandleADSFlagClick, + }; + + case LABEL_ITEM_MNT_FLAGS: + + if (mntflagToggled) + { + return new CustomLabelItem() + { + Text = c3.ToString(), + OnMouseClick = HandleMNTFlagClick, + }; + } + + else + return new CustomLabelItem() + { + Text = "", + OnMouseClick = HandleMNTFlagClick, + }; + + //case LABEL_ITEM_SCC: // // return new CustomLabelItem() @@ -172,23 +377,34 @@ public CustomLabelItem GetCustomLabelItem(string itemType, Track track, FDP2.FDR case LABEL_ITEM_ANNOT_IND: + bool scratch = String.IsNullOrEmpty(flightDataRecord.LabelOpData); - return new CustomLabelItem() + if (scratch) { - Text = "◦" //& - }; + return new CustomLabelItem() + { + Text = "◦" + }; + } + else + { + return new CustomLabelItem() + { + Text = "&" + }; + } - //case LABEL_ITEM_RESTR: - // - // if (Regex.IsMatch(flightDataRecord.GlobalOpData, @"AT \d\d\d\d")) - // - // return new CustomLabelItem() - // { - // Text = "x" - // }; - // - // return null; + case LABEL_ITEM_RESTR: + + if (flightDataRecord.LabelOpData.Contains ("AT") || flightDataRecord.LabelOpData.Contains("BY") || flightDataRecord.LabelOpData.Contains("CLEARED TO")) + + return new CustomLabelItem() + { + Text = "x" + }; + + return null; case LABEL_ITEM_VMI: bool isNonRVSMOrNewCFL = !flightDataRecord.RVSM || track.NewCFL; @@ -222,10 +438,24 @@ public CustomLabelItem GetCustomLabelItem(string itemType, Track track, FDP2.FDR case LABEL_ITEM_RADAR_IND: - return new CustomLabelItem() + + if (radarToggled) { - Text = "◦"//★ - }; + return new CustomLabelItem() + { + Text = "★", + OnMouseClick = HandleRadarFlagClick, + }; + } + + else + { + return new CustomLabelItem() + { + Text = "◦", + OnMouseClick = HandleRadarFlagClick, + }; + } case LABEL_ITEM_FILED_SPEED: return new CustomLabelItem() @@ -246,15 +476,6 @@ public CustomLabelItem GetCustomLabelItem(string itemType, Track track, FDP2.FDR } } - public CustomLabelItem TrackSelectBox(Track a, MMI.ClickspotCategories b) //box around selected tracks - { - //if (MMI.ClickspotTypes.Track_Select) - return new CustomLabelItem() - { - Border = MMI.SelectedTrack != null ? BorderFlags.All : BorderFlags.None, - }; - } - public CustomColour SelectASDTrackColour(Track track) { //only apply East/West colour to jurisdiction state diff --git a/AuroraStripItemPlugin.cs b/AuroraStripItemPlugin.cs index 45cb3e1..a3887bc 100644 --- a/AuroraStripItemPlugin.cs +++ b/AuroraStripItemPlugin.cs @@ -1,10 +1,12 @@ using System; -using System.Collections.Concurrent; -using System.ComponentModel.Composition; //<--Need to add a reference to System.ComponentModel.Composition +using System.Collections.Generic; using System.Text.RegularExpressions; using vatsys; using vatsys.Plugin; +using System.Collections.Concurrent; +using System.ComponentModel.Composition; //<--Need to add a reference to System.ComponentModel.Composition using static vatsys.Performance; +using static vatsys.Network; namespace AuroraStripItemsPlugin { @@ -17,6 +19,8 @@ public class AuroraStripItemsPlugin : IStripPlugin /// in the Profile const string LABEL_ITEM_ADSB_CPDLC = "AURORA_ADSB_CPDLC"; //field c(4) const string STRIP_ITEM_CALLSIGN = "AURORA_CALLSIGN"; + const string STRIP_ITEM_CTLSECTOR = "AURORA_CDA"; + const string STRIP_ITEM_NXTSECTOR = "AURORA_NDA"; const string STRIP_ITEM_T10_FLAG = "AURORA_T10_FLAG"; const string STRIP_ITEM_MNT_FLAG = "AURORA_MNT_FLAG"; const string STRIP_ITEM_DIST_FLAG = "AURORA_DIST_FLAG"; @@ -25,20 +29,22 @@ public class AuroraStripItemsPlugin : IStripPlugin const string STRIP_ITEM_MAN_EST = "AURORA_MAN_EST"; const string STRIP_ITEM_LATERAL_FLAG = "AURORA_LATERAL_FLAG"; const string STRIP_ITEM_ANNOT_IND = "AURORA_ANNOT_STRIP"; - readonly static CustomColour EastboundColour = new CustomColour(240, 255, 255); - readonly static CustomColour WestboundColour = new CustomColour(240, 231, 140); readonly static CustomColour NonRVSM = new CustomColour(242, 133, 0); readonly static CustomColour SepFlags = new CustomColour(0, 196, 253); - readonly static CustomColour Probe = new CustomColour(0, 255, 0); + readonly static CustomColour Pending = new CustomColour(46, 139, 87); readonly static CustomColour NotCDA = new CustomColour(100, 0, 100); readonly ConcurrentDictionary eastboundCallsigns = new ConcurrentDictionary(); + readonly ConcurrentDictionary flagtoggle = new ConcurrentDictionary(); /// Plugin Name public string Name { get => "Aurora Label Items"; } public void OnFDRUpdate(FDP2.FDR updated) { if (FDP2.GetFDRIndex(updated.Callsign) == -1) //FDR was removed (that's what triggered the update) + { eastboundCallsigns.TryRemove(updated.Callsign, out _); + flagtoggle.TryRemove(updated.Callsign, out _); + } else @@ -55,27 +61,11 @@ public void OnFDRUpdate(FDP2.FDR updated) } } - //internal void SendContactMe(NetworkPilot pilot, VSCSFrequency freq) - //{ - // if (validATC && HaveConnection && !((DateTime.UtcNow - pilot.LastContactMe).TotalMinutes < 1.0)) - // { - // string text = "Please contact me on " + Conversions.FrequencyToString(freq.Frequency); - // if (freq.AliasFrequency != VSCSFrequency.None.Frequency) - // { - // text = text + " (" + Conversions.FrequencyToString(freq.AliasFrequency) + ")"; - // } - // - // SendTextMessage(pilot.Callsign, text); - // pilot.LastContactMe = DateTime.UtcNow; - // } - //} - /// This is called each time a radar track is updated public void OnRadarTrackUpdate(RDP.RadarTrack updated) { } - public static bool MachNumberTech(PerformanceData mnt) { if (mnt == null) return false; @@ -89,7 +79,16 @@ public static bool MachNumberTech(PerformanceData mnt) private void ItemMouseClick(CustomLabelItemMouseClickEventArgs e) { - e.Item.CustomForeColour = SepFlags; + bool flagToggled = flagtoggle.TryGetValue(e.Track.GetFDR().Callsign, out _); + + if (flagToggled) + { + flagtoggle.TryRemove(e.Track.GetFDR().Callsign, out _); + } + else + { + flagtoggle.TryAdd(e.Track.GetFDR().Callsign, 0); + } e.Handled = true; } public CustomStripItem GetCustomStripItem(string itemType, Track track, FDP2.FDR flightDataRecord, RDP.RadarTrack radarTrack) @@ -98,7 +97,7 @@ public CustomStripItem GetCustomStripItem(string itemType, Track track, FDP2.FDR Match pbn = Regex.Match(flightDataRecord.Remarks, @"PBN\/\w+\s"); bool cpdlc = Regex.IsMatch(flightDataRecord.AircraftEquip, @"J5") || Regex.IsMatch(flightDataRecord.AircraftEquip, @"J7"); bool adsc = Regex.IsMatch(flightDataRecord.AircraftSurvEquip, @"D1"); - bool adsb = flightDataRecord.ADSB; //Regex.IsMatch(flightDataRecord.AircraftSurvEquip, @"B\d"); + bool adsb = flightDataRecord.ADSB; bool rnp10 = Regex.IsMatch(pbn.Value, @"A1"); bool rnp4 = Regex.IsMatch(pbn.Value, @"L1"); bool rvsm = flightDataRecord.RVSM; @@ -106,8 +105,9 @@ public CustomStripItem GetCustomStripItem(string itemType, Track track, FDP2.FDR int cfl; bool isCfl = Int32.TryParse(flightDataRecord.CFLString, out cfl); bool isEastBound = true; + bool flagToggled = flagtoggle.TryGetValue(flightDataRecord.Callsign, out _); - if (flightDataRecord is null) + if (flightDataRecord is null) return null; switch (itemType) @@ -134,6 +134,30 @@ public CustomStripItem GetCustomStripItem(string itemType, Track track, FDP2.FDR Text = flightDataRecord.Callsign }; } + + case STRIP_ITEM_CTLSECTOR: + + bool pendingCoordination = track.State == MMI.HMIStates.Preactive || track.State == MMI.HMIStates.Announced; + + return new CustomStripItem() + { + ForeColourIdentity = pendingCoordination ? Colours.Identities.Custom : default, + CustomForeColour = Pending, + Text = flightDataRecord.ControllingSector != null ? flightDataRecord.ControllingSector.Name : null + }; + + + // case STRIP_ITEM_NXTSECTOR: + // + // return new CustomStripItem() + // { + // ForeColourIdentity = Colours.Identities.Custom, + // CustomForeColour = Pending, + // Text = + // }; + + + case LABEL_ITEM_ADSB_CPDLC: @@ -176,7 +200,8 @@ public CustomStripItem GetCustomStripItem(string itemType, Track track, FDP2.FDR return new CustomStripItem() { - //BackColourIdentity = Colours.Identities.Custom, + BackColourIdentity = flagToggled ? Colours.Identities.Custom : default, + CustomBackColour = SepFlags, Text = "M", OnMouseClick = ItemMouseClick }; @@ -189,7 +214,8 @@ public CustomStripItem GetCustomStripItem(string itemType, Track track, FDP2.FDR return new CustomStripItem() { - //BackColourIdentity = Colours.Identities.Custom, + BackColourIdentity = flagToggled ? Colours.Identities.Custom : default, + CustomBackColour = SepFlags, Text = "R", OnMouseClick = ItemMouseClick }; @@ -203,7 +229,8 @@ public CustomStripItem GetCustomStripItem(string itemType, Track track, FDP2.FDR return new CustomStripItem() { - //BackColourIdentity = Colours.Identities.Custom, + BackColourIdentity = flagToggled ? Colours.Identities.Custom : default, + CustomBackColour = SepFlags, Text = rnp4 ? "3" : "D", OnMouseClick = ItemMouseClick }; @@ -280,5 +307,14 @@ public CustomStripItem GetCustomStripItem(string itemType, Track track, FDP2.FDR default: return null; } } + //private CustomColour PETOColor(FDP2.FDR.ExtractedRoute.Segment estimate, Colours.Identities state) + //{ + // if (estimate.IsPETO) + // { + // return state = state; + // } + // + // return null; + //} } } From 560a41aa807f7d33d971ef2b91431702a09aea71 Mon Sep 17 00:00:00 2001 From: Dominic Nguyen Date: Mon, 19 Dec 2022 22:03:03 -0800 Subject: [PATCH 14/76] remove event --- AuroraLabelItemsPlugin.cs | 48 +++++++++++++++++++-------------------- 1 file changed, 24 insertions(+), 24 deletions(-) diff --git a/AuroraLabelItemsPlugin.cs b/AuroraLabelItemsPlugin.cs index efc1e6e..f58f72d 100644 --- a/AuroraLabelItemsPlugin.cs +++ b/AuroraLabelItemsPlugin.cs @@ -45,28 +45,13 @@ public class AuroraLabelItemsPlugin : ILabelPlugin readonly ConcurrentDictionary adsflagtoggle = new ConcurrentDictionary(); readonly ConcurrentDictionary mntflagtoggle = new ConcurrentDictionary(); readonly ConcurrentDictionary downlink = new ConcurrentDictionary(); - readonly ConcurrentDictionary trackselect = new ConcurrentDictionary(); public AuroraLabelItemsPlugin() { Network.PrivateMessagesChanged += Network_PrivateMessagesChanged; Network.RadioMessageAcknowledged += Network_RadioMessageAcknowledged; - //MMI.SelectedTrackChanged += MMI_SelectedTrackChanged; } - //private void MMI_SelectedTrackChanged(object sender, EventArgs e) - //{ - // var callsign = MMI.SelectedTrack?.GetFDR()?.Callsign; - // if (callsign != null) - // { - // trackselect.TryRemove(callsign, out _); - // - // } - // else - // { - // trackselect.TryAdd(callsign, 0); - // } - //} private void Network_RadioMessageAcknowledged(object sender, RadioMessageEventArgs e) { @@ -108,7 +93,6 @@ public void OnFDRUpdate(FDP2.FDR updated) adsflagtoggle.TryRemove(updated.Callsign, out _); mntflagtoggle.TryRemove(updated.Callsign, out _); downlink.TryRemove(updated.Callsign, out _); - trackselect.TryRemove(updated.Callsign, out _); } else { @@ -264,34 +248,50 @@ public CustomLabelItem GetCustomLabelItem(string itemType, Track track, FDP2.FDR bool adsflagToggled = adsflagtoggle.TryGetValue(flightDataRecord.Callsign, out _); bool mntflagToggled = mntflagtoggle.TryGetValue(flightDataRecord.Callsign, out _); bool downLink = downlink.TryGetValue(flightDataRecord.Callsign, out _); - bool trackSelect = trackselect.TryGetValue(flightDataRecord.Callsign, out _); - + bool selectedCallsign = MMI.SelectedTrack?.GetFDR()?.Callsign == flightDataRecord.Callsign; + switch (itemType) { case LABEL_ITEM_SELECT_HORI: - if (trackSelect) + if (selectedCallsign) { return new CustomLabelItem() + { - Border = BorderFlags.Horizontal + Border = BorderFlags.Top }; } - else return null; + else + { + return new CustomLabelItem() + + { + Border = BorderFlags.None + }; + } case LABEL_ITEM_SELECT_VERT: - if (trackSelect) + if (selectedCallsign) { return new CustomLabelItem() { - Border = BorderFlags.Vertical + Text = "", + Border = BorderFlags.Left }; } - else return null; + else + { + return new CustomLabelItem() + { + Text = "", + Border = BorderFlags.None + }; + } case LABEL_ITEM_COMM_ICON: From 3b9f5eafb711f151f8003164384bf9ded51735de Mon Sep 17 00:00:00 2001 From: Dominic Nguyen Date: Thu, 18 May 2023 15:17:24 -0700 Subject: [PATCH 15/76] Mach # --- AuroraLabelItemsPlugin.cs | 4 +- AuroraStripItemPlugin.cs | 640 +++++++++++++++++++------------------- 2 files changed, 323 insertions(+), 321 deletions(-) diff --git a/AuroraLabelItemsPlugin.cs b/AuroraLabelItemsPlugin.cs index f58f72d..7d1c25d 100644 --- a/AuroraLabelItemsPlugin.cs +++ b/AuroraLabelItemsPlugin.cs @@ -458,9 +458,11 @@ public CustomLabelItem GetCustomLabelItem(string itemType, Track track, FDP2.FDR } case LABEL_ITEM_FILED_SPEED: + var mach = flightDataRecord.TAS / 581.0; return new CustomLabelItem() { - Text = "N" + flightDataRecord.TAS + Text = "M" + Convert.ToDecimal(mach).ToString("F2").Replace(".","") + //Text = "N" + flightDataRecord.TAS }; case LABEL_ITEM_3DIGIT_GROUNDSPEED: diff --git a/AuroraStripItemPlugin.cs b/AuroraStripItemPlugin.cs index a3887bc..49e4387 100644 --- a/AuroraStripItemPlugin.cs +++ b/AuroraStripItemPlugin.cs @@ -1,320 +1,320 @@ -using System; -using System.Collections.Generic; -using System.Text.RegularExpressions; -using vatsys; -using vatsys.Plugin; -using System.Collections.Concurrent; -using System.ComponentModel.Composition; //<--Need to add a reference to System.ComponentModel.Composition -using static vatsys.Performance; -using static vatsys.Network; - -namespace AuroraStripItemsPlugin -{ - [Export(typeof(IPlugin))] - - public class AuroraStripItemsPlugin : IStripPlugin - { - - /// The name of the custom label item we've added to Labels - /// in the Profile - const string LABEL_ITEM_ADSB_CPDLC = "AURORA_ADSB_CPDLC"; //field c(4) - const string STRIP_ITEM_CALLSIGN = "AURORA_CALLSIGN"; - const string STRIP_ITEM_CTLSECTOR = "AURORA_CDA"; - const string STRIP_ITEM_NXTSECTOR = "AURORA_NDA"; - const string STRIP_ITEM_T10_FLAG = "AURORA_T10_FLAG"; - const string STRIP_ITEM_MNT_FLAG = "AURORA_MNT_FLAG"; - const string STRIP_ITEM_DIST_FLAG = "AURORA_DIST_FLAG"; - const string STRIP_ITEM_RVSM_FLAG = "AURORA_RVSM_FLAG"; - const string STRIP_ITEM_VMI = "AURORA_STRIP_VMI"; - const string STRIP_ITEM_MAN_EST = "AURORA_MAN_EST"; - const string STRIP_ITEM_LATERAL_FLAG = "AURORA_LATERAL_FLAG"; - const string STRIP_ITEM_ANNOT_IND = "AURORA_ANNOT_STRIP"; - readonly static CustomColour NonRVSM = new CustomColour(242, 133, 0); - readonly static CustomColour SepFlags = new CustomColour(0, 196, 253); - readonly static CustomColour Pending = new CustomColour(46, 139, 87); - readonly static CustomColour NotCDA = new CustomColour(100, 0, 100); - readonly ConcurrentDictionary eastboundCallsigns = new ConcurrentDictionary(); - readonly ConcurrentDictionary flagtoggle = new ConcurrentDictionary(); - /// Plugin Name - public string Name { get => "Aurora Label Items"; } - - public void OnFDRUpdate(FDP2.FDR updated) - { - if (FDP2.GetFDRIndex(updated.Callsign) == -1) //FDR was removed (that's what triggered the update) - { - eastboundCallsigns.TryRemove(updated.Callsign, out _); - flagtoggle.TryRemove(updated.Callsign, out _); - } - - else - - { - - if (updated.ParsedRoute.Count > 1) - { - //calculate track from first route point to last (Departure point to destination point) - var rte = updated.ParsedRoute; - double trk = Conversions.CalculateTrack(rte.First().Intersection.LatLong, rte.Last().Intersection.LatLong); - bool east = trk >= 0 && trk < 180; - eastboundCallsigns.AddOrUpdate(updated.Callsign, east, (c, e) => east); - } - } - } - - /// This is called each time a radar track is updated - public void OnRadarTrackUpdate(RDP.RadarTrack updated) - { - - } - public static bool MachNumberTech(PerformanceData mnt) - { - if (mnt == null) return false; - return mnt.IsJet; - } - - //public void Estimates(FDP2.FDR.ExtractedRoute.Segment estimate) - //{ - // estimate.IsPETO = true; - //} - - private void ItemMouseClick(CustomLabelItemMouseClickEventArgs e) - { - bool flagToggled = flagtoggle.TryGetValue(e.Track.GetFDR().Callsign, out _); - - if (flagToggled) - { - flagtoggle.TryRemove(e.Track.GetFDR().Callsign, out _); - } - else - { - flagtoggle.TryAdd(e.Track.GetFDR().Callsign, 0); - } - e.Handled = true; - } - public CustomStripItem GetCustomStripItem(string itemType, Track track, FDP2.FDR flightDataRecord, RDP.RadarTrack radarTrack) - - { - Match pbn = Regex.Match(flightDataRecord.Remarks, @"PBN\/\w+\s"); - bool cpdlc = Regex.IsMatch(flightDataRecord.AircraftEquip, @"J5") || Regex.IsMatch(flightDataRecord.AircraftEquip, @"J7"); - bool adsc = Regex.IsMatch(flightDataRecord.AircraftSurvEquip, @"D1"); - bool adsb = flightDataRecord.ADSB; - bool rnp10 = Regex.IsMatch(pbn.Value, @"A1"); - bool rnp4 = Regex.IsMatch(pbn.Value, @"L1"); - bool rvsm = flightDataRecord.RVSM; - int level = radarTrack == null ? flightDataRecord.PRL / 100 : radarTrack.CorrectedAltitude / 100; - int cfl; - bool isCfl = Int32.TryParse(flightDataRecord.CFLString, out cfl); - bool isEastBound = true; - bool flagToggled = flagtoggle.TryGetValue(flightDataRecord.Callsign, out _); - - if (flightDataRecord is null) - return null; - - switch (itemType) - { - case STRIP_ITEM_CALLSIGN: - - eastboundCallsigns.TryGetValue(flightDataRecord.Callsign, out isEastBound); - - if (isEastBound) - { - return new CustomStripItem() - { - BackColourIdentity = Colours.Identities.StripText, - ForeColourIdentity = Colours.Identities.StripBackground, - Text = flightDataRecord.Callsign - }; - } - else - { - return new CustomStripItem() - { - BackColourIdentity = Colours.Identities.StripBackground, - ForeColourIdentity = Colours.Identities.StripText, - Text = flightDataRecord.Callsign - }; - } - - case STRIP_ITEM_CTLSECTOR: - - bool pendingCoordination = track.State == MMI.HMIStates.Preactive || track.State == MMI.HMIStates.Announced; - - return new CustomStripItem() - { - ForeColourIdentity = pendingCoordination ? Colours.Identities.Custom : default, - CustomForeColour = Pending, - Text = flightDataRecord.ControllingSector != null ? flightDataRecord.ControllingSector.Name : null - }; - - - // case STRIP_ITEM_NXTSECTOR: - // - // return new CustomStripItem() - // { - // ForeColourIdentity = Colours.Identities.Custom, - // CustomForeColour = Pending, - // Text = - // }; - - - - case LABEL_ITEM_ADSB_CPDLC: - - - if (isEastBound & !adsb & cpdlc) - - return new CustomStripItem() - { - BackColourIdentity = Colours.Identities.StripText, - ForeColourIdentity = Colours.Identities.StripBackground, - Text = "⧆" - }; - - else if (!adsb & cpdlc) - - return new CustomStripItem() - { - Text = "⧆" - }; - - - else if (!adsb) - - return new CustomStripItem() - { - Text = "⎕" - }; - - else if (cpdlc) - - return new CustomStripItem() - { - Text = "*" - }; - - return null; - - case STRIP_ITEM_T10_FLAG: - - if (MachNumberTech(flightDataRecord.PerformanceData)) - - return new CustomStripItem() - { - BackColourIdentity = flagToggled ? Colours.Identities.Custom : default, - CustomBackColour = SepFlags, - Text = "M", - OnMouseClick = ItemMouseClick - }; - - return null; - - case STRIP_ITEM_MNT_FLAG: - - if (MachNumberTech(flightDataRecord.PerformanceData)) - - return new CustomStripItem() - { - BackColourIdentity = flagToggled ? Colours.Identities.Custom : default, - CustomBackColour = SepFlags, - Text = "R", - OnMouseClick = ItemMouseClick - }; - - return null; - - case STRIP_ITEM_DIST_FLAG: - - if (adsc & cpdlc & rnp4 || rnp10) - - - return new CustomStripItem() - { - BackColourIdentity = flagToggled ? Colours.Identities.Custom : default, - CustomBackColour = SepFlags, - Text = rnp4 ? "3" : "D", - OnMouseClick = ItemMouseClick - }; - return null; - - case STRIP_ITEM_RVSM_FLAG: - - if (rvsm) - - return new CustomStripItem() - { - BackColourIdentity = Colours.Identities.Custom, - CustomBackColour = SepFlags, - Text = "W" - }; - - return null; - - case STRIP_ITEM_VMI: - var vs = radarTrack == null ? flightDataRecord.PredictedPosition.VerticalSpeed : radarTrack.VerticalSpeed; - - if (level == cfl || level == flightDataRecord.RFL)//level - - return new CustomStripItem() - { - Text = "" - }; - else if (cfl > level && track.NewCFL || vs > 300)//Issued or trending climb - - return new CustomStripItem() - { - Text = "↑", - }; - - else if (cfl > 0 && cfl < level && track.NewCFL || vs < -300)//Issued or trending descent - - return new CustomStripItem() - { - Text = "↓", - }; - - return null; - - //case STRIP_ITEM_MAN_EST: - - //if (Estimates) - // return new CustomStripItem() - // { - // BackColourIdentity = Colours.Identities.HighlightedText - // }; - //return null; - - case STRIP_ITEM_ANNOT_IND: - - return new CustomStripItem() - { - Text = "." //& - }; - - - case STRIP_ITEM_LATERAL_FLAG: - - if (adsc & cpdlc & rnp4 || rnp10) - - - return new CustomStripItem() - { - //BackColourIdentity = Colours.Identities.Custom, - Text = rnp4 ? "4" : "R", - OnMouseClick = ItemMouseClick - }; - return null; - - default: return null; - } - } - //private CustomColour PETOColor(FDP2.FDR.ExtractedRoute.Segment estimate, Colours.Identities state) - //{ - // if (estimate.IsPETO) - // { - // return state = state; - // } - // - // return null; - //} - } -} +using System; +using System.Collections.Generic; +using System.Text.RegularExpressions; +using vatsys; +using vatsys.Plugin; +using System.Collections.Concurrent; +using System.ComponentModel.Composition; //<--Need to add a reference to System.ComponentModel.Composition +using static vatsys.Performance; +using static vatsys.Network; + +namespace AuroraStripItemsPlugin +{ + [Export(typeof(IPlugin))] + + public class AuroraStripItemsPlugin : IStripPlugin + { + + /// The name of the custom label item we've added to Labels + /// in the Profile + const string LABEL_ITEM_ADSB_CPDLC = "AURORA_ADSB_CPDLC"; //field c(4) + const string STRIP_ITEM_CALLSIGN = "AURORA_CALLSIGN"; + const string STRIP_ITEM_CTLSECTOR = "AURORA_CDA"; + const string STRIP_ITEM_NXTSECTOR = "AURORA_NDA"; + const string STRIP_ITEM_T10_FLAG = "AURORA_T10_FLAG"; + const string STRIP_ITEM_MNT_FLAG = "AURORA_MNT_FLAG"; + const string STRIP_ITEM_DIST_FLAG = "AURORA_DIST_FLAG"; + const string STRIP_ITEM_RVSM_FLAG = "AURORA_RVSM_FLAG"; + const string STRIP_ITEM_VMI = "AURORA_STRIP_VMI"; + const string STRIP_ITEM_MAN_EST = "AURORA_MAN_EST"; + const string STRIP_ITEM_LATERAL_FLAG = "AURORA_LATERAL_FLAG"; + const string STRIP_ITEM_ANNOT_IND = "AURORA_ANNOT_STRIP"; + readonly static CustomColour NonRVSM = new CustomColour(242, 133, 0); + readonly static CustomColour SepFlags = new CustomColour(0, 196, 253); + readonly static CustomColour Pending = new CustomColour(46, 139, 87); + readonly static CustomColour NotCDA = new CustomColour(100, 0, 100); + readonly ConcurrentDictionary eastboundCallsigns = new ConcurrentDictionary(); + readonly ConcurrentDictionary flagtoggle = new ConcurrentDictionary(); + /// Plugin Name + public string Name { get => "Aurora Label Items"; } + + public void OnFDRUpdate(FDP2.FDR updated) + { + if (FDP2.GetFDRIndex(updated.Callsign) == -1) //FDR was removed (that's what triggered the update) + { + eastboundCallsigns.TryRemove(updated.Callsign, out _); + flagtoggle.TryRemove(updated.Callsign, out _); + } + + else + + { + + if (updated.ParsedRoute.Count > 1) + { + //calculate track from first route point to last (Departure point to destination point) + var rte = updated.ParsedRoute; + double trk = Conversions.CalculateTrack(rte.First().Intersection.LatLong, rte.Last().Intersection.LatLong); + bool east = trk >= 0 && trk < 180; + eastboundCallsigns.AddOrUpdate(updated.Callsign, east, (c, e) => east); + } + } + } + + /// This is called each time a radar track is updated + public void OnRadarTrackUpdate(RDP.RadarTrack updated) + { + + } + public static bool MachNumberTech(PerformanceData mnt) + { + if (mnt == null) return false; + return mnt.IsJet; + } + + //public void Estimates(FDP2.FDR.ExtractedRoute.Segment estimate) + //{ + // estimate.IsPETO = true; + //} + + private void ItemMouseClick(CustomLabelItemMouseClickEventArgs e) + { + bool flagToggled = flagtoggle.TryGetValue(e.Track.GetFDR().Callsign, out _); + + if (flagToggled) + { + flagtoggle.TryRemove(e.Track.GetFDR().Callsign, out _); + } + else + { + flagtoggle.TryAdd(e.Track.GetFDR().Callsign, 0); + } + e.Handled = true; + } + public CustomStripItem GetCustomStripItem(string itemType, Track track, FDP2.FDR flightDataRecord, RDP.RadarTrack radarTrack) + + { + Match pbn = Regex.Match(flightDataRecord.Remarks, @"PBN\/\w+\s"); + bool cpdlc = Regex.IsMatch(flightDataRecord.AircraftEquip, @"J5") || Regex.IsMatch(flightDataRecord.AircraftEquip, @"J7"); + bool adsc = Regex.IsMatch(flightDataRecord.AircraftSurvEquip, @"D1"); + bool adsb = flightDataRecord.ADSB; + bool rnp10 = Regex.IsMatch(pbn.Value, @"A1"); + bool rnp4 = Regex.IsMatch(pbn.Value, @"L1"); + bool rvsm = flightDataRecord.RVSM; + int level = radarTrack == null ? flightDataRecord.PRL / 100 : radarTrack.CorrectedAltitude / 100; + int cfl; + bool isCfl = Int32.TryParse(flightDataRecord.CFLString, out cfl); + bool isEastBound = true; + bool flagToggled = flagtoggle.TryGetValue(flightDataRecord.Callsign, out _); + + if (flightDataRecord is null) + return null; + + switch (itemType) + { + case STRIP_ITEM_CALLSIGN: + + eastboundCallsigns.TryGetValue(flightDataRecord.Callsign, out isEastBound); + + if (isEastBound) + { + return new CustomStripItem() + { + BackColourIdentity = Colours.Identities.StripText, + ForeColourIdentity = Colours.Identities.StripBackground, + Text = flightDataRecord.Callsign + }; + } + else + { + return new CustomStripItem() + { + BackColourIdentity = Colours.Identities.StripBackground, + ForeColourIdentity = Colours.Identities.StripText, + Text = flightDataRecord.Callsign + }; + } + + case STRIP_ITEM_CTLSECTOR: + + bool pendingCoordination = track.State == MMI.HMIStates.Preactive || track.State == MMI.HMIStates.Announced; + + return new CustomStripItem() + { + ForeColourIdentity = pendingCoordination ? Colours.Identities.Custom : default, + CustomForeColour = Pending, + Text = flightDataRecord.ControllingSector != null ? flightDataRecord.ControllingSector.Name : null + }; + + + // case STRIP_ITEM_NXTSECTOR: + // + // return new CustomStripItem() + // { + // ForeColourIdentity = Colours.Identities.Custom, + // CustomForeColour = Pending, + // Text = + // }; + + + + case LABEL_ITEM_ADSB_CPDLC: + + + if (isEastBound & !adsb & cpdlc) + + return new CustomStripItem() + { + BackColourIdentity = Colours.Identities.StripText, + ForeColourIdentity = Colours.Identities.StripBackground, + Text = "⧆" + }; + + else if (!adsb & cpdlc) + + return new CustomStripItem() + { + Text = "⧆" + }; + + + else if (!adsb) + + return new CustomStripItem() + { + Text = "⎕" + }; + + else if (cpdlc) + + return new CustomStripItem() + { + Text = "*" + }; + + return null; + + case STRIP_ITEM_T10_FLAG: + + if (MachNumberTech(flightDataRecord.PerformanceData)) + + return new CustomStripItem() + { + BackColourIdentity = flagToggled ? Colours.Identities.Custom : default, + CustomBackColour = SepFlags, + Text = "M", + OnMouseClick = ItemMouseClick + }; + + return null; + + case STRIP_ITEM_MNT_FLAG: + + if (MachNumberTech(flightDataRecord.PerformanceData)) + + return new CustomStripItem() + { + BackColourIdentity = flagToggled ? Colours.Identities.Custom : default, + CustomBackColour = SepFlags, + Text = "R", + OnMouseClick = ItemMouseClick + }; + + return null; + + case STRIP_ITEM_DIST_FLAG: + + if (adsc & cpdlc & rnp4 || rnp10) + + + return new CustomStripItem() + { + BackColourIdentity = flagToggled ? Colours.Identities.Custom : default, + CustomBackColour = SepFlags, + Text = rnp4 ? "3" : "D", + OnMouseClick = ItemMouseClick + }; + return null; + + case STRIP_ITEM_RVSM_FLAG: + + if (rvsm) + + return new CustomStripItem() + { + BackColourIdentity = Colours.Identities.Custom, + CustomBackColour = SepFlags, + Text = "W" + }; + + return null; + + case STRIP_ITEM_VMI: + var vs = radarTrack == null ? flightDataRecord.PredictedPosition.VerticalSpeed : radarTrack.VerticalSpeed; + + if (level == cfl || level == flightDataRecord.RFL)//level + + return new CustomStripItem() + { + Text = "" + }; + else if (cfl > level && track.NewCFL || vs > 300)//Issued or trending climb + + return new CustomStripItem() + { + Text = "↑", + }; + + else if (cfl > 0 && cfl < level && track.NewCFL || vs < -300)//Issued or trending descent + + return new CustomStripItem() + { + Text = "↓", + }; + + return null; + + //case STRIP_ITEM_MAN_EST: + + //if (Estimates) + // return new CustomStripItem() + // { + // BackColourIdentity = Colours.Identities.HighlightedText + // }; + //return null; + + case STRIP_ITEM_ANNOT_IND: + + return new CustomStripItem() + { + Text = "." //& + }; + + + case STRIP_ITEM_LATERAL_FLAG: + + if (adsc & cpdlc & rnp4 || rnp10) + + + return new CustomStripItem() + { + //BackColourIdentity = Colours.Identities.Custom, + Text = rnp4 ? "4" : "R", + OnMouseClick = ItemMouseClick + }; + return null; + + default: return null; + } + } + //private CustomColour PETOColor(FDP2.FDR.ExtractedRoute.Segment estimate, Colours.Identities state) + //{ + // if (estimate.IsPETO) + // { + // return state = state; + // } + // + // return null; + //} + } +} From da5ec39e36e9b71945a98433f321cf4dff957efd Mon Sep 17 00:00:00 2001 From: Dominic Nguyen Date: Thu, 13 Jul 2023 16:10:20 -0700 Subject: [PATCH 16/76] Added strips --- FAAStripItemPlugin.cs | 156 +++++++++++++++++++ MEARTSLabelItemsPlugin.cs | 319 ++++++++++++++++++++++++++++++++++++++ 2 files changed, 475 insertions(+) create mode 100644 FAAStripItemPlugin.cs create mode 100644 MEARTSLabelItemsPlugin.cs diff --git a/FAAStripItemPlugin.cs b/FAAStripItemPlugin.cs new file mode 100644 index 0000000..7f855a1 --- /dev/null +++ b/FAAStripItemPlugin.cs @@ -0,0 +1,156 @@ +using System; +using System.Collections.Generic; +using System.Text.RegularExpressions; +using vatsys; +using vatsys.Plugin; +using System.Collections.Concurrent; +using System.ComponentModel.Composition; //<--Need to add a reference to System.ComponentModel.Composition +using static vatsys.Performance; +using static vatsys.Network; +using System.Linq; + +namespace FAAStripItemsPlugin +{ + [Export(typeof(IPlugin))] + + public class FAAStripItemsPlugin : IStripPlugin + { + + /// The name of the custom label item we've added to Labels + /// in the Profile + const string STRIP_ITEM_HEAVY = "FAA_HEAVY"; + const string STRIP_ITEM_CTLSECTOR = "AURORA_CDA"; + const string STRIP_ITEM_NXTSECTOR = "AURORA_NDA"; + const string STRIP_ITEM_EQSUFFIX = "FAA_EQUIPMENT"; + const string STRIP_ITEM_TRUNCSYM = "FAA_TRUNCATION"; + const string STRIP_ITEM_TAS = "FAA_TAS"; + const string STRIP_ITEM_GS = "FAA_GS"; + const string STRIP_ITEM_HOUR = "FAA_HOUR"; + const string STRIP_ITEM_MINUTE = "FAA_MINUTE"; + const string STRIP_ITEM_ROUTE = "FAA_ROUTE"; + const string STRIP_ITEM_REMARKS = "FAA_REMARKS"; + + public string Name => throw new NotImplementedException(); + + /// Plugin Name + + public void OnFDRUpdate(FDP2.FDR updated) + { + + } + + /// This is called each time a radar track is updated + public void OnRadarTrackUpdate(RDP.RadarTrack updated) + { + + } + + private void ItemMouseClick(CustomLabelItemMouseClickEventArgs e) + { + + } + public CustomStripItem GetCustomStripItem(string itemType, Track track, FDP2.FDR flightDataRecord, RDP.RadarTrack radarTrack) + + { + //bool trunc = flightDataRecord.DepAirport != flightDataRecord.Route.Equals; + bool heavy = Regex.IsMatch(flightDataRecord.AircraftWake, @"H"); + bool faaFp = !flightDataRecord.IsICAOFormat; + int level = radarTrack == null ? flightDataRecord.PRL / 100 : radarTrack.CorrectedAltitude / 100; + int cfl; + bool isCfl = Int32.TryParse(flightDataRecord.CFLString, out cfl); + + + if (flightDataRecord is null) + return null; + + switch (itemType) + { + case STRIP_ITEM_HEAVY: + + if (heavy) + { + return new CustomStripItem() + { + Text = "H/" + }; + } + return null; + + case STRIP_ITEM_EQSUFFIX: + + if (faaFp) + { + return new CustomStripItem() + { + Text = "/" + flightDataRecord.AircraftEquip + }; + } + return null; + + + case STRIP_ITEM_NXTSECTOR: + + return new CustomStripItem() + { + Text = flightDataRecord.HandoffSector.ToString() + }; + + case STRIP_ITEM_TAS: + var mach = flightDataRecord.TAS / 581.0; + return new CustomStripItem() + { + //Text = "M" + Convert.ToDecimal(mach).ToString("F2").Replace(".", "") + Text = "T" + flightDataRecord.TAS.ToString("000")//format as 3 digits (with leading zeros) + }; + + case STRIP_ITEM_GS: + + return new CustomStripItem() + { + Text = radarTrack == null ? null :"G" + radarTrack.GroundSpeed.ToString("000")//format as 3 digits (with leading zeros) + }; + + case STRIP_ITEM_HOUR: + + return new CustomStripItem() + { + Text = flightDataRecord.PredictedPosition.ETO.ToString("HH") //format as 2 digit hour + }; + + case STRIP_ITEM_MINUTE: + + + return new CustomStripItem() + { + Text = flightDataRecord.PredictedPosition.ETO.ToString("mm") //format as 2 digit minute + }; + + case STRIP_ITEM_ROUTE: + + return new CustomStripItem() + { + Text = flightDataRecord.Route + }; + + case STRIP_ITEM_REMARKS: + + return new CustomStripItem() + { + Text = "○" + flightDataRecord.Remarks + }; + //case STRIP_ITEM_TRUNCSYM: + // + // if (trunc) + // { + // return new CustomStripItem() + // { + // Text = "./." + // }; + // } + // return null; + + default: return null; + } + } + } +} diff --git a/MEARTSLabelItemsPlugin.cs b/MEARTSLabelItemsPlugin.cs new file mode 100644 index 0000000..defb0b9 --- /dev/null +++ b/MEARTSLabelItemsPlugin.cs @@ -0,0 +1,319 @@ +using System; +using System.Collections.Concurrent; +using System.ComponentModel.Composition; //<--Need to add a reference to System.ComponentModel.Composition +using System.Text.RegularExpressions; +using vatsys; +using vatsys.Plugin; + + +//Note the reference to vatsys (set Copy Local to false) -----> + +namespace AuroraLabelItemsPlugin +{ + [Export(typeof(IPlugin))] + + public class MEARTSLabelItemsPlugin : ILabelPlugin + { + + /// The name of the custom label item we've added to Labels + /// in the Profile + const string LABEL_ITEM_SELECT_HORI = "SELECT_HORI"; + const string LABEL_ITEM_SELECT_VERT = "SELECT_VERT"; + const string LABEL_ITEM_COMM_ICON = "AURORA_COMM_ICON"; //field a(2) + const string LABEL_ITEM_ADSB_CPDLC = "AURORA_ADSB_CPDLC"; //field c(4) + const string LABEL_ITEM_ADS_FLAGS = "AURORA_ADS_FLAGS"; //field c(4) + const string LABEL_ITEM_MNT_FLAGS = "AURORA_MNT_FLAGS"; //field c(4) + const string LABEL_ITEM_SCC = "AURORA_SCC"; //field c(5) + const string LABEL_ITEM_ANNOT_IND = "AURORA_ANNOT_IND"; //field e(1) + const string LABEL_ITEM_RESTR = "AURORA_RESTR"; //field f(1) + const string LABEL_ITEM_VMI = "AURORA_VMI"; //field h(1) + const string LABEL_ITEM_CLEARED_LEVEL = "AURORA_CLEARED_LEVEL"; //field i(7) + const string LABEL_ITEM_RADAR_IND = "AURORA_RADAR_IND"; //field k(1) + const string LABEL_ITEM_FILED_SPEED = "AURORA_FILEDSPEED"; //field m(4) + const string LABEL_ITEM_3DIGIT_GROUNDSPEED = "AURORA_GROUNDSPEED"; //field n(5) + readonly static CustomColour EastboundColour = new CustomColour(240, 255, 255); + readonly static CustomColour WestboundColour = new CustomColour(240, 231, 140); + readonly static CustomColour NonRVSM = new CustomColour(242, 133, 0); + readonly static CustomColour Probe = new CustomColour(0, 255, 0); + readonly static CustomColour NotCDA = new CustomColour(100, 0, 100); + readonly ConcurrentDictionary eastboundCallsigns = new ConcurrentDictionary(); + readonly ConcurrentDictionary adsbcpdlcValues = new ConcurrentDictionary(); + readonly ConcurrentDictionary adsflagValues = new ConcurrentDictionary(); + readonly ConcurrentDictionary mntflagValues = new ConcurrentDictionary(); + readonly ConcurrentDictionary altValues = new ConcurrentDictionary(); + readonly ConcurrentDictionary radartoggle = new ConcurrentDictionary(); + readonly ConcurrentDictionary adsflagtoggle = new ConcurrentDictionary(); + readonly ConcurrentDictionary mntflagtoggle = new ConcurrentDictionary(); + readonly ConcurrentDictionary downlink = new ConcurrentDictionary(); + + public MEARTSLabelItemsPlugin() + { + Network.PrivateMessagesChanged += Network_PrivateMessagesChanged; + Network.RadioMessageAcknowledged += Network_RadioMessageAcknowledged; + } + + + private void Network_RadioMessageAcknowledged(object sender, RadioMessageEventArgs e) + { + throw new NotImplementedException(); + } + + private void Network_PrivateMessagesChanged(object sender, Network.GenericMessageEventArgs e) + { + bool downLink = e.Message.Sent == true; + + if (downLink) + { + downlink.TryRemove(e.Message.Address, out _); + } + else + { + downlink.TryAdd(e.Message.Address, 0); + } + + } + + /// Plugin Name + public string Name { get => "Aurora Label Items"; } + + /// This is called each time a flight data record is updated + /// Here we are updating the eastbound callsigns dictionary with each flight data record + /// When the FDR is updated we check if it still exists in the Flight Data Processor and remove from our dictionary if not. Otherwise we do some simple regex matching to find + /// the flight planned PBN category and store the character we want to display in the label in the dictionary. + public void OnFDRUpdate(FDP2.FDR updated) + { + if (FDP2.GetFDRIndex(updated.Callsign) == -1) + { + + altValues.TryRemove(updated.Callsign, out _); + + } + else + { + int cfl; + bool isCfl = Int32.TryParse(updated.CFLString, out cfl); + var vs = updated.PredictedPosition.VerticalSpeed; + int level = updated.PRL / 100; + + + + + char h1 = default; + + if (level == cfl || level == updated.RFL)//level + h1 = default; + + else if (cfl > level || vs > 300)//Issued or trending climb + h1 = '↑'; + + else if (cfl > 0 && cfl < level || vs < -300)//Issued or trending descent + h1 = '↓'; + + else if (level - updated.RFL / 100 >= 3)//deviating above + h1 = '+'; + + else if (level - updated.RFL / 100 <= -3)//deviating below + h1 = '-'; + + + altValues.AddOrUpdate(updated.Callsign, h1, (k, v) => h1); + + + + if (updated.ParsedRoute.Count > 1) + { + //calculate track from first route point to last (Departure point to destination point) + var rte = updated.ParsedRoute; + double trk = Conversions.CalculateTrack(rte.First().Intersection.LatLong, rte.Last().Intersection.LatLong); + bool east = trk >= 0 && trk < 180; + eastboundCallsigns.AddOrUpdate(updated.Callsign, east, (c, e) => east); + } + } + } + + + /// Could use the new position of the radar track or its change in state (cancelled, etc.) to do some processing. + public void OnRadarTrackUpdate(RDP.RadarTrack updated) + { + + } + + + private void HandleRadarFlagClick(CustomLabelItemMouseClickEventArgs e) + { + + } + private void HandleADSFlagClick(CustomLabelItemMouseClickEventArgs e) + { + + } + + private void HandleMNTFlagClick(CustomLabelItemMouseClickEventArgs e) + { + + } + /// vatSys calls this function when it encounters a custom label item (defined in Labels.xml) during the label rendering. + /// itemType is the value of the Type attribute in Labels.xml + /// If it's not our item being called (another plugins, for example), return null. + /// As a general rule, don't do processing in here as you'll slow down the ASD refresh. In the case of parsing a level to a string though, that's fine. + public CustomLabelItem GetCustomLabelItem(string itemType, Track track, FDP2.FDR flightDataRecord, RDP.RadarTrack radarTrack) + { + + if (flightDataRecord == null || track == null) + return null; + + + bool selectedCallsign = MMI.SelectedTrack?.GetFDR()?.Callsign == flightDataRecord.Callsign; + + + switch (itemType) + { + case LABEL_ITEM_SELECT_HORI: + + if (selectedCallsign) + { + return new CustomLabelItem() + + { + Border = BorderFlags.Top + }; + } + + else + { + return new CustomLabelItem() + + { + Border = BorderFlags.None + }; + } + + case LABEL_ITEM_SELECT_VERT: + + if (selectedCallsign) + { + return new CustomLabelItem() + { + Text = "", + Border = BorderFlags.Left + }; + } + + else + { + return new CustomLabelItem() + { + Text = "", + Border = BorderFlags.None + }; + } + + + + + + //case LABEL_ITEM_SCC: + // + // return new CustomLabelItem() + // { + // Text = pos //| ca | la | ra | rcf | dup | spd + // }; + + + case LABEL_ITEM_ANNOT_IND: + bool scratch = String.IsNullOrEmpty(flightDataRecord.LabelOpData); + + if (scratch) + { + return new CustomLabelItem() + { + Text = "◦" + }; + } + + else + { + return new CustomLabelItem() + { + Text = "&" + }; + } + + case LABEL_ITEM_RESTR: + + if (flightDataRecord.LabelOpData.Contains("AT") || flightDataRecord.LabelOpData.Contains("BY") || flightDataRecord.LabelOpData.Contains("CLEARED TO")) + + return new CustomLabelItem() + { + Text = "x" + }; + + return null; + + + case LABEL_ITEM_CLEARED_LEVEL: + + return new CustomLabelItem() + { + Text = (track.NewCFL && radarTrack.ReachedCFL) ? string.Empty : flightDataRecord.CFLString, + ForeColourIdentity = Colours.Identities.Custom, + CustomForeColour = !flightDataRecord.RVSM ? NonRVSM : Probe + }; + + + + case LABEL_ITEM_FILED_SPEED: + var mach = flightDataRecord.TAS / 581.0; + return new CustomLabelItem() + { + Text = "M" + Convert.ToDecimal(mach).ToString("F2").Replace(".", "") + //Text = "N" + flightDataRecord.TAS + }; + + case LABEL_ITEM_3DIGIT_GROUNDSPEED: + //get groundspeed value from either FDR or radarTrack if coupled + var gs = radarTrack == null ? flightDataRecord.PredictedPosition.Groundspeed : radarTrack.GroundSpeed; + return new CustomLabelItem() + { + Text = "N" + gs.ToString("000")//format as 3 digits (with leading zeros) + }; + + default: + return null; + } + } + + public CustomColour SelectASDTrackColour(Track track) + { + //only apply East/West colour to jurisdiction state + if (track.State != MMI.HMIStates.Jurisdiction) + return null; + + var fdr = track.GetFDR(); + //if track doesn't have an FDR coupled do nothing + if (fdr == null) + return null; + + //read our dictionary of stored bools (true means is easterly) and return the correct colour + return GetDirectionColour(fdr.Callsign); + } + + public CustomColour SelectGroundTrackColour(Track track) + { + return null; + } + + private CustomColour GetDirectionColour(string callsign) + { + if (eastboundCallsigns.TryGetValue(callsign, out bool east)) + { + if (east) + return EastboundColour; + else + return WestboundColour; + } + + return null; + } + } +} \ No newline at end of file From 3558919b176bf2882eedc5c734abb6dbef67f89c Mon Sep 17 00:00:00 2001 From: Milan K <34196765+CaptainTux@users.noreply.github.com> Date: Fri, 14 Jul 2023 22:02:38 +0200 Subject: [PATCH 17/76] implement feature --- AuroraLabelItemsPlugin.cs | 1059 +++++++++++++++++++------------------ 1 file changed, 546 insertions(+), 513 deletions(-) diff --git a/AuroraLabelItemsPlugin.cs b/AuroraLabelItemsPlugin.cs index 7d1c25d..a20a646 100644 --- a/AuroraLabelItemsPlugin.cs +++ b/AuroraLabelItemsPlugin.cs @@ -1,514 +1,547 @@ -using System; -using System.Collections.Concurrent; -using System.ComponentModel.Composition; //<--Need to add a reference to System.ComponentModel.Composition -using System.Text.RegularExpressions; -using vatsys; -using vatsys.Plugin; - - -//Note the reference to vatsys (set Copy Local to false) -----> - -namespace AuroraLabelItemsPlugin -{ - [Export(typeof(IPlugin))] - - public class AuroraLabelItemsPlugin : ILabelPlugin - { - - /// The name of the custom label item we've added to Labels - /// in the Profile - const string LABEL_ITEM_SELECT_HORI = "SELECT_HORI"; - const string LABEL_ITEM_SELECT_VERT = "SELECT_VERT"; - const string LABEL_ITEM_COMM_ICON = "AURORA_COMM_ICON"; //field a(2) - const string LABEL_ITEM_ADSB_CPDLC = "AURORA_ADSB_CPDLC"; //field c(4) - const string LABEL_ITEM_ADS_FLAGS = "AURORA_ADS_FLAGS"; //field c(4) - const string LABEL_ITEM_MNT_FLAGS = "AURORA_MNT_FLAGS"; //field c(4) - const string LABEL_ITEM_SCC = "AURORA_SCC"; //field c(5) - const string LABEL_ITEM_ANNOT_IND = "AURORA_ANNOT_IND"; //field e(1) - const string LABEL_ITEM_RESTR = "AURORA_RESTR"; //field f(1) - const string LABEL_ITEM_VMI = "AURORA_VMI"; //field h(1) - const string LABEL_ITEM_CLEARED_LEVEL = "AURORA_CLEARED_LEVEL"; //field i(7) - const string LABEL_ITEM_RADAR_IND = "AURORA_RADAR_IND"; //field k(1) - const string LABEL_ITEM_FILED_SPEED = "AURORA_FILEDSPEED"; //field m(4) - const string LABEL_ITEM_3DIGIT_GROUNDSPEED = "AURORA_GROUNDSPEED"; //field n(5) - readonly static CustomColour EastboundColour = new CustomColour(240, 255, 255); - readonly static CustomColour WestboundColour = new CustomColour(240, 231, 140); - readonly static CustomColour NonRVSM = new CustomColour(242, 133, 0); - readonly static CustomColour Probe = new CustomColour(0, 255, 0); - readonly static CustomColour NotCDA = new CustomColour(100, 0, 100); - readonly ConcurrentDictionary eastboundCallsigns = new ConcurrentDictionary(); - readonly ConcurrentDictionary adsbcpdlcValues = new ConcurrentDictionary(); - readonly ConcurrentDictionary adsflagValues = new ConcurrentDictionary(); - readonly ConcurrentDictionary mntflagValues = new ConcurrentDictionary(); - readonly ConcurrentDictionary altValues = new ConcurrentDictionary(); - readonly ConcurrentDictionary radartoggle = new ConcurrentDictionary(); - readonly ConcurrentDictionary adsflagtoggle = new ConcurrentDictionary(); - readonly ConcurrentDictionary mntflagtoggle = new ConcurrentDictionary(); - readonly ConcurrentDictionary downlink = new ConcurrentDictionary(); - - public AuroraLabelItemsPlugin() - { - Network.PrivateMessagesChanged += Network_PrivateMessagesChanged; - Network.RadioMessageAcknowledged += Network_RadioMessageAcknowledged; - } - - - private void Network_RadioMessageAcknowledged(object sender, RadioMessageEventArgs e) - { - throw new NotImplementedException(); - } - - private void Network_PrivateMessagesChanged(object sender, Network.GenericMessageEventArgs e) - { - bool downLink = e.Message.Sent == true; - - if (downLink) - { - downlink.TryRemove(e.Message.Address, out _); - } - else - { - downlink.TryAdd(e.Message.Address, 0); - } - - } - - /// Plugin Name - public string Name { get => "Aurora Label Items"; } - - /// This is called each time a flight data record is updated - /// Here we are updating the eastbound callsigns dictionary with each flight data record - /// When the FDR is updated we check if it still exists in the Flight Data Processor and remove from our dictionary if not. Otherwise we do some simple regex matching to find - /// the flight planned PBN category and store the character we want to display in the label in the dictionary. - public void OnFDRUpdate(FDP2.FDR updated) - { - if (FDP2.GetFDRIndex(updated.Callsign) == -1) - { - eastboundCallsigns.TryRemove(updated.Callsign, out _); - adsbcpdlcValues.TryRemove(updated.Callsign, out _); - adsflagValues.TryRemove(updated.Callsign, out _); - mntflagValues.TryRemove(updated.Callsign, out _); - altValues.TryRemove(updated.Callsign, out _); - radartoggle.TryRemove(updated.Callsign, out _); - adsflagtoggle.TryRemove(updated.Callsign, out _); - mntflagtoggle.TryRemove(updated.Callsign, out _); - downlink.TryRemove(updated.Callsign, out _); - } - else - { - Match pbn = Regex.Match(updated.Remarks, @"PBN\/\w+\s"); - bool rnp10 = Regex.IsMatch(pbn.Value, @"A1"); - bool rnp4 = Regex.IsMatch(pbn.Value, @"L1"); - bool cpdlc = Regex.IsMatch(updated.AircraftEquip, @"J5") || Regex.IsMatch(updated.AircraftEquip, @"J7"); - bool adsc = Regex.IsMatch(updated.AircraftSurvEquip, @"D1"); - int cfl; - bool isCfl = Int32.TryParse(updated.CFLString, out cfl); - var vs = updated.PredictedPosition.VerticalSpeed; - int level = updated.PRL / 100; - - char c1 = default; - - if (!updated.ADSB && cpdlc) - - c1 = '⧆'; - - else if (!updated.ADSB) - - c1 = '⎕'; - - else if (cpdlc) - - c1 = '*'; - - - adsbcpdlcValues.AddOrUpdate(updated.Callsign, c1, (k, v) => c1); - - char c2 = default; - - if (adsc & cpdlc & rnp4) - c2 = '3'; - - else if (adsc & cpdlc & rnp10) - c2 = 'D'; - - adsflagValues.AddOrUpdate(updated.Callsign, c2, (k, v) => c2); - - char c3 = default; - - if (AuroraStripItemsPlugin.AuroraStripItemsPlugin.MachNumberTech(updated.PerformanceData)) - c3 = 'M'; - - mntflagValues.AddOrUpdate(updated.Callsign, c3, (k, v) => c3); - - - char h1 = default; - - if (level == cfl || level == updated.RFL)//level - h1 = default; - - else if (cfl > level || vs > 300)//Issued or trending climb - h1 = '↑'; - - else if (cfl > 0 && cfl < level || vs < -300)//Issued or trending descent - h1 = '↓'; - - else if (level - updated.RFL / 100 >= 3)//deviating above - h1 = '+'; - - else if (level - updated.RFL / 100 <= -3)//deviating below - h1 = '-'; - - - altValues.AddOrUpdate(updated.Callsign, h1, (k, v) => h1); - - - - if (updated.ParsedRoute.Count > 1) - { - //calculate track from first route point to last (Departure point to destination point) - var rte = updated.ParsedRoute; - double trk = Conversions.CalculateTrack(rte.First().Intersection.LatLong, rte.Last().Intersection.LatLong); - bool east = trk >= 0 && trk < 180; - eastboundCallsigns.AddOrUpdate(updated.Callsign, east, (c, e) => east); - } - } - } - - - /// Could use the new position of the radar track or its change in state (cancelled, etc.) to do some processing. - public void OnRadarTrackUpdate(RDP.RadarTrack updated) - { - - } - - - private void HandleRadarFlagClick(CustomLabelItemMouseClickEventArgs e) - { - bool radarToggled = radartoggle.TryGetValue(e.Track.GetFDR().Callsign, out _); - - if (radarToggled) - { - radartoggle.TryRemove(e.Track.GetFDR().Callsign, out _); - } - else - { - radartoggle.TryAdd(e.Track.GetFDR().Callsign, 0); - } - e.Handled = true; - } - private void HandleADSFlagClick(CustomLabelItemMouseClickEventArgs e) - { - bool adsflagToggled = radartoggle.TryGetValue(e.Track.GetFDR().Callsign, out _); - - if (adsflagToggled) - { - adsflagtoggle.TryRemove(e.Track.GetFDR().Callsign, out _); - } - else - { - adsflagtoggle.TryAdd(e.Track.GetFDR().Callsign, 0); - } - e.Handled = true; - } - - private void HandleMNTFlagClick(CustomLabelItemMouseClickEventArgs e) - { - bool mntflagToggled = radartoggle.TryGetValue(e.Track.GetFDR().Callsign, out _); - - if (mntflagToggled) - { - mntflagtoggle.TryRemove(e.Track.GetFDR().Callsign, out _); - } - else - { - mntflagtoggle.TryAdd(e.Track.GetFDR().Callsign, 0); - } - e.Handled = true; - } - /// vatSys calls this function when it encounters a custom label item (defined in Labels.xml) during the label rendering. - /// itemType is the value of the Type attribute in Labels.xml - /// If it's not our item being called (another plugins, for example), return null. - /// As a general rule, don't do processing in here as you'll slow down the ASD refresh. In the case of parsing a level to a string though, that's fine. - public CustomLabelItem GetCustomLabelItem(string itemType, Track track, FDP2.FDR flightDataRecord, RDP.RadarTrack radarTrack) - { - - if (flightDataRecord == null || track == null) - return null; - - char c1; - adsbcpdlcValues.TryGetValue(flightDataRecord.Callsign, out c1); - char c2; - adsflagValues.TryGetValue(flightDataRecord.Callsign, out c2); - char c3; - mntflagValues.TryGetValue(flightDataRecord.Callsign, out c3); - char h1; - altValues.TryGetValue(flightDataRecord.Callsign, out h1); - - bool radarToggled = radartoggle.TryGetValue(flightDataRecord.Callsign, out _); - bool adsflagToggled = adsflagtoggle.TryGetValue(flightDataRecord.Callsign, out _); - bool mntflagToggled = mntflagtoggle.TryGetValue(flightDataRecord.Callsign, out _); - bool downLink = downlink.TryGetValue(flightDataRecord.Callsign, out _); - bool selectedCallsign = MMI.SelectedTrack?.GetFDR()?.Callsign == flightDataRecord.Callsign; - - - switch (itemType) - { - case LABEL_ITEM_SELECT_HORI: - - if (selectedCallsign) - { - return new CustomLabelItem() - - { - Border = BorderFlags.Top - }; - } - - else - { - return new CustomLabelItem() - - { - Border = BorderFlags.None - }; - } - - case LABEL_ITEM_SELECT_VERT: - - if (selectedCallsign) - { - return new CustomLabelItem() - { - Text = "", - Border = BorderFlags.Left - }; - } - - else - { - return new CustomLabelItem() - { - Text = "", - Border = BorderFlags.None - }; - } - - case LABEL_ITEM_COMM_ICON: - - if (downLink) - { - return new CustomLabelItem() - { - Text = "▼", - Border = BorderFlags.All - }; - } - else - { - return new CustomLabelItem() - { - Text = "⬜" - }; - } - case LABEL_ITEM_ADSB_CPDLC: - - bool useCustomForeColour = track.State == MMI.HMIStates.Preactive || track.State == MMI.HMIStates.Announced; - - if (useCustomForeColour) - { - return new CustomLabelItem() - { - ForeColourIdentity = Colours.Identities.Custom, - CustomForeColour = NotCDA, - Text = c1.ToString() - }; - } - else - { - return new CustomLabelItem() - { - Text = c1.ToString() - }; - } - - case LABEL_ITEM_ADS_FLAGS: - - if (adsflagToggled) - { - return new CustomLabelItem() - { - Text = c2.ToString(), - OnMouseClick = HandleADSFlagClick, - }; - } - - else - return new CustomLabelItem() - { - Text = "", - OnMouseClick = HandleADSFlagClick, - }; - - case LABEL_ITEM_MNT_FLAGS: - - if (mntflagToggled) - { - return new CustomLabelItem() - { - Text = c3.ToString(), - OnMouseClick = HandleMNTFlagClick, - }; - } - - else - return new CustomLabelItem() - { - Text = "", - OnMouseClick = HandleMNTFlagClick, - }; - - - //case LABEL_ITEM_SCC: - // - // return new CustomLabelItem() - // { - // Text = pos //| ca | la | ra | rcf | dup | spd - // }; - - - case LABEL_ITEM_ANNOT_IND: - bool scratch = String.IsNullOrEmpty(flightDataRecord.LabelOpData); - - if (scratch) - { - return new CustomLabelItem() - { - Text = "◦" - }; - } - - else - { - return new CustomLabelItem() - { - Text = "&" - }; - } - - case LABEL_ITEM_RESTR: - - if (flightDataRecord.LabelOpData.Contains ("AT") || flightDataRecord.LabelOpData.Contains("BY") || flightDataRecord.LabelOpData.Contains("CLEARED TO")) - - return new CustomLabelItem() - { - Text = "x" - }; - - return null; - - case LABEL_ITEM_VMI: - bool isNonRVSMOrNewCFL = !flightDataRecord.RVSM || track.NewCFL; - - if (isNonRVSMOrNewCFL) - { - return new CustomLabelItem() - { - Text = h1.ToString(), - ForeColourIdentity = Colours.Identities.Custom, - CustomForeColour = !flightDataRecord.RVSM ? NonRVSM : Probe - }; - } - else - { - return new CustomLabelItem() - { - Text = h1.ToString() - }; - } - - - case LABEL_ITEM_CLEARED_LEVEL: - - return new CustomLabelItem() - { - Text = (track.NewCFL && radarTrack.ReachedCFL) ? string.Empty : flightDataRecord.CFLString, - ForeColourIdentity = Colours.Identities.Custom, - CustomForeColour = !flightDataRecord.RVSM ? NonRVSM : Probe - }; - - case LABEL_ITEM_RADAR_IND: - - - if (radarToggled) - { - return new CustomLabelItem() - { - Text = "★", - OnMouseClick = HandleRadarFlagClick, - }; - } - - else - { - return new CustomLabelItem() - { - Text = "◦", - OnMouseClick = HandleRadarFlagClick, - }; - } - - case LABEL_ITEM_FILED_SPEED: - var mach = flightDataRecord.TAS / 581.0; - return new CustomLabelItem() - { - Text = "M" + Convert.ToDecimal(mach).ToString("F2").Replace(".","") - //Text = "N" + flightDataRecord.TAS - }; - - case LABEL_ITEM_3DIGIT_GROUNDSPEED: - //get groundspeed value from either FDR or radarTrack if coupled - var gs = radarTrack == null ? flightDataRecord.PredictedPosition.Groundspeed : radarTrack.GroundSpeed; - return new CustomLabelItem() - { - Text = "N" + gs.ToString("000")//format as 3 digits (with leading zeros) - }; - - default: - return null; - } - } - - public CustomColour SelectASDTrackColour(Track track) - { - //only apply East/West colour to jurisdiction state - if (track.State != MMI.HMIStates.Jurisdiction) - return null; - - var fdr = track.GetFDR(); - //if track doesn't have an FDR coupled do nothing - if (fdr == null) - return null; - - //read our dictionary of stored bools (true means is easterly) and return the correct colour - return GetDirectionColour(fdr.Callsign); - } - - public CustomColour SelectGroundTrackColour(Track track) - { - return null; - } - - private CustomColour GetDirectionColour(string callsign) - { - if (eastboundCallsigns.TryGetValue(callsign, out bool east)) - { - if (east) - return EastboundColour; - else - return WestboundColour; - } - - return null; - } - } +using System; +using System.Collections.Concurrent; +using System.ComponentModel.Composition; +using System.Linq; //<--Need to add a reference to System.ComponentModel.Composition +using System.Text.RegularExpressions; +using vatsys; +using vatsys.Plugin; + + +//Note the reference to vatsys (set Copy Local to false) -----> + +namespace AuroraLabelItemsPlugin +{ + [Export(typeof(IPlugin))] + + public class AuroraLabelItemsPlugin : ILabelPlugin + { + + /// The name of the custom label item we've added to Labels + /// in the Profile + const string LABEL_ITEM_SELECT_HORI = "SELECT_HORI"; + const string LABEL_ITEM_SELECT_VERT = "SELECT_VERT"; + const string LABEL_ITEM_COMM_ICON = "AURORA_COMM_ICON"; //field a(2) + const string LABEL_ITEM_ADSB_CPDLC = "AURORA_ADSB_CPDLC"; //field c(4) + const string LABEL_ITEM_ADS_FLAGS = "AURORA_ADS_FLAGS"; //field c(4) + const string LABEL_ITEM_MNT_FLAGS = "AURORA_MNT_FLAGS"; //field c(4) + const string LABEL_ITEM_SCC = "AURORA_SCC"; //field c(5) + const string LABEL_ITEM_ANNOT_IND = "AURORA_ANNOT_IND"; //field e(1) + const string LABEL_ITEM_RESTR = "AURORA_RESTR"; //field f(1) + const string LABEL_ITEM_VMI = "AURORA_VMI"; //field h(1) + const string LABEL_ITEM_CLEARED_LEVEL = "AURORA_CLEARED_LEVEL"; //field i(7) + const string LABEL_ITEM_RADAR_IND = "AURORA_RADAR_IND"; //field k(1) + const string LABEL_ITEM_FILED_SPEED = "AURORA_FILEDSPEED"; //field m(4) + const string LABEL_ITEM_3DIGIT_GROUNDSPEED = "AURORA_GROUNDSPEED"; //field n(5) + readonly static CustomColour EastboundColour = new CustomColour(240, 255, 255); + readonly static CustomColour WestboundColour = new CustomColour(240, 231, 140); + readonly static CustomColour NonRVSM = new CustomColour(242, 133, 0); + readonly static CustomColour Probe = new CustomColour(0, 255, 0); + readonly static CustomColour NotCDA = new CustomColour(100, 0, 100); + readonly ConcurrentDictionary eastboundCallsigns = new ConcurrentDictionary(); + readonly ConcurrentDictionary adsbcpdlcValues = new ConcurrentDictionary(); + readonly ConcurrentDictionary adsflagValues = new ConcurrentDictionary(); + readonly ConcurrentDictionary mntflagValues = new ConcurrentDictionary(); + readonly ConcurrentDictionary altValues = new ConcurrentDictionary(); + readonly ConcurrentDictionary radartoggle = new ConcurrentDictionary(); + readonly ConcurrentDictionary adsflagtoggle = new ConcurrentDictionary(); + readonly ConcurrentDictionary mntflagtoggle = new ConcurrentDictionary(); + readonly ConcurrentDictionary downlink = new ConcurrentDictionary(); + + public AuroraLabelItemsPlugin() + { + Network.PrivateMessagesChanged += Network_PrivateMessagesChanged; + Network.RadioMessageAcknowledged += Network_RadioMessageAcknowledged; + } + + + private void Network_RadioMessageAcknowledged(object sender, RadioMessageEventArgs e) + { + throw new NotImplementedException(); + } + + private void Network_PrivateMessagesChanged(object sender, Network.GenericMessageEventArgs e) + { + bool downLink = e.Message.Sent == true; + + if (downLink) + { + downlink.TryRemove(e.Message.Address, out _); + } + else + { + downlink.TryAdd(e.Message.Address, 0); + } + + } + + /// Plugin Name + public string Name { get => "Aurora Label Items"; } + + /// This is called each time a flight data record is updated + /// Here we are updating the eastbound callsigns dictionary with each flight data record + /// When the FDR is updated we check if it still exists in the Flight Data Processor and remove from our dictionary if not. Otherwise we do some simple regex matching to find + /// the flight planned PBN category and store the character we want to display in the label in the dictionary. + public void OnFDRUpdate(FDP2.FDR updated) + { + AutoAssume(updated); + // autoDrop(updated); + if (FDP2.GetFDRIndex(updated.Callsign) == -1) + { + eastboundCallsigns.TryRemove(updated.Callsign, out _); + adsbcpdlcValues.TryRemove(updated.Callsign, out _); + adsflagValues.TryRemove(updated.Callsign, out _); + mntflagValues.TryRemove(updated.Callsign, out _); + altValues.TryRemove(updated.Callsign, out _); + radartoggle.TryRemove(updated.Callsign, out _); + adsflagtoggle.TryRemove(updated.Callsign, out _); + mntflagtoggle.TryRemove(updated.Callsign, out _); + downlink.TryRemove(updated.Callsign, out _); + } + else + { + Match pbn = Regex.Match(updated.Remarks, @"PBN\/\w+\s"); + bool rnp10 = Regex.IsMatch(pbn.Value, @"A1"); + bool rnp4 = Regex.IsMatch(pbn.Value, @"L1"); + bool cpdlc = Regex.IsMatch(updated.AircraftEquip, @"J5") || Regex.IsMatch(updated.AircraftEquip, @"J7"); + bool adsc = Regex.IsMatch(updated.AircraftSurvEquip, @"D1"); + int cfl; + bool isCfl = Int32.TryParse(updated.CFLString, out cfl); + var vs = updated.PredictedPosition.VerticalSpeed; + int level = updated.PRL / 100; + + char c1 = default; + + if (!updated.ADSB && cpdlc) + + c1 = '⧆'; + + else if (!updated.ADSB) + + c1 = '⎕'; + + else if (cpdlc) + + c1 = '*'; + + + adsbcpdlcValues.AddOrUpdate(updated.Callsign, c1, (k, v) => c1); + + char c2 = default; + + if (adsc & cpdlc & rnp4) + c2 = '3'; + + else if (adsc & cpdlc & rnp10) + c2 = 'D'; + + adsflagValues.AddOrUpdate(updated.Callsign, c2, (k, v) => c2); + + char c3 = default; + + if (AuroraStripItemsPlugin.AuroraStripItemsPlugin.MachNumberTech(updated.PerformanceData)) + c3 = 'M'; + + mntflagValues.AddOrUpdate(updated.Callsign, c3, (k, v) => c3); + + + char h1 = default; + + if (level == cfl || level == updated.RFL)//level + h1 = default; + + else if (cfl > level || vs > 300)//Issued or trending climb + h1 = '↑'; + + else if (cfl > 0 && cfl < level || vs < -300)//Issued or trending descent + h1 = '↓'; + + else if (level - updated.RFL / 100 >= 3)//deviating above + h1 = '+'; + + else if (level - updated.RFL / 100 <= -3)//deviating below + h1 = '-'; + + + altValues.AddOrUpdate(updated.Callsign, h1, (k, v) => h1); + + + + if (updated.ParsedRoute.Count > 1) + { + //calculate track from first route point to last (Departure point to destination point) + var rte = updated.ParsedRoute; + double trk = Conversions.CalculateTrack(rte.First().Intersection.LatLong, rte.Last().Intersection.LatLong); + bool east = trk >= 0 && trk < 180; + eastboundCallsigns.AddOrUpdate(updated.Callsign, east, (c, e) => east); + } + } + } + + public void ProbeConflict(RDP.RadarTrack rt) + { + // TODO: implement + } + + public void AutoAssume(RDP.RadarTrack rt) + { + var fdr = rt.CoupledFDR; + AutoAssume(fdr); + } + + public static void AutoAssume(FDP2.FDR fdr) + { + if (fdr.ControllingSector == null && MMI.IsMySectorConcerned(fdr)) + { + FDP2.AcceptJurisdiction(fdr, MMI.SectorsControlled.First()); + FDP2.HandoffFirst(fdr); + } + } + + public void AutoDrop(FDP2.FDR fdr) + { + if (fdr.IsTrackedByMe && MMI.SectorsControlled.ToList() + .TrueForAll(s => !s.IsInSector(fdr.GetLocation(), fdr.PRL))) + { + FDP2.HandoffToNone(fdr); + } + } + + + /// Could use the new position of the radar track or its change in state (cancelled, etc.) to do some processing. + public void OnRadarTrackUpdate(RDP.RadarTrack updated) + { + AutoAssume(updated); + ProbeConflict(updated); + } + + + private void HandleRadarFlagClick(CustomLabelItemMouseClickEventArgs e) + { + bool radarToggled = radartoggle.TryGetValue(e.Track.GetFDR().Callsign, out _); + + if (radarToggled) + { + radartoggle.TryRemove(e.Track.GetFDR().Callsign, out _); + } + else + { + radartoggle.TryAdd(e.Track.GetFDR().Callsign, 0); + } + e.Handled = true; + } + private void HandleADSFlagClick(CustomLabelItemMouseClickEventArgs e) + { + bool adsflagToggled = radartoggle.TryGetValue(e.Track.GetFDR().Callsign, out _); + + if (adsflagToggled) + { + adsflagtoggle.TryRemove(e.Track.GetFDR().Callsign, out _); + } + else + { + adsflagtoggle.TryAdd(e.Track.GetFDR().Callsign, 0); + } + e.Handled = true; + } + + private void HandleMNTFlagClick(CustomLabelItemMouseClickEventArgs e) + { + bool mntflagToggled = radartoggle.TryGetValue(e.Track.GetFDR().Callsign, out _); + + if (mntflagToggled) + { + mntflagtoggle.TryRemove(e.Track.GetFDR().Callsign, out _); + } + else + { + mntflagtoggle.TryAdd(e.Track.GetFDR().Callsign, 0); + } + e.Handled = true; + } + /// vatSys calls this function when it encounters a custom label item (defined in Labels.xml) during the label rendering. + /// itemType is the value of the Type attribute in Labels.xml + /// If it's not our item being called (another plugins, for example), return null. + /// As a general rule, don't do processing in here as you'll slow down the ASD refresh. In the case of parsing a level to a string though, that's fine. + public CustomLabelItem GetCustomLabelItem(string itemType, Track track, FDP2.FDR flightDataRecord, RDP.RadarTrack radarTrack) + { + + if (flightDataRecord == null || track == null) + return null; + + char c1; + adsbcpdlcValues.TryGetValue(flightDataRecord.Callsign, out c1); + char c2; + adsflagValues.TryGetValue(flightDataRecord.Callsign, out c2); + char c3; + mntflagValues.TryGetValue(flightDataRecord.Callsign, out c3); + char h1; + altValues.TryGetValue(flightDataRecord.Callsign, out h1); + + bool radarToggled = radartoggle.TryGetValue(flightDataRecord.Callsign, out _); + bool adsflagToggled = adsflagtoggle.TryGetValue(flightDataRecord.Callsign, out _); + bool mntflagToggled = mntflagtoggle.TryGetValue(flightDataRecord.Callsign, out _); + bool downLink = downlink.TryGetValue(flightDataRecord.Callsign, out _); + bool selectedCallsign = MMI.SelectedTrack?.GetFDR()?.Callsign == flightDataRecord.Callsign; + + + switch (itemType) + { + case LABEL_ITEM_SELECT_HORI: + + if (selectedCallsign) + { + return new CustomLabelItem() + + { + Border = BorderFlags.Top + }; + } + + else + { + return new CustomLabelItem() + + { + Border = BorderFlags.None + }; + } + + case LABEL_ITEM_SELECT_VERT: + + if (selectedCallsign) + { + return new CustomLabelItem() + { + Text = "", + Border = BorderFlags.Left + }; + } + + else + { + return new CustomLabelItem() + { + Text = "", + Border = BorderFlags.None + }; + } + + case LABEL_ITEM_COMM_ICON: + + if (downLink) + { + return new CustomLabelItem() + { + Text = "▼", + Border = BorderFlags.All + }; + } + else + { + return new CustomLabelItem() + { + Text = "⬜" + }; + } + case LABEL_ITEM_ADSB_CPDLC: + + bool useCustomForeColour = track.State == MMI.HMIStates.Preactive || track.State == MMI.HMIStates.Announced; + + if (useCustomForeColour) + { + return new CustomLabelItem() + { + ForeColourIdentity = Colours.Identities.Custom, + CustomForeColour = NotCDA, + Text = c1.ToString() + }; + } + else + { + return new CustomLabelItem() + { + Text = c1.ToString() + }; + } + + case LABEL_ITEM_ADS_FLAGS: + + if (adsflagToggled) + { + return new CustomLabelItem() + { + Text = c2.ToString(), + OnMouseClick = HandleADSFlagClick, + }; + } + + else + return new CustomLabelItem() + { + Text = "", + OnMouseClick = HandleADSFlagClick, + }; + + case LABEL_ITEM_MNT_FLAGS: + + if (mntflagToggled) + { + return new CustomLabelItem() + { + Text = c3.ToString(), + OnMouseClick = HandleMNTFlagClick, + }; + } + + else + return new CustomLabelItem() + { + Text = "", + OnMouseClick = HandleMNTFlagClick, + }; + + + //case LABEL_ITEM_SCC: + // + // return new CustomLabelItem() + // { + // Text = pos //| ca | la | ra | rcf | dup | spd + // }; + + + case LABEL_ITEM_ANNOT_IND: + bool scratch = String.IsNullOrEmpty(flightDataRecord.LabelOpData); + + if (scratch) + { + return new CustomLabelItem() + { + Text = "◦" + }; + } + + else + { + return new CustomLabelItem() + { + Text = "&" + }; + } + + case LABEL_ITEM_RESTR: + + if (flightDataRecord.LabelOpData.Contains ("AT") || flightDataRecord.LabelOpData.Contains("BY") || flightDataRecord.LabelOpData.Contains("CLEARED TO")) + + return new CustomLabelItem() + { + Text = "x" + }; + + return null; + + case LABEL_ITEM_VMI: + bool isNonRVSMOrNewCFL = !flightDataRecord.RVSM || track.NewCFL; + + if (isNonRVSMOrNewCFL) + { + return new CustomLabelItem() + { + Text = h1.ToString(), + ForeColourIdentity = Colours.Identities.Custom, + CustomForeColour = !flightDataRecord.RVSM ? NonRVSM : Probe + }; + } + else + { + return new CustomLabelItem() + { + Text = h1.ToString() + }; + } + + + case LABEL_ITEM_CLEARED_LEVEL: + + return new CustomLabelItem() + { + Text = (track.NewCFL && radarTrack.ReachedCFL) ? string.Empty : flightDataRecord.CFLString, + ForeColourIdentity = Colours.Identities.Custom, + CustomForeColour = !flightDataRecord.RVSM ? NonRVSM : Probe + }; + + case LABEL_ITEM_RADAR_IND: + + + if (radarToggled) + { + return new CustomLabelItem() + { + Text = "★", + OnMouseClick = HandleRadarFlagClick, + }; + } + + else + { + return new CustomLabelItem() + { + Text = "◦", + OnMouseClick = HandleRadarFlagClick, + }; + } + + case LABEL_ITEM_FILED_SPEED: + var mach = flightDataRecord.TAS / 581.0; + return new CustomLabelItem() + { + Text = "M" + Convert.ToDecimal(mach).ToString("F2").Replace(".","") + //Text = "N" + flightDataRecord.TAS + }; + + case LABEL_ITEM_3DIGIT_GROUNDSPEED: + //get groundspeed value from either FDR or radarTrack if coupled + var gs = radarTrack == null ? flightDataRecord.PredictedPosition.Groundspeed : radarTrack.GroundSpeed; + return new CustomLabelItem() + { + Text = "N" + gs.ToString("000")//format as 3 digits (with leading zeros) + }; + + default: + return null; + } + } + + public CustomColour SelectASDTrackColour(Track track) + { + //only apply East/West colour to jurisdiction state + if (track.State != MMI.HMIStates.Jurisdiction) + return null; + + var fdr = track.GetFDR(); + //if track doesn't have an FDR coupled do nothing + if (fdr == null) + return null; + + //read our dictionary of stored bools (true means is easterly) and return the correct colour + return GetDirectionColour(fdr.Callsign); + } + + public CustomColour SelectGroundTrackColour(Track track) + { + return null; + } + + private CustomColour GetDirectionColour(string callsign) + { + if (eastboundCallsigns.TryGetValue(callsign, out bool east)) + { + if (east) + return EastboundColour; + else + return WestboundColour; + } + + return null; + } + } } \ No newline at end of file From c5b53a0f3380339fcf3723627a78523864213ede Mon Sep 17 00:00:00 2001 From: Dominic Nguyen Date: Thu, 20 Jul 2023 12:50:55 -0700 Subject: [PATCH 18/76] Add files via upload Added FP null checks --- AuroraLabelItemsPlugin.cs | 1119 +++++++++++++++++++------------------ 1 file changed, 573 insertions(+), 546 deletions(-) diff --git a/AuroraLabelItemsPlugin.cs b/AuroraLabelItemsPlugin.cs index a20a646..8cbd79a 100644 --- a/AuroraLabelItemsPlugin.cs +++ b/AuroraLabelItemsPlugin.cs @@ -1,547 +1,574 @@ -using System; -using System.Collections.Concurrent; -using System.ComponentModel.Composition; -using System.Linq; //<--Need to add a reference to System.ComponentModel.Composition -using System.Text.RegularExpressions; -using vatsys; -using vatsys.Plugin; - - -//Note the reference to vatsys (set Copy Local to false) -----> - -namespace AuroraLabelItemsPlugin -{ - [Export(typeof(IPlugin))] - - public class AuroraLabelItemsPlugin : ILabelPlugin - { - - /// The name of the custom label item we've added to Labels - /// in the Profile - const string LABEL_ITEM_SELECT_HORI = "SELECT_HORI"; - const string LABEL_ITEM_SELECT_VERT = "SELECT_VERT"; - const string LABEL_ITEM_COMM_ICON = "AURORA_COMM_ICON"; //field a(2) - const string LABEL_ITEM_ADSB_CPDLC = "AURORA_ADSB_CPDLC"; //field c(4) - const string LABEL_ITEM_ADS_FLAGS = "AURORA_ADS_FLAGS"; //field c(4) - const string LABEL_ITEM_MNT_FLAGS = "AURORA_MNT_FLAGS"; //field c(4) - const string LABEL_ITEM_SCC = "AURORA_SCC"; //field c(5) - const string LABEL_ITEM_ANNOT_IND = "AURORA_ANNOT_IND"; //field e(1) - const string LABEL_ITEM_RESTR = "AURORA_RESTR"; //field f(1) - const string LABEL_ITEM_VMI = "AURORA_VMI"; //field h(1) - const string LABEL_ITEM_CLEARED_LEVEL = "AURORA_CLEARED_LEVEL"; //field i(7) - const string LABEL_ITEM_RADAR_IND = "AURORA_RADAR_IND"; //field k(1) - const string LABEL_ITEM_FILED_SPEED = "AURORA_FILEDSPEED"; //field m(4) - const string LABEL_ITEM_3DIGIT_GROUNDSPEED = "AURORA_GROUNDSPEED"; //field n(5) - readonly static CustomColour EastboundColour = new CustomColour(240, 255, 255); - readonly static CustomColour WestboundColour = new CustomColour(240, 231, 140); - readonly static CustomColour NonRVSM = new CustomColour(242, 133, 0); - readonly static CustomColour Probe = new CustomColour(0, 255, 0); - readonly static CustomColour NotCDA = new CustomColour(100, 0, 100); - readonly ConcurrentDictionary eastboundCallsigns = new ConcurrentDictionary(); - readonly ConcurrentDictionary adsbcpdlcValues = new ConcurrentDictionary(); - readonly ConcurrentDictionary adsflagValues = new ConcurrentDictionary(); - readonly ConcurrentDictionary mntflagValues = new ConcurrentDictionary(); - readonly ConcurrentDictionary altValues = new ConcurrentDictionary(); - readonly ConcurrentDictionary radartoggle = new ConcurrentDictionary(); - readonly ConcurrentDictionary adsflagtoggle = new ConcurrentDictionary(); - readonly ConcurrentDictionary mntflagtoggle = new ConcurrentDictionary(); - readonly ConcurrentDictionary downlink = new ConcurrentDictionary(); - - public AuroraLabelItemsPlugin() - { - Network.PrivateMessagesChanged += Network_PrivateMessagesChanged; - Network.RadioMessageAcknowledged += Network_RadioMessageAcknowledged; - } - - - private void Network_RadioMessageAcknowledged(object sender, RadioMessageEventArgs e) - { - throw new NotImplementedException(); - } - - private void Network_PrivateMessagesChanged(object sender, Network.GenericMessageEventArgs e) - { - bool downLink = e.Message.Sent == true; - - if (downLink) - { - downlink.TryRemove(e.Message.Address, out _); - } - else - { - downlink.TryAdd(e.Message.Address, 0); - } - - } - - /// Plugin Name - public string Name { get => "Aurora Label Items"; } - - /// This is called each time a flight data record is updated - /// Here we are updating the eastbound callsigns dictionary with each flight data record - /// When the FDR is updated we check if it still exists in the Flight Data Processor and remove from our dictionary if not. Otherwise we do some simple regex matching to find - /// the flight planned PBN category and store the character we want to display in the label in the dictionary. - public void OnFDRUpdate(FDP2.FDR updated) - { - AutoAssume(updated); - // autoDrop(updated); - if (FDP2.GetFDRIndex(updated.Callsign) == -1) - { - eastboundCallsigns.TryRemove(updated.Callsign, out _); - adsbcpdlcValues.TryRemove(updated.Callsign, out _); - adsflagValues.TryRemove(updated.Callsign, out _); - mntflagValues.TryRemove(updated.Callsign, out _); - altValues.TryRemove(updated.Callsign, out _); - radartoggle.TryRemove(updated.Callsign, out _); - adsflagtoggle.TryRemove(updated.Callsign, out _); - mntflagtoggle.TryRemove(updated.Callsign, out _); - downlink.TryRemove(updated.Callsign, out _); - } - else - { - Match pbn = Regex.Match(updated.Remarks, @"PBN\/\w+\s"); - bool rnp10 = Regex.IsMatch(pbn.Value, @"A1"); - bool rnp4 = Regex.IsMatch(pbn.Value, @"L1"); - bool cpdlc = Regex.IsMatch(updated.AircraftEquip, @"J5") || Regex.IsMatch(updated.AircraftEquip, @"J7"); - bool adsc = Regex.IsMatch(updated.AircraftSurvEquip, @"D1"); - int cfl; - bool isCfl = Int32.TryParse(updated.CFLString, out cfl); - var vs = updated.PredictedPosition.VerticalSpeed; - int level = updated.PRL / 100; - - char c1 = default; - - if (!updated.ADSB && cpdlc) - - c1 = '⧆'; - - else if (!updated.ADSB) - - c1 = '⎕'; - - else if (cpdlc) - - c1 = '*'; - - - adsbcpdlcValues.AddOrUpdate(updated.Callsign, c1, (k, v) => c1); - - char c2 = default; - - if (adsc & cpdlc & rnp4) - c2 = '3'; - - else if (adsc & cpdlc & rnp10) - c2 = 'D'; - - adsflagValues.AddOrUpdate(updated.Callsign, c2, (k, v) => c2); - - char c3 = default; - - if (AuroraStripItemsPlugin.AuroraStripItemsPlugin.MachNumberTech(updated.PerformanceData)) - c3 = 'M'; - - mntflagValues.AddOrUpdate(updated.Callsign, c3, (k, v) => c3); - - - char h1 = default; - - if (level == cfl || level == updated.RFL)//level - h1 = default; - - else if (cfl > level || vs > 300)//Issued or trending climb - h1 = '↑'; - - else if (cfl > 0 && cfl < level || vs < -300)//Issued or trending descent - h1 = '↓'; - - else if (level - updated.RFL / 100 >= 3)//deviating above - h1 = '+'; - - else if (level - updated.RFL / 100 <= -3)//deviating below - h1 = '-'; - - - altValues.AddOrUpdate(updated.Callsign, h1, (k, v) => h1); - - - - if (updated.ParsedRoute.Count > 1) - { - //calculate track from first route point to last (Departure point to destination point) - var rte = updated.ParsedRoute; - double trk = Conversions.CalculateTrack(rte.First().Intersection.LatLong, rte.Last().Intersection.LatLong); - bool east = trk >= 0 && trk < 180; - eastboundCallsigns.AddOrUpdate(updated.Callsign, east, (c, e) => east); - } - } - } - - public void ProbeConflict(RDP.RadarTrack rt) - { - // TODO: implement - } - - public void AutoAssume(RDP.RadarTrack rt) - { - var fdr = rt.CoupledFDR; - AutoAssume(fdr); - } - - public static void AutoAssume(FDP2.FDR fdr) - { - if (fdr.ControllingSector == null && MMI.IsMySectorConcerned(fdr)) - { - FDP2.AcceptJurisdiction(fdr, MMI.SectorsControlled.First()); - FDP2.HandoffFirst(fdr); - } - } - - public void AutoDrop(FDP2.FDR fdr) - { - if (fdr.IsTrackedByMe && MMI.SectorsControlled.ToList() - .TrueForAll(s => !s.IsInSector(fdr.GetLocation(), fdr.PRL))) - { - FDP2.HandoffToNone(fdr); - } - } - - - /// Could use the new position of the radar track or its change in state (cancelled, etc.) to do some processing. - public void OnRadarTrackUpdate(RDP.RadarTrack updated) - { - AutoAssume(updated); - ProbeConflict(updated); - } - - - private void HandleRadarFlagClick(CustomLabelItemMouseClickEventArgs e) - { - bool radarToggled = radartoggle.TryGetValue(e.Track.GetFDR().Callsign, out _); - - if (radarToggled) - { - radartoggle.TryRemove(e.Track.GetFDR().Callsign, out _); - } - else - { - radartoggle.TryAdd(e.Track.GetFDR().Callsign, 0); - } - e.Handled = true; - } - private void HandleADSFlagClick(CustomLabelItemMouseClickEventArgs e) - { - bool adsflagToggled = radartoggle.TryGetValue(e.Track.GetFDR().Callsign, out _); - - if (adsflagToggled) - { - adsflagtoggle.TryRemove(e.Track.GetFDR().Callsign, out _); - } - else - { - adsflagtoggle.TryAdd(e.Track.GetFDR().Callsign, 0); - } - e.Handled = true; - } - - private void HandleMNTFlagClick(CustomLabelItemMouseClickEventArgs e) - { - bool mntflagToggled = radartoggle.TryGetValue(e.Track.GetFDR().Callsign, out _); - - if (mntflagToggled) - { - mntflagtoggle.TryRemove(e.Track.GetFDR().Callsign, out _); - } - else - { - mntflagtoggle.TryAdd(e.Track.GetFDR().Callsign, 0); - } - e.Handled = true; - } - /// vatSys calls this function when it encounters a custom label item (defined in Labels.xml) during the label rendering. - /// itemType is the value of the Type attribute in Labels.xml - /// If it's not our item being called (another plugins, for example), return null. - /// As a general rule, don't do processing in here as you'll slow down the ASD refresh. In the case of parsing a level to a string though, that's fine. - public CustomLabelItem GetCustomLabelItem(string itemType, Track track, FDP2.FDR flightDataRecord, RDP.RadarTrack radarTrack) - { - - if (flightDataRecord == null || track == null) - return null; - - char c1; - adsbcpdlcValues.TryGetValue(flightDataRecord.Callsign, out c1); - char c2; - adsflagValues.TryGetValue(flightDataRecord.Callsign, out c2); - char c3; - mntflagValues.TryGetValue(flightDataRecord.Callsign, out c3); - char h1; - altValues.TryGetValue(flightDataRecord.Callsign, out h1); - - bool radarToggled = radartoggle.TryGetValue(flightDataRecord.Callsign, out _); - bool adsflagToggled = adsflagtoggle.TryGetValue(flightDataRecord.Callsign, out _); - bool mntflagToggled = mntflagtoggle.TryGetValue(flightDataRecord.Callsign, out _); - bool downLink = downlink.TryGetValue(flightDataRecord.Callsign, out _); - bool selectedCallsign = MMI.SelectedTrack?.GetFDR()?.Callsign == flightDataRecord.Callsign; - - - switch (itemType) - { - case LABEL_ITEM_SELECT_HORI: - - if (selectedCallsign) - { - return new CustomLabelItem() - - { - Border = BorderFlags.Top - }; - } - - else - { - return new CustomLabelItem() - - { - Border = BorderFlags.None - }; - } - - case LABEL_ITEM_SELECT_VERT: - - if (selectedCallsign) - { - return new CustomLabelItem() - { - Text = "", - Border = BorderFlags.Left - }; - } - - else - { - return new CustomLabelItem() - { - Text = "", - Border = BorderFlags.None - }; - } - - case LABEL_ITEM_COMM_ICON: - - if (downLink) - { - return new CustomLabelItem() - { - Text = "▼", - Border = BorderFlags.All - }; - } - else - { - return new CustomLabelItem() - { - Text = "⬜" - }; - } - case LABEL_ITEM_ADSB_CPDLC: - - bool useCustomForeColour = track.State == MMI.HMIStates.Preactive || track.State == MMI.HMIStates.Announced; - - if (useCustomForeColour) - { - return new CustomLabelItem() - { - ForeColourIdentity = Colours.Identities.Custom, - CustomForeColour = NotCDA, - Text = c1.ToString() - }; - } - else - { - return new CustomLabelItem() - { - Text = c1.ToString() - }; - } - - case LABEL_ITEM_ADS_FLAGS: - - if (adsflagToggled) - { - return new CustomLabelItem() - { - Text = c2.ToString(), - OnMouseClick = HandleADSFlagClick, - }; - } - - else - return new CustomLabelItem() - { - Text = "", - OnMouseClick = HandleADSFlagClick, - }; - - case LABEL_ITEM_MNT_FLAGS: - - if (mntflagToggled) - { - return new CustomLabelItem() - { - Text = c3.ToString(), - OnMouseClick = HandleMNTFlagClick, - }; - } - - else - return new CustomLabelItem() - { - Text = "", - OnMouseClick = HandleMNTFlagClick, - }; - - - //case LABEL_ITEM_SCC: - // - // return new CustomLabelItem() - // { - // Text = pos //| ca | la | ra | rcf | dup | spd - // }; - - - case LABEL_ITEM_ANNOT_IND: - bool scratch = String.IsNullOrEmpty(flightDataRecord.LabelOpData); - - if (scratch) - { - return new CustomLabelItem() - { - Text = "◦" - }; - } - - else - { - return new CustomLabelItem() - { - Text = "&" - }; - } - - case LABEL_ITEM_RESTR: - - if (flightDataRecord.LabelOpData.Contains ("AT") || flightDataRecord.LabelOpData.Contains("BY") || flightDataRecord.LabelOpData.Contains("CLEARED TO")) - - return new CustomLabelItem() - { - Text = "x" - }; - - return null; - - case LABEL_ITEM_VMI: - bool isNonRVSMOrNewCFL = !flightDataRecord.RVSM || track.NewCFL; - - if (isNonRVSMOrNewCFL) - { - return new CustomLabelItem() - { - Text = h1.ToString(), - ForeColourIdentity = Colours.Identities.Custom, - CustomForeColour = !flightDataRecord.RVSM ? NonRVSM : Probe - }; - } - else - { - return new CustomLabelItem() - { - Text = h1.ToString() - }; - } - - - case LABEL_ITEM_CLEARED_LEVEL: - - return new CustomLabelItem() - { - Text = (track.NewCFL && radarTrack.ReachedCFL) ? string.Empty : flightDataRecord.CFLString, - ForeColourIdentity = Colours.Identities.Custom, - CustomForeColour = !flightDataRecord.RVSM ? NonRVSM : Probe - }; - - case LABEL_ITEM_RADAR_IND: - - - if (radarToggled) - { - return new CustomLabelItem() - { - Text = "★", - OnMouseClick = HandleRadarFlagClick, - }; - } - - else - { - return new CustomLabelItem() - { - Text = "◦", - OnMouseClick = HandleRadarFlagClick, - }; - } - - case LABEL_ITEM_FILED_SPEED: - var mach = flightDataRecord.TAS / 581.0; - return new CustomLabelItem() - { - Text = "M" + Convert.ToDecimal(mach).ToString("F2").Replace(".","") - //Text = "N" + flightDataRecord.TAS - }; - - case LABEL_ITEM_3DIGIT_GROUNDSPEED: - //get groundspeed value from either FDR or radarTrack if coupled - var gs = radarTrack == null ? flightDataRecord.PredictedPosition.Groundspeed : radarTrack.GroundSpeed; - return new CustomLabelItem() - { - Text = "N" + gs.ToString("000")//format as 3 digits (with leading zeros) - }; - - default: - return null; - } - } - - public CustomColour SelectASDTrackColour(Track track) - { - //only apply East/West colour to jurisdiction state - if (track.State != MMI.HMIStates.Jurisdiction) - return null; - - var fdr = track.GetFDR(); - //if track doesn't have an FDR coupled do nothing - if (fdr == null) - return null; - - //read our dictionary of stored bools (true means is easterly) and return the correct colour - return GetDirectionColour(fdr.Callsign); - } - - public CustomColour SelectGroundTrackColour(Track track) - { - return null; - } - - private CustomColour GetDirectionColour(string callsign) - { - if (eastboundCallsigns.TryGetValue(callsign, out bool east)) - { - if (east) - return EastboundColour; - else - return WestboundColour; - } - - return null; - } - } +using System; +using System.Collections.Concurrent; +using System.ComponentModel.Composition; +using System.Linq; //<--Need to add a reference to System.ComponentModel.Composition +using System.Text.RegularExpressions; +using vatsys; +using vatsys.Plugin; + + +//Note the reference to vatsys (set Copy Local to false) -----> + +namespace AuroraLabelItemsPlugin +{ + [Export(typeof(IPlugin))] + + public class AuroraLabelItemsPlugin : ILabelPlugin + { + + /// The name of the custom label item we've added to Labels + /// in the Profile + const string LABEL_ITEM_SELECT_HORI = "SELECT_HORI"; + const string LABEL_ITEM_SELECT_VERT = "SELECT_VERT"; + const string LABEL_ITEM_COMM_ICON = "AURORA_COMM_ICON"; //field a(2) + const string LABEL_ITEM_ADSB_CPDLC = "AURORA_ADSB_CPDLC"; //field c(4) + const string LABEL_ITEM_ADS_FLAGS = "AURORA_ADS_FLAGS"; //field c(4) + const string LABEL_ITEM_MNT_FLAGS = "AURORA_MNT_FLAGS"; //field c(4) + const string LABEL_ITEM_SCC = "AURORA_SCC"; //field c(5) + const string LABEL_ITEM_ANNOT_IND = "AURORA_ANNOT_IND"; //field e(1) + const string LABEL_ITEM_RESTR = "AURORA_RESTR"; //field f(1) + const string LABEL_ITEM_VMI = "AURORA_VMI"; //field h(1) + const string LABEL_ITEM_CLEARED_LEVEL = "AURORA_CLEARED_LEVEL"; //field i(7) + const string LABEL_ITEM_RADAR_IND = "AURORA_RADAR_IND"; //field k(1) + const string LABEL_ITEM_FILED_SPEED = "AURORA_FILEDSPEED"; //field m(4) + const string LABEL_ITEM_3DIGIT_GROUNDSPEED = "AURORA_GROUNDSPEED"; //field n(5) + readonly static CustomColour EastboundColour = new CustomColour(240, 255, 255); + readonly static CustomColour WestboundColour = new CustomColour(240, 231, 140); + readonly static CustomColour NonRVSM = new CustomColour(242, 133, 0); + readonly static CustomColour Probe = new CustomColour(0, 255, 0); + readonly static CustomColour NotCDA = new CustomColour(100, 0, 100); + readonly ConcurrentDictionary eastboundCallsigns = new ConcurrentDictionary(); + readonly ConcurrentDictionary adsbcpdlcValues = new ConcurrentDictionary(); + readonly ConcurrentDictionary adsflagValues = new ConcurrentDictionary(); + readonly ConcurrentDictionary mntflagValues = new ConcurrentDictionary(); + readonly ConcurrentDictionary altValues = new ConcurrentDictionary(); + readonly ConcurrentDictionary radartoggle = new ConcurrentDictionary(); + readonly ConcurrentDictionary adsflagtoggle = new ConcurrentDictionary(); + readonly ConcurrentDictionary mntflagtoggle = new ConcurrentDictionary(); + readonly ConcurrentDictionary downlink = new ConcurrentDictionary(); + readonly ConcurrentDictionary conflicts = new ConcurrentDictionary(); + + public AuroraLabelItemsPlugin() + { + Network.PrivateMessagesChanged += Network_PrivateMessagesChanged; + Network.RadioMessageAcknowledged += Network_RadioMessageAcknowledged; + } + + + private void Network_RadioMessageAcknowledged(object sender, RadioMessageEventArgs e) + { + throw new NotImplementedException(); + } + + private void Network_PrivateMessagesChanged(object sender, Network.GenericMessageEventArgs e) + { + bool downLink = e.Message.Sent == true; + + if (downLink) + { + downlink.TryRemove(e.Message.Address, out _); + } + else + { + downlink.TryAdd(e.Message.Address, 0); + } + } + + /// Plugin Name + public string Name { get => "Aurora Label Items"; } + + /// This is called each time a flight data record is updated + /// Here we are updating the eastbound callsigns dictionary with each flight data record + /// When the FDR is updated we check if it still exists in the Flight Data Processor and remove from our dictionary if not. Otherwise we do some simple regex matching to find + /// the flight planned PBN category and store the character we want to display in the label in the dictionary. + public void OnFDRUpdate(FDP2.FDR updated) + { + AutoAssume(updated); + AutoDrop(updated); + if (FDP2.GetFDRIndex(updated.Callsign) == -1) + { + eastboundCallsigns.TryRemove(updated.Callsign, out _); + adsbcpdlcValues.TryRemove(updated.Callsign, out _); + adsflagValues.TryRemove(updated.Callsign, out _); + mntflagValues.TryRemove(updated.Callsign, out _); + altValues.TryRemove(updated.Callsign, out _); + radartoggle.TryRemove(updated.Callsign, out _); + adsflagtoggle.TryRemove(updated.Callsign, out _); + mntflagtoggle.TryRemove(updated.Callsign, out _); + downlink.TryRemove(updated.Callsign, out _); + } + else + { + Match pbn = Regex.Match(updated.Remarks, @"PBN\/\w+\s"); + bool rnp10 = Regex.IsMatch(pbn.Value, @"A1"); + bool rnp4 = Regex.IsMatch(pbn.Value, @"L1"); + bool cpdlc = Regex.IsMatch(updated.AircraftEquip, @"J5") || Regex.IsMatch(updated.AircraftEquip, @"J7"); + bool adsc = Regex.IsMatch(updated.AircraftSurvEquip, @"D1"); + int cfl; + bool isCfl = Int32.TryParse(updated.CFLString, out cfl); + var vs = updated.PredictedPosition.VerticalSpeed; + int level = updated.PRL / 100; + + char c1 = default; + + if (!updated.ADSB && cpdlc) + + c1 = '⧆'; + + else if (!updated.ADSB) + + c1 = '⎕'; + + else if (cpdlc) + + c1 = '*'; + + + adsbcpdlcValues.AddOrUpdate(updated.Callsign, c1, (k, v) => c1); + + char c2 = default; + + if (adsc & cpdlc & rnp4) + c2 = '3'; + + else if (adsc & cpdlc & rnp10) + c2 = 'D'; + + adsflagValues.AddOrUpdate(updated.Callsign, c2, (k, v) => c2); + + char c3 = default; + + if (AuroraStripItemsPlugin.AuroraStripItemsPlugin.MachNumberTech(updated.PerformanceData)) + c3 = 'M'; + + mntflagValues.AddOrUpdate(updated.Callsign, c3, (k, v) => c3); + + + char h1 = default; + + if (level == cfl || level == updated.RFL)//level + h1 = default; + + else if (cfl > level || vs > 300)//Issued or trending climb + h1 = '↑'; + + else if (cfl > 0 && cfl < level || vs < -300)//Issued or trending descent + h1 = '↓'; + + else if (level - updated.RFL / 100 >= 3)//deviating above + h1 = '+'; + + else if (level - updated.RFL / 100 <= -3)//deviating below + h1 = '-'; + + + altValues.AddOrUpdate(updated.Callsign, h1, (k, v) => h1); + + + + if (updated.ParsedRoute.Count > 1) + { + //calculate track from first route point to last (Departure point to destination point) + var rte = updated.ParsedRoute; + double trk = Conversions.CalculateTrack(rte.First().Intersection.LatLong, rte.Last().Intersection.LatLong); + bool east = trk >= 0 && trk < 180; + eastboundCallsigns.AddOrUpdate(updated.Callsign, east, (c, e) => east); + } + } + } + + private static void ProbeMidTermConflict(RDP.RadarTrack rt) + { + // TODO: implement + } + + private static void AutoAssume(RDP.RadarTrack rt) + { + var fdr = rt.CoupledFDR; + if (fdr != null) + { + AutoAssume(fdr); + } + } + + private static void AutoAssume(FDP2.FDR fdr) + { + if (fdr != null) + { + FDP2.CalculateTrajectoryEstimates(fdr); + FDP2.CalculateAffectedSectors(fdr); + if ((fdr.ControllingSector == null && MMI.IsMySectorConcerned(fdr)) || + (MMI.SectorsControlled.ToList() + .Exists(s => s.IsInSector(fdr.GetLocation(), fdr.PRL)) && !fdr.IsTrackedByMe && MMI.SectorsControlled.Contains(fdr.ControllingSector))) + { + FDP2.AcceptJurisdiction(fdr, MMI.SectorsControlled.First()); + FDP2.HandoffFirst(fdr); + } + } + + } + + private static void AutoDrop(RDP.RadarTrack rt) + { + var fdr = rt.CoupledFDR; + if (fdr != null) + { + AutoDrop(fdr); + } + } + + private static void AutoDrop(FDP2.FDR fdr) + { + if (fdr != null) + { + FDP2.CalculateAffectedSectors(fdr); + FDP2.CalculateTrajectoryEstimates(fdr); + if (fdr.IsTrackedByMe && !MMI.IsMySectorConcerned(fdr) && MMI.SectorsControlled.ToList() + .TrueForAll(s => !s.IsInSector(fdr.GetLocation(), fdr.PRL))) + { + FDP2.HandoffToNone(fdr); + } + } + + } + + + /// Could use the new position of the radar track or its change in state (cancelled, etc.) to do some processing. + public void OnRadarTrackUpdate(RDP.RadarTrack updated) + { + AutoAssume(updated); + AutoDrop(updated); + ProbeMidTermConflict(updated); + } + + + private void HandleRadarFlagClick(CustomLabelItemMouseClickEventArgs e) + { + bool radarToggled = radartoggle.TryGetValue(e.Track.GetFDR().Callsign, out _); + + if (radarToggled) + { + radartoggle.TryRemove(e.Track.GetFDR().Callsign, out _); + } + else + { + radartoggle.TryAdd(e.Track.GetFDR().Callsign, 0); + } + e.Handled = true; + } + private void HandleADSFlagClick(CustomLabelItemMouseClickEventArgs e) + { + bool adsflagToggled = radartoggle.TryGetValue(e.Track.GetFDR().Callsign, out _); + + if (adsflagToggled) + { + adsflagtoggle.TryRemove(e.Track.GetFDR().Callsign, out _); + } + else + { + adsflagtoggle.TryAdd(e.Track.GetFDR().Callsign, 0); + } + e.Handled = true; + } + + private void HandleMNTFlagClick(CustomLabelItemMouseClickEventArgs e) + { + bool mntflagToggled = radartoggle.TryGetValue(e.Track.GetFDR().Callsign, out _); + + if (mntflagToggled) + { + mntflagtoggle.TryRemove(e.Track.GetFDR().Callsign, out _); + } + else + { + mntflagtoggle.TryAdd(e.Track.GetFDR().Callsign, 0); + } + e.Handled = true; + } + /// vatSys calls this function when it encounters a custom label item (defined in Labels.xml) during the label rendering. + /// itemType is the value of the Type attribute in Labels.xml + /// If it's not our item being called (another plugins, for example), return null. + /// As a general rule, don't do processing in here as you'll slow down the ASD refresh. In the case of parsing a level to a string though, that's fine. + public CustomLabelItem GetCustomLabelItem(string itemType, Track track, FDP2.FDR flightDataRecord, RDP.RadarTrack radarTrack) + { + + if (flightDataRecord == null || track == null) + return null; + + char c1; + adsbcpdlcValues.TryGetValue(flightDataRecord.Callsign, out c1); + char c2; + adsflagValues.TryGetValue(flightDataRecord.Callsign, out c2); + char c3; + mntflagValues.TryGetValue(flightDataRecord.Callsign, out c3); + char h1; + altValues.TryGetValue(flightDataRecord.Callsign, out h1); + + bool radarToggled = radartoggle.TryGetValue(flightDataRecord.Callsign, out _); + bool adsflagToggled = adsflagtoggle.TryGetValue(flightDataRecord.Callsign, out _); + bool mntflagToggled = mntflagtoggle.TryGetValue(flightDataRecord.Callsign, out _); + bool downLink = downlink.TryGetValue(flightDataRecord.Callsign, out _); + bool selectedCallsign = MMI.SelectedTrack?.GetFDR()?.Callsign == flightDataRecord.Callsign; + + + switch (itemType) + { + case LABEL_ITEM_SELECT_HORI: + + if (selectedCallsign) + { + return new CustomLabelItem() + + { + Border = BorderFlags.Top + }; + } + + else + { + return new CustomLabelItem() + + { + Border = BorderFlags.None + }; + } + + case LABEL_ITEM_SELECT_VERT: + + if (selectedCallsign) + { + return new CustomLabelItem() + { + Text = "", + Border = BorderFlags.Left + }; + } + + else + { + return new CustomLabelItem() + { + Text = "", + Border = BorderFlags.None + }; + } + + case LABEL_ITEM_COMM_ICON: + + if (downLink) + { + return new CustomLabelItem() + { + Text = "▼", + Border = BorderFlags.All + }; + } + else + { + return new CustomLabelItem() + { + Text = "⬜" + }; + } + case LABEL_ITEM_ADSB_CPDLC: + + bool useCustomForeColour = track.State == MMI.HMIStates.Preactive || track.State == MMI.HMIStates.Announced; + + if (useCustomForeColour) + { + return new CustomLabelItem() + { + ForeColourIdentity = Colours.Identities.Custom, + CustomForeColour = NotCDA, + Text = c1.ToString() + }; + } + else + { + return new CustomLabelItem() + { + Text = c1.ToString() + }; + } + + case LABEL_ITEM_ADS_FLAGS: + + if (adsflagToggled) + { + return new CustomLabelItem() + { + Text = c2.ToString(), + OnMouseClick = HandleADSFlagClick, + }; + } + + else + return new CustomLabelItem() + { + Text = "", + OnMouseClick = HandleADSFlagClick, + }; + + case LABEL_ITEM_MNT_FLAGS: + + if (mntflagToggled) + { + return new CustomLabelItem() + { + Text = c3.ToString(), + OnMouseClick = HandleMNTFlagClick, + }; + } + + else + return new CustomLabelItem() + { + Text = "", + OnMouseClick = HandleMNTFlagClick, + }; + + + //case LABEL_ITEM_SCC: + // + // return new CustomLabelItem() + // { + // Text = pos //| ca | la | ra | rcf | dup | spd + // }; + + + case LABEL_ITEM_ANNOT_IND: + bool scratch = String.IsNullOrEmpty(flightDataRecord.LabelOpData); + + if (scratch) + { + return new CustomLabelItem() + { + Text = "◦" + }; + } + + else + { + return new CustomLabelItem() + { + Text = "&" + }; + } + + case LABEL_ITEM_RESTR: + + if (flightDataRecord.LabelOpData.Contains ("AT") || flightDataRecord.LabelOpData.Contains("BY") || flightDataRecord.LabelOpData.Contains("CLEARED TO")) + + return new CustomLabelItem() + { + Text = "x" + }; + + return null; + + case LABEL_ITEM_VMI: + bool isNonRVSMOrNewCFL = !flightDataRecord.RVSM || track.NewCFL; + + if (isNonRVSMOrNewCFL) + { + return new CustomLabelItem() + { + Text = h1.ToString(), + ForeColourIdentity = Colours.Identities.Custom, + CustomForeColour = !flightDataRecord.RVSM ? NonRVSM : Probe + }; + } + else + { + return new CustomLabelItem() + { + Text = h1.ToString() + }; + } + + + case LABEL_ITEM_CLEARED_LEVEL: + + return new CustomLabelItem() + { + Text = (track.NewCFL && radarTrack.ReachedCFL) ? string.Empty : flightDataRecord.CFLString, + ForeColourIdentity = Colours.Identities.Custom, + CustomForeColour = !flightDataRecord.RVSM ? NonRVSM : Probe + }; + + case LABEL_ITEM_RADAR_IND: + + + if (radarToggled) + { + return new CustomLabelItem() + { + Text = "★", + OnMouseClick = HandleRadarFlagClick, + }; + } + + else + { + return new CustomLabelItem() + { + Text = "◦", + OnMouseClick = HandleRadarFlagClick, + }; + } + + case LABEL_ITEM_FILED_SPEED: + var mach = flightDataRecord.TAS / 581.0; + return new CustomLabelItem() + { + Text = "M" + Convert.ToDecimal(mach).ToString("F2").Replace(".","") + //Text = "N" + flightDataRecord.TAS + }; + + case LABEL_ITEM_3DIGIT_GROUNDSPEED: + //get groundspeed value from either FDR or radarTrack if coupled + var gs = radarTrack == null ? flightDataRecord.PredictedPosition.Groundspeed : radarTrack.GroundSpeed; + return new CustomLabelItem() + { + Text = "N" + gs.ToString("000")//format as 3 digits (with leading zeros) + }; + + default: + return null; + } + } + + public CustomColour SelectASDTrackColour(Track track) + { + //only apply East/West colour to jurisdiction state + if (track.State != MMI.HMIStates.Jurisdiction) + return null; + + var fdr = track.GetFDR(); + //if track doesn't have an FDR coupled do nothing + if (fdr == null) + return null; + + //read our dictionary of stored bools (true means is easterly) and return the correct colour + return GetDirectionColour(fdr.Callsign); + } + + public CustomColour SelectGroundTrackColour(Track track) + { + return null; + } + + private CustomColour GetDirectionColour(string callsign) + { + if (eastboundCallsigns.TryGetValue(callsign, out bool east)) + { + if (east) + return EastboundColour; + else + return WestboundColour; + } + + return null; + } + } } \ No newline at end of file From 0a28469278c5290cb340f21499f7b23ddfa46392 Mon Sep 17 00:00:00 2001 From: Dominic Nguyen Date: Thu, 20 Jul 2023 19:53:20 -0700 Subject: [PATCH 19/76] FDR to MMI methods --- AuroraLabelItemsPlugin.cs | 26 +++++++++++++------------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/AuroraLabelItemsPlugin.cs b/AuroraLabelItemsPlugin.cs index 8cbd79a..6bed9dc 100644 --- a/AuroraLabelItemsPlugin.cs +++ b/AuroraLabelItemsPlugin.cs @@ -195,15 +195,17 @@ private static void AutoAssume(FDP2.FDR fdr) { if (fdr != null) { - FDP2.CalculateTrajectoryEstimates(fdr); - FDP2.CalculateAffectedSectors(fdr); - if ((fdr.ControllingSector == null && MMI.IsMySectorConcerned(fdr)) || - (MMI.SectorsControlled.ToList() - .Exists(s => s.IsInSector(fdr.GetLocation(), fdr.PRL)) && !fdr.IsTrackedByMe && MMI.SectorsControlled.Contains(fdr.ControllingSector))) + if (!fdr.ESTed && fdr.ControllingSector == null && MMI.IsMySectorConcerned(fdr)) { - FDP2.AcceptJurisdiction(fdr, MMI.SectorsControlled.First()); - FDP2.HandoffFirst(fdr); + MMI.EstFDR(fdr); } + + if (MMI.SectorsControlled.ToList() + .Exists(s => s.IsInSector(fdr.GetLocation(), fdr.PRL)) && !fdr.IsTrackedByMe && MMI.SectorsControlled.Contains(fdr.ControllingSector) || fdr.ControllingSector == null) + { + MMI.AcceptJurisdiction(fdr); + } + } } @@ -220,13 +222,11 @@ private static void AutoDrop(RDP.RadarTrack rt) private static void AutoDrop(FDP2.FDR fdr) { if (fdr != null) - { - FDP2.CalculateAffectedSectors(fdr); - FDP2.CalculateTrajectoryEstimates(fdr); - if (fdr.IsTrackedByMe && !MMI.IsMySectorConcerned(fdr) && MMI.SectorsControlled.ToList() + { + if (fdr.IsTrackedByMe && MMI.SectorsControlled.ToList() .TrueForAll(s => !s.IsInSector(fdr.GetLocation(), fdr.PRL))) - { - FDP2.HandoffToNone(fdr); + { + MMI.HandoffToNone(fdr); } } From 7ccabf9c1d08be5a8e138fea5d0bcf96b1bd45b2 Mon Sep 17 00:00:00 2001 From: Milan K <34196765+CaptainTux@users.noreply.github.com> Date: Sat, 22 Jul 2023 01:41:20 +0200 Subject: [PATCH 20/76] first try at conflict probing --- AuroraLabelItemsPlugin.cs | 123 +++++++++++++++++++++++++++----------- packages.config | 4 ++ 2 files changed, 92 insertions(+), 35 deletions(-) create mode 100644 packages.config diff --git a/AuroraLabelItemsPlugin.cs b/AuroraLabelItemsPlugin.cs index 6bed9dc..668f14b 100644 --- a/AuroraLabelItemsPlugin.cs +++ b/AuroraLabelItemsPlugin.cs @@ -1,8 +1,10 @@ using System; using System.Collections.Concurrent; +using System.Collections.Generic; using System.ComponentModel.Composition; using System.Linq; //<--Need to add a reference to System.ComponentModel.Composition using System.Text.RegularExpressions; +using Microsoft.Spatial; using vatsys; using vatsys.Plugin; @@ -12,19 +14,18 @@ namespace AuroraLabelItemsPlugin { [Export(typeof(IPlugin))] - public class AuroraLabelItemsPlugin : ILabelPlugin { - /// The name of the custom label item we've added to Labels /// in the Profile const string LABEL_ITEM_SELECT_HORI = "SELECT_HORI"; + const string LABEL_ITEM_SELECT_VERT = "SELECT_VERT"; const string LABEL_ITEM_COMM_ICON = "AURORA_COMM_ICON"; //field a(2) const string LABEL_ITEM_ADSB_CPDLC = "AURORA_ADSB_CPDLC"; //field c(4) const string LABEL_ITEM_ADS_FLAGS = "AURORA_ADS_FLAGS"; //field c(4) const string LABEL_ITEM_MNT_FLAGS = "AURORA_MNT_FLAGS"; //field c(4) - const string LABEL_ITEM_SCC = "AURORA_SCC"; //field c(5) + const string LABEL_ITEM_SCC = "AURORA_SCC"; //field c(5) const string LABEL_ITEM_ANNOT_IND = "AURORA_ANNOT_IND"; //field e(1) const string LABEL_ITEM_RESTR = "AURORA_RESTR"; //field f(1) const string LABEL_ITEM_VMI = "AURORA_VMI"; //field h(1) @@ -75,7 +76,10 @@ private void Network_PrivateMessagesChanged(object sender, Network.GenericMessag } /// Plugin Name - public string Name { get => "Aurora Label Items"; } + public string Name + { + get => "Aurora Label Items"; + } /// This is called each time a flight data record is updated /// Here we are updating the eastbound callsigns dictionary with each flight data record @@ -146,40 +150,83 @@ public void OnFDRUpdate(FDP2.FDR updated) char h1 = default; - if (level == cfl || level == updated.RFL)//level + if (level == cfl || level == updated.RFL) //level h1 = default; - else if (cfl > level || vs > 300)//Issued or trending climb + else if (cfl > level || vs > 300) //Issued or trending climb h1 = '↑'; - else if (cfl > 0 && cfl < level || vs < -300)//Issued or trending descent + else if (cfl > 0 && cfl < level || vs < -300) //Issued or trending descent h1 = '↓'; - else if (level - updated.RFL / 100 >= 3)//deviating above + else if (level - updated.RFL / 100 >= 3) //deviating above h1 = '+'; - else if (level - updated.RFL / 100 <= -3)//deviating below + else if (level - updated.RFL / 100 <= -3) //deviating below h1 = '-'; altValues.AddOrUpdate(updated.Callsign, h1, (k, v) => h1); - - if (updated.ParsedRoute.Count > 1) { //calculate track from first route point to last (Departure point to destination point) var rte = updated.ParsedRoute; - double trk = Conversions.CalculateTrack(rte.First().Intersection.LatLong, rte.Last().Intersection.LatLong); + double trk = Conversions.CalculateTrack(rte.First().Intersection.LatLong, + rte.Last().Intersection.LatLong); bool east = trk >= 0 && trk < 180; eastboundCallsigns.AddOrUpdate(updated.Callsign, east, (c, e) => east); } } } - private static void ProbeMidTermConflict(RDP.RadarTrack rt) + private static GeographyMultiLineString GetTrajectoryPoints(List trajectory) { - // TODO: implement + var lineString = GeographyFactory.MultiLineString(CoordinateSystem.DefaultGeography); + trajectory.ForEach(t => + lineString.LineTo(t.Location.Latitude, t.Location.Longitude)); + + return lineString.Build(); + } + + private static void ProbeStandardConflict(FDP2.FDR fdr) + { + if (fdr == null) return; + int cfl; + bool isCfl = Int32.TryParse(fdr.CFLString, out cfl); + if (!isCfl) return; + + var isRvsm = fdr.RVSM; + var trajectoryPoints = GetTrajectoryPoints(fdr.Trajectory); + + foreach (var fdr2 in FDP2.GetFDRs) + { + if (fdr2 == null || MMI.IsMySectorConcerned(fdr)) continue; + int cfl2; + bool isCfl2 = Int32.TryParse(fdr.CFLString, out cfl2); + if (!isCfl2) continue; + var isRvsm2 = fdr2.RVSM; + var delta = Math.Abs(cfl - cfl2); + int requiredAltSep = (cfl > FDP2.RVSM_BAND_LOWER && !isRvsm) || + (cfl2 > FDP2.RVSM_BAND_LOWER && !isRvsm2) || cfl > FDP2.RVSM_BAND_UPPER || + cfl2 > FDP2.RVSM_BAND_UPPER + ? 2000 + : 1000; + + if (delta < requiredAltSep) + { + var trajectoryPoints2 = GetTrajectoryPoints(fdr2.Trajectory); + var distance = trajectoryPoints.Distance(trajectoryPoints2); + if (distance != null) + { + var distanceNm = Conversions.MetresToNauticalMiles((double) distance); + if (distanceNm < 23) + { + // TODO: things + } + } + } + } } private static void AutoAssume(RDP.RadarTrack rt) @@ -201,13 +248,12 @@ private static void AutoAssume(FDP2.FDR fdr) } if (MMI.SectorsControlled.ToList() - .Exists(s => s.IsInSector(fdr.GetLocation(), fdr.PRL)) && !fdr.IsTrackedByMe && MMI.SectorsControlled.Contains(fdr.ControllingSector) || fdr.ControllingSector == null) + .Exists(s => s.IsInSector(fdr.GetLocation(), fdr.PRL)) && !fdr.IsTrackedByMe && + MMI.SectorsControlled.Contains(fdr.ControllingSector) || fdr.ControllingSector == null) { MMI.AcceptJurisdiction(fdr); } - } - } private static void AutoDrop(RDP.RadarTrack rt) @@ -222,14 +268,13 @@ private static void AutoDrop(RDP.RadarTrack rt) private static void AutoDrop(FDP2.FDR fdr) { if (fdr != null) - { + { if (fdr.IsTrackedByMe && MMI.SectorsControlled.ToList() .TrueForAll(s => !s.IsInSector(fdr.GetLocation(), fdr.PRL))) - { - MMI.HandoffToNone(fdr); + { + MMI.HandoffToNone(fdr); } } - } @@ -238,7 +283,6 @@ public void OnRadarTrackUpdate(RDP.RadarTrack updated) { AutoAssume(updated); AutoDrop(updated); - ProbeMidTermConflict(updated); } @@ -254,8 +298,10 @@ private void HandleRadarFlagClick(CustomLabelItemMouseClickEventArgs e) { radartoggle.TryAdd(e.Track.GetFDR().Callsign, 0); } + e.Handled = true; } + private void HandleADSFlagClick(CustomLabelItemMouseClickEventArgs e) { bool adsflagToggled = radartoggle.TryGetValue(e.Track.GetFDR().Callsign, out _); @@ -268,6 +314,7 @@ private void HandleADSFlagClick(CustomLabelItemMouseClickEventArgs e) { adsflagtoggle.TryAdd(e.Track.GetFDR().Callsign, 0); } + e.Handled = true; } @@ -283,15 +330,17 @@ private void HandleMNTFlagClick(CustomLabelItemMouseClickEventArgs e) { mntflagtoggle.TryAdd(e.Track.GetFDR().Callsign, 0); } + e.Handled = true; } + /// vatSys calls this function when it encounters a custom label item (defined in Labels.xml) during the label rendering. /// itemType is the value of the Type attribute in Labels.xml /// If it's not our item being called (another plugins, for example), return null. /// As a general rule, don't do processing in here as you'll slow down the ASD refresh. In the case of parsing a level to a string though, that's fine. - public CustomLabelItem GetCustomLabelItem(string itemType, Track track, FDP2.FDR flightDataRecord, RDP.RadarTrack radarTrack) + public CustomLabelItem GetCustomLabelItem(string itemType, Track track, FDP2.FDR flightDataRecord, + RDP.RadarTrack radarTrack) { - if (flightDataRecord == null || track == null) return null; @@ -356,10 +405,10 @@ public CustomLabelItem GetCustomLabelItem(string itemType, Track track, FDP2.FDR case LABEL_ITEM_COMM_ICON: if (downLink) - { + { return new CustomLabelItem() { - Text = "▼", + Text = "▼", Border = BorderFlags.All }; } @@ -367,12 +416,13 @@ public CustomLabelItem GetCustomLabelItem(string itemType, Track track, FDP2.FDR { return new CustomLabelItem() { - Text = "⬜" + Text = "⬜" }; } case LABEL_ITEM_ADSB_CPDLC: - bool useCustomForeColour = track.State == MMI.HMIStates.Preactive || track.State == MMI.HMIStates.Announced; + bool useCustomForeColour = + track.State == MMI.HMIStates.Preactive || track.State == MMI.HMIStates.Announced; if (useCustomForeColour) { @@ -456,14 +506,15 @@ public CustomLabelItem GetCustomLabelItem(string itemType, Track track, FDP2.FDR } case LABEL_ITEM_RESTR: - - if (flightDataRecord.LabelOpData.Contains ("AT") || flightDataRecord.LabelOpData.Contains("BY") || flightDataRecord.LabelOpData.Contains("CLEARED TO")) - + + if (flightDataRecord.LabelOpData.Contains("AT") || flightDataRecord.LabelOpData.Contains("BY") || + flightDataRecord.LabelOpData.Contains("CLEARED TO")) + return new CustomLabelItem() { Text = "x" }; - + return null; case LABEL_ITEM_VMI: @@ -521,16 +572,18 @@ public CustomLabelItem GetCustomLabelItem(string itemType, Track track, FDP2.FDR var mach = flightDataRecord.TAS / 581.0; return new CustomLabelItem() { - Text = "M" + Convert.ToDecimal(mach).ToString("F2").Replace(".","") + Text = "M" + Convert.ToDecimal(mach).ToString("F2").Replace(".", "") //Text = "N" + flightDataRecord.TAS }; case LABEL_ITEM_3DIGIT_GROUNDSPEED: //get groundspeed value from either FDR or radarTrack if coupled - var gs = radarTrack == null ? flightDataRecord.PredictedPosition.Groundspeed : radarTrack.GroundSpeed; + var gs = radarTrack == null + ? flightDataRecord.PredictedPosition.Groundspeed + : radarTrack.GroundSpeed; return new CustomLabelItem() { - Text = "N" + gs.ToString("000")//format as 3 digits (with leading zeros) + Text = "N" + gs.ToString("000") //format as 3 digits (with leading zeros) }; default: diff --git a/packages.config b/packages.config new file mode 100644 index 0000000..5a1dc50 --- /dev/null +++ b/packages.config @@ -0,0 +1,4 @@ + + + + \ No newline at end of file From 95078d1c708b9d25d21e491355b86f4308c6e4c4 Mon Sep 17 00:00:00 2001 From: Milan K <34196765+CaptainTux@users.noreply.github.com> Date: Thu, 27 Jul 2023 22:20:31 +0200 Subject: [PATCH 21/76] add conflict probing (no guarantees( --- AuroraLabelItemsPlugin.cs | 170 +++++++++++++++++++++++++++++++++----- 1 file changed, 149 insertions(+), 21 deletions(-) diff --git a/AuroraLabelItemsPlugin.cs b/AuroraLabelItemsPlugin.cs index 668f14b..d1e4b4c 100644 --- a/AuroraLabelItemsPlugin.cs +++ b/AuroraLabelItemsPlugin.cs @@ -47,7 +47,8 @@ public class AuroraLabelItemsPlugin : ILabelPlugin readonly ConcurrentDictionary adsflagtoggle = new ConcurrentDictionary(); readonly ConcurrentDictionary mntflagtoggle = new ConcurrentDictionary(); readonly ConcurrentDictionary downlink = new ConcurrentDictionary(); - readonly ConcurrentDictionary conflicts = new ConcurrentDictionary(); + // key: callsign, value: acknowledged status + readonly ConcurrentDictionary acknowledgedConflicts = new ConcurrentDictionary(); public AuroraLabelItemsPlugin() { @@ -89,6 +90,7 @@ public void OnFDRUpdate(FDP2.FDR updated) { AutoAssume(updated); AutoDrop(updated); + ProbeStandardConflict(updated, 23); if (FDP2.GetFDRIndex(updated.Callsign) == -1) { eastboundCallsigns.TryRemove(updated.Callsign, out _); @@ -179,17 +181,136 @@ public void OnFDRUpdate(FDP2.FDR updated) } } } - - private static GeographyMultiLineString GetTrajectoryPoints(List trajectory) + + public class Segment + { + public string callsign; + public Coordinate startLatlong; + public Coordinate endLatlong; + public DateTime startTime = DateTime.MaxValue; + public DateTime endTime = DateTime.MaxValue; + public FDP2.FDR.ExtractedRoute.Segment routeSegment; + } + + private static List CreatePolygon(Coordinate point1, Coordinate point2, int value) + { + List polygon = new List(); + double track = Conversions.CalculateTrack(point1, point2); + double num1 = track - 90.0; + for (int index = 0; index <= 180; index += 10) + { + double heading = num1 - (double)index; + Coordinate fromBearingRange = Conversions.CalculateLLFromBearingRange(point1, (double)value, heading); + polygon.Add(fromBearingRange); + } + double num2 = track + 90.0; + for (int index = 0; index <= 180; index += 10) + { + double heading = num2 - (double)index; + Coordinate fromBearingRange = Conversions.CalculateLLFromBearingRange(point2, (double)value, heading); + polygon.Add(fromBearingRange); + } + polygon.Add(polygon[0]); + return polygon; + } + + private static List CalculatePolygonIntersections( + List polygon, + Coordinate point1, + Coordinate point2) { - var lineString = GeographyFactory.MultiLineString(CoordinateSystem.DefaultGeography); - trajectory.ForEach(t => - lineString.LineTo(t.Location.Latitude, t.Location.Longitude)); + List polygonIntersections = new List(); + for (int index = 1; index < polygon.Count; ++index) + { + List gcIntersectionLl = Conversions.CalculateAllGCIntersectionLL(polygon[index - 1], polygon[index], point1, point2); + if (gcIntersectionLl != null) + polygonIntersections.AddRange(gcIntersectionLl); + } + for (int index = 0; index < polygonIntersections.Count; ++index) + { + Coordinate intsect = polygonIntersections[index]; + polygonIntersections.RemoveAll(c => c != intsect && Conversions.CalculateDistance(intsect, c) < 0.01); + } + return polygonIntersections; + } - return lineString.Build(); + private static List CalculateAreaOfConflict(FDP2.FDR fdr1, FDP2.FDR fdr2, int value) + { + List segs = new List(); + List route1waypoints = fdr1.ParsedRoute.ToList().Where(s => s.Type == FDP2.FDR.ExtractedRoute.Segment.SegmentTypes.WAYPOINT).ToList(); + List route2waypoints = fdr2.ParsedRoute.ToList().Where(s => s.Type == FDP2.FDR.ExtractedRoute.Segment.SegmentTypes.WAYPOINT).ToList(); + for (int wp1index = 1; wp1index < route1waypoints.Count; ++wp1index) + { + List route1Segment = CreatePolygon(route1waypoints[wp1index - 1].Intersection.LatLong, route1waypoints[wp1index].Intersection.LatLong, value); + for (int wp2index = 1; wp2index < route2waypoints.Count; wp2index++) + { + List source = new List(); + List intersectionPoints = new List(); + source.AddRange((IEnumerable)CalculatePolygonIntersections(route1Segment, route2waypoints[wp2index - 1].Intersection.LatLong, route2waypoints[wp2index].Intersection.LatLong)); + int num1 = 0; + int num2 = 0; + foreach (Coordinate coordinate in source.ToList()) + { + if (Conversions.IsLatLonOnGC(route2waypoints[wp2index - 1].Intersection.LatLong, route2waypoints[wp2index].Intersection.LatLong, coordinate)) + { + intersectionPoints.Add(coordinate); + } + else + { + double track = Conversions.CalculateTrack(route2waypoints[wp2index - 1].Intersection.LatLong, route2waypoints[wp2index].Intersection.LatLong); + if (Math.Abs(track - Conversions.CalculateTrack(route2waypoints[wp2index - 1].Intersection.LatLong, coordinate)) > 90.0) + ++num1; + if (Math.Abs(track - Conversions.CalculateTrack(coordinate, route2waypoints[wp2index].Intersection.LatLong)) > 90.0) + ++num2; + } + } + if (num1 % 2 != 0 && num2 % 2 != 0) + { + intersectionPoints.Clear(); + intersectionPoints.Add(route2waypoints[wp2index - 1].Intersection.LatLong); + intersectionPoints.Add(route2waypoints[wp2index].Intersection.LatLong); + } + else if (num2 % 2 != 0) + intersectionPoints.Add(route2waypoints[wp2index].Intersection.LatLong); + else if (num1 % 2 != 0) + intersectionPoints.Add(route2waypoints[wp2index - 1].Intersection.LatLong); + intersectionPoints.Sort((x, y) => Conversions.CalculateDistance(route2waypoints[wp2index - 1].Intersection.LatLong, x).CompareTo(Conversions.CalculateDistance(route2waypoints[wp2index - 1].Intersection.LatLong, y))); + for (int ipIndex = 1; ipIndex < intersectionPoints.Count; ipIndex += 2) + { + Segment seg = new Segment(); + seg.startLatlong = intersectionPoints[ipIndex - 1]; + seg.endLatlong = intersectionPoints[ipIndex]; + List conflictSegments = segs.Where((Func)(s => s.routeSegment == route2waypoints[wp2index])).Where((Func)(s => Conversions.CalculateDistance(s.startLatlong, route2waypoints[wp2index - 1].Intersection.LatLong) < Conversions.CalculateDistance(seg.startLatlong, route2waypoints[wp2index - 1].Intersection.LatLong) && Conversions.CalculateDistance(s.endLatlong, route2waypoints[wp2index - 1].Intersection.LatLong) > Conversions.CalculateDistance(seg.startLatlong, route2waypoints[wp2index - 1].Intersection.LatLong) || Conversions.CalculateDistance(s.endLatlong, route2waypoints[wp2index - 1].Intersection.LatLong) > Conversions.CalculateDistance(seg.endLatlong, route2waypoints[wp2index - 1].Intersection.LatLong) && Conversions.CalculateDistance(s.startLatlong, route2waypoints[wp2index - 1].Intersection.LatLong) < Conversions.CalculateDistance(seg.endLatlong, route2waypoints[wp2index - 1].Intersection.LatLong) || Conversions.CalculateDistance(s.startLatlong, route2waypoints[wp2index - 1].Intersection.LatLong) > Conversions.CalculateDistance(seg.startLatlong, route2waypoints[wp2index - 1].Intersection.LatLong) && Conversions.CalculateDistance(s.endLatlong, route2waypoints[wp2index - 1].Intersection.LatLong) < Conversions.CalculateDistance(seg.endLatlong, route2waypoints[wp2index - 1].Intersection.LatLong) || Conversions.CalculateDistance(s.startLatlong, seg.startLatlong) < 0.01 || Conversions.CalculateDistance(s.endLatlong, seg.endLatlong) < 0.01)).ToList(); + if (conflictSegments.Count > 0) + { + foreach (Segment segment in conflictSegments) + { + if (Conversions.CalculateDistance(segment.endLatlong, route2waypoints[wp2index - 1].Intersection.LatLong) < Conversions.CalculateDistance(seg.endLatlong, route2waypoints[wp2index - 1].Intersection.LatLong)) + segment.endLatlong = seg.endLatlong; + if (Conversions.CalculateDistance(seg.startLatlong, route2waypoints[wp2index - 1].Intersection.LatLong) < Conversions.CalculateDistance(segment.startLatlong, route2waypoints[wp2index - 1].Intersection.LatLong)) + segment.startLatlong = seg.startLatlong; + } + } + else + { + seg.callsign = fdr2.Callsign; + seg.routeSegment = route2waypoints[wp2index]; + segs.Add(seg); + } + } + } + } + for (int i = 0; i < segs.Count; i++) + { + if (!segs.Exists((Predicate)(s => Conversions.CalculateDistance(segs[i].startLatlong, s.endLatlong) < 0.01))) + segs[i].startTime = FDP2.GetSystemEstimateAtPosition(fdr2, segs[i].startLatlong, segs[i].routeSegment); + if (!segs.Exists((Predicate)(s => Conversions.CalculateDistance(segs[i].endLatlong, s.startLatlong) < 0.01))) + segs[i].endTime = FDP2.GetSystemEstimateAtPosition(fdr2, segs[i].endLatlong, segs[i].routeSegment); + } + return segs; } - private static void ProbeStandardConflict(FDP2.FDR fdr) + private void ProbeStandardConflict(FDP2.FDR fdr, int value) { if (fdr == null) return; int cfl; @@ -197,11 +318,12 @@ private static void ProbeStandardConflict(FDP2.FDR fdr) if (!isCfl) return; var isRvsm = fdr.RVSM; - var trajectoryPoints = GetTrajectoryPoints(fdr.Trajectory); - + + bool never; + foreach (var fdr2 in FDP2.GetFDRs) { - if (fdr2 == null || MMI.IsMySectorConcerned(fdr)) continue; + if (fdr2 == null || fdr.Callsign == fdr2.Callsign || !MMI.IsMySectorConcerned(fdr2)) continue; int cfl2; bool isCfl2 = Int32.TryParse(fdr.CFLString, out cfl2); if (!isCfl2) continue; @@ -212,19 +334,25 @@ private static void ProbeStandardConflict(FDP2.FDR fdr) cfl2 > FDP2.RVSM_BAND_UPPER ? 2000 : 1000; - + if (delta < requiredAltSep) { - var trajectoryPoints2 = GetTrajectoryPoints(fdr2.Trajectory); - var distance = trajectoryPoints.Distance(trajectoryPoints2); - if (distance != null) + var segments1 = CalculateAreaOfConflict(fdr, fdr2, value); + // var segments2 = CalculateAreaOfConflict(fdr2, fdr, value); + if (segments1.Count > 0) { - var distanceNm = Conversions.MetresToNauticalMiles((double) distance); - if (distanceNm < 23) - { - // TODO: things - } - } + // auto acknowledge + acknowledgedConflicts.AddOrUpdate(fdr.Callsign, true, (k, v) => true); + acknowledgedConflicts.AddOrUpdate(fdr.Callsign, true, (k, v) => true); + } + else + { + acknowledgedConflicts.TryRemove(fdr.Callsign, out never); + } + } + else + { + acknowledgedConflicts.TryRemove(fdr.Callsign, out never); } } } From 1f6ca74c7fed38b0597512da2739c5d5969e048b Mon Sep 17 00:00:00 2001 From: Milan K <34196765+captaintux@users.noreply.github.com> Date: Thu, 27 Jul 2023 22:20:31 +0200 Subject: [PATCH 22/76] add conflict probing (no guarantees) --- AuroraLabelItemsPlugin.cs | 171 +++++++++++++++++++++++++++++++++----- 1 file changed, 149 insertions(+), 22 deletions(-) diff --git a/AuroraLabelItemsPlugin.cs b/AuroraLabelItemsPlugin.cs index 668f14b..7e80ec2 100644 --- a/AuroraLabelItemsPlugin.cs +++ b/AuroraLabelItemsPlugin.cs @@ -4,7 +4,6 @@ using System.ComponentModel.Composition; using System.Linq; //<--Need to add a reference to System.ComponentModel.Composition using System.Text.RegularExpressions; -using Microsoft.Spatial; using vatsys; using vatsys.Plugin; @@ -47,7 +46,8 @@ public class AuroraLabelItemsPlugin : ILabelPlugin readonly ConcurrentDictionary adsflagtoggle = new ConcurrentDictionary(); readonly ConcurrentDictionary mntflagtoggle = new ConcurrentDictionary(); readonly ConcurrentDictionary downlink = new ConcurrentDictionary(); - readonly ConcurrentDictionary conflicts = new ConcurrentDictionary(); + // key: callsign, value: acknowledged status + readonly ConcurrentDictionary acknowledgedConflicts = new ConcurrentDictionary(); public AuroraLabelItemsPlugin() { @@ -89,6 +89,7 @@ public void OnFDRUpdate(FDP2.FDR updated) { AutoAssume(updated); AutoDrop(updated); + ProbeStandardConflict(updated, 23); if (FDP2.GetFDRIndex(updated.Callsign) == -1) { eastboundCallsigns.TryRemove(updated.Callsign, out _); @@ -179,17 +180,136 @@ public void OnFDRUpdate(FDP2.FDR updated) } } } - - private static GeographyMultiLineString GetTrajectoryPoints(List trajectory) + + public class Segment + { + public string callsign; + public Coordinate startLatlong; + public Coordinate endLatlong; + public DateTime startTime = DateTime.MaxValue; + public DateTime endTime = DateTime.MaxValue; + public FDP2.FDR.ExtractedRoute.Segment routeSegment; + } + + private static List CreatePolygon(Coordinate point1, Coordinate point2, int value) + { + List polygon = new List(); + double track = Conversions.CalculateTrack(point1, point2); + double num1 = track - 90.0; + for (int index = 0; index <= 180; index += 10) + { + double heading = num1 - (double)index; + Coordinate fromBearingRange = Conversions.CalculateLLFromBearingRange(point1, (double)value, heading); + polygon.Add(fromBearingRange); + } + double num2 = track + 90.0; + for (int index = 0; index <= 180; index += 10) + { + double heading = num2 - (double)index; + Coordinate fromBearingRange = Conversions.CalculateLLFromBearingRange(point2, (double)value, heading); + polygon.Add(fromBearingRange); + } + polygon.Add(polygon[0]); + return polygon; + } + + private static List CalculatePolygonIntersections( + List polygon, + Coordinate point1, + Coordinate point2) { - var lineString = GeographyFactory.MultiLineString(CoordinateSystem.DefaultGeography); - trajectory.ForEach(t => - lineString.LineTo(t.Location.Latitude, t.Location.Longitude)); + List polygonIntersections = new List(); + for (int index = 1; index < polygon.Count; ++index) + { + List gcIntersectionLl = Conversions.CalculateAllGCIntersectionLL(polygon[index - 1], polygon[index], point1, point2); + if (gcIntersectionLl != null) + polygonIntersections.AddRange(gcIntersectionLl); + } + for (int index = 0; index < polygonIntersections.Count; ++index) + { + Coordinate intsect = polygonIntersections[index]; + polygonIntersections.RemoveAll(c => c != intsect && Conversions.CalculateDistance(intsect, c) < 0.01); + } + return polygonIntersections; + } - return lineString.Build(); + private static List CalculateAreaOfConflict(FDP2.FDR fdr1, FDP2.FDR fdr2, int value) + { + List segs = new List(); + List route1waypoints = fdr1.ParsedRoute.ToList().Where(s => s.Type == FDP2.FDR.ExtractedRoute.Segment.SegmentTypes.WAYPOINT).ToList(); + List route2waypoints = fdr2.ParsedRoute.ToList().Where(s => s.Type == FDP2.FDR.ExtractedRoute.Segment.SegmentTypes.WAYPOINT).ToList(); + for (int wp1index = 1; wp1index < route1waypoints.Count; ++wp1index) + { + List route1Segment = CreatePolygon(route1waypoints[wp1index - 1].Intersection.LatLong, route1waypoints[wp1index].Intersection.LatLong, value); + for (int wp2index = 1; wp2index < route2waypoints.Count; wp2index++) + { + List source = new List(); + List intersectionPoints = new List(); + source.AddRange((IEnumerable)CalculatePolygonIntersections(route1Segment, route2waypoints[wp2index - 1].Intersection.LatLong, route2waypoints[wp2index].Intersection.LatLong)); + int num1 = 0; + int num2 = 0; + foreach (Coordinate coordinate in source.ToList()) + { + if (Conversions.IsLatLonOnGC(route2waypoints[wp2index - 1].Intersection.LatLong, route2waypoints[wp2index].Intersection.LatLong, coordinate)) + { + intersectionPoints.Add(coordinate); + } + else + { + double track = Conversions.CalculateTrack(route2waypoints[wp2index - 1].Intersection.LatLong, route2waypoints[wp2index].Intersection.LatLong); + if (Math.Abs(track - Conversions.CalculateTrack(route2waypoints[wp2index - 1].Intersection.LatLong, coordinate)) > 90.0) + ++num1; + if (Math.Abs(track - Conversions.CalculateTrack(coordinate, route2waypoints[wp2index].Intersection.LatLong)) > 90.0) + ++num2; + } + } + if (num1 % 2 != 0 && num2 % 2 != 0) + { + intersectionPoints.Clear(); + intersectionPoints.Add(route2waypoints[wp2index - 1].Intersection.LatLong); + intersectionPoints.Add(route2waypoints[wp2index].Intersection.LatLong); + } + else if (num2 % 2 != 0) + intersectionPoints.Add(route2waypoints[wp2index].Intersection.LatLong); + else if (num1 % 2 != 0) + intersectionPoints.Add(route2waypoints[wp2index - 1].Intersection.LatLong); + intersectionPoints.Sort((x, y) => Conversions.CalculateDistance(route2waypoints[wp2index - 1].Intersection.LatLong, x).CompareTo(Conversions.CalculateDistance(route2waypoints[wp2index - 1].Intersection.LatLong, y))); + for (int ipIndex = 1; ipIndex < intersectionPoints.Count; ipIndex += 2) + { + Segment seg = new Segment(); + seg.startLatlong = intersectionPoints[ipIndex - 1]; + seg.endLatlong = intersectionPoints[ipIndex]; + List conflictSegments = segs.Where((Func)(s => s.routeSegment == route2waypoints[wp2index])).Where((Func)(s => Conversions.CalculateDistance(s.startLatlong, route2waypoints[wp2index - 1].Intersection.LatLong) < Conversions.CalculateDistance(seg.startLatlong, route2waypoints[wp2index - 1].Intersection.LatLong) && Conversions.CalculateDistance(s.endLatlong, route2waypoints[wp2index - 1].Intersection.LatLong) > Conversions.CalculateDistance(seg.startLatlong, route2waypoints[wp2index - 1].Intersection.LatLong) || Conversions.CalculateDistance(s.endLatlong, route2waypoints[wp2index - 1].Intersection.LatLong) > Conversions.CalculateDistance(seg.endLatlong, route2waypoints[wp2index - 1].Intersection.LatLong) && Conversions.CalculateDistance(s.startLatlong, route2waypoints[wp2index - 1].Intersection.LatLong) < Conversions.CalculateDistance(seg.endLatlong, route2waypoints[wp2index - 1].Intersection.LatLong) || Conversions.CalculateDistance(s.startLatlong, route2waypoints[wp2index - 1].Intersection.LatLong) > Conversions.CalculateDistance(seg.startLatlong, route2waypoints[wp2index - 1].Intersection.LatLong) && Conversions.CalculateDistance(s.endLatlong, route2waypoints[wp2index - 1].Intersection.LatLong) < Conversions.CalculateDistance(seg.endLatlong, route2waypoints[wp2index - 1].Intersection.LatLong) || Conversions.CalculateDistance(s.startLatlong, seg.startLatlong) < 0.01 || Conversions.CalculateDistance(s.endLatlong, seg.endLatlong) < 0.01)).ToList(); + if (conflictSegments.Count > 0) + { + foreach (Segment segment in conflictSegments) + { + if (Conversions.CalculateDistance(segment.endLatlong, route2waypoints[wp2index - 1].Intersection.LatLong) < Conversions.CalculateDistance(seg.endLatlong, route2waypoints[wp2index - 1].Intersection.LatLong)) + segment.endLatlong = seg.endLatlong; + if (Conversions.CalculateDistance(seg.startLatlong, route2waypoints[wp2index - 1].Intersection.LatLong) < Conversions.CalculateDistance(segment.startLatlong, route2waypoints[wp2index - 1].Intersection.LatLong)) + segment.startLatlong = seg.startLatlong; + } + } + else + { + seg.callsign = fdr2.Callsign; + seg.routeSegment = route2waypoints[wp2index]; + segs.Add(seg); + } + } + } + } + for (int i = 0; i < segs.Count; i++) + { + if (!segs.Exists((Predicate)(s => Conversions.CalculateDistance(segs[i].startLatlong, s.endLatlong) < 0.01))) + segs[i].startTime = FDP2.GetSystemEstimateAtPosition(fdr2, segs[i].startLatlong, segs[i].routeSegment); + if (!segs.Exists((Predicate)(s => Conversions.CalculateDistance(segs[i].endLatlong, s.startLatlong) < 0.01))) + segs[i].endTime = FDP2.GetSystemEstimateAtPosition(fdr2, segs[i].endLatlong, segs[i].routeSegment); + } + return segs; } - private static void ProbeStandardConflict(FDP2.FDR fdr) + private void ProbeStandardConflict(FDP2.FDR fdr, int value) { if (fdr == null) return; int cfl; @@ -197,11 +317,12 @@ private static void ProbeStandardConflict(FDP2.FDR fdr) if (!isCfl) return; var isRvsm = fdr.RVSM; - var trajectoryPoints = GetTrajectoryPoints(fdr.Trajectory); - + + bool never; + foreach (var fdr2 in FDP2.GetFDRs) { - if (fdr2 == null || MMI.IsMySectorConcerned(fdr)) continue; + if (fdr2 == null || fdr.Callsign == fdr2.Callsign || !MMI.IsMySectorConcerned(fdr2)) continue; int cfl2; bool isCfl2 = Int32.TryParse(fdr.CFLString, out cfl2); if (!isCfl2) continue; @@ -212,19 +333,25 @@ private static void ProbeStandardConflict(FDP2.FDR fdr) cfl2 > FDP2.RVSM_BAND_UPPER ? 2000 : 1000; - + if (delta < requiredAltSep) { - var trajectoryPoints2 = GetTrajectoryPoints(fdr2.Trajectory); - var distance = trajectoryPoints.Distance(trajectoryPoints2); - if (distance != null) + var segments1 = CalculateAreaOfConflict(fdr, fdr2, value); + // var segments2 = CalculateAreaOfConflict(fdr2, fdr, value); + if (segments1.Count > 0) { - var distanceNm = Conversions.MetresToNauticalMiles((double) distance); - if (distanceNm < 23) - { - // TODO: things - } - } + // auto acknowledge + acknowledgedConflicts.AddOrUpdate(fdr.Callsign, true, (k, v) => true); + acknowledgedConflicts.AddOrUpdate(fdr.Callsign, true, (k, v) => true); + } + else + { + acknowledgedConflicts.TryRemove(fdr.Callsign, out never); + } + } + else + { + acknowledgedConflicts.TryRemove(fdr.Callsign, out never); } } } From be3d21c9503cb1532f03a4654e2f3b000832041f Mon Sep 17 00:00:00 2001 From: Dominic Nguyen Date: Thu, 27 Jul 2023 21:03:20 -0700 Subject: [PATCH 23/76] Add files via upload Auto Flag --- AuroraStripItemPlugin.cs | 18 ++++++++---------- 1 file changed, 8 insertions(+), 10 deletions(-) diff --git a/AuroraStripItemPlugin.cs b/AuroraStripItemPlugin.cs index 49e4387..725949c 100644 --- a/AuroraStripItemPlugin.cs +++ b/AuroraStripItemPlugin.cs @@ -105,7 +105,7 @@ public CustomStripItem GetCustomStripItem(string itemType, Track track, FDP2.FDR int cfl; bool isCfl = Int32.TryParse(flightDataRecord.CFLString, out cfl); bool isEastBound = true; - bool flagToggled = flagtoggle.TryGetValue(flightDataRecord.Callsign, out _); + if (flightDataRecord is null) return null; @@ -200,8 +200,8 @@ public CustomStripItem GetCustomStripItem(string itemType, Track track, FDP2.FDR return new CustomStripItem() { - BackColourIdentity = flagToggled ? Colours.Identities.Custom : default, - CustomBackColour = SepFlags, + //BackColourIdentity = Colours.Identities.Custom, + //CustomBackColour = SepFlags, Text = "M", OnMouseClick = ItemMouseClick }; @@ -214,10 +214,9 @@ public CustomStripItem GetCustomStripItem(string itemType, Track track, FDP2.FDR return new CustomStripItem() { - BackColourIdentity = flagToggled ? Colours.Identities.Custom : default, - CustomBackColour = SepFlags, - Text = "R", - OnMouseClick = ItemMouseClick + //BackColourIdentity = Colours.Identities.Custom, + //CustomBackColour = SepFlags, + Text = "R" }; return null; @@ -229,10 +228,9 @@ public CustomStripItem GetCustomStripItem(string itemType, Track track, FDP2.FDR return new CustomStripItem() { - BackColourIdentity = flagToggled ? Colours.Identities.Custom : default, + BackColourIdentity = Colours.Identities.Custom, CustomBackColour = SepFlags, - Text = rnp4 ? "3" : "D", - OnMouseClick = ItemMouseClick + Text = rnp4 ? "3" : "D" }; return null; From 1e4a407cb93fb0c128102263403eacbab99e310b Mon Sep 17 00:00:00 2001 From: Dominic Nguyen Date: Thu, 27 Jul 2023 21:03:38 -0700 Subject: [PATCH 24/76] Add files via upload Auto Flag, Test Conflict Colors, Broke select box --- AuroraLabelItemsPlugin.cs | 183 +++++++++++++++++++++++--------------- 1 file changed, 110 insertions(+), 73 deletions(-) diff --git a/AuroraLabelItemsPlugin.cs b/AuroraLabelItemsPlugin.cs index 7e80ec2..3f29dff 100644 --- a/AuroraLabelItemsPlugin.cs +++ b/AuroraLabelItemsPlugin.cs @@ -1,11 +1,15 @@ using System; +using System.Threading; using System.Collections.Concurrent; using System.Collections.Generic; using System.ComponentModel.Composition; +using System.Diagnostics; using System.Linq; //<--Need to add a reference to System.ComponentModel.Composition +using System.Runtime.CompilerServices; using System.Text.RegularExpressions; using vatsys; using vatsys.Plugin; +using static vatsys.FDP2; //Note the reference to vatsys (set Copy Local to false) -----> @@ -37,17 +41,19 @@ public class AuroraLabelItemsPlugin : ILabelPlugin readonly static CustomColour NonRVSM = new CustomColour(242, 133, 0); readonly static CustomColour Probe = new CustomColour(0, 255, 0); readonly static CustomColour NotCDA = new CustomColour(100, 0, 100); + readonly static CustomColour Advisory = new CustomColour(255, 0, 0); + readonly static CustomColour Imminent = new CustomColour(255, 165, 0); readonly ConcurrentDictionary eastboundCallsigns = new ConcurrentDictionary(); readonly ConcurrentDictionary adsbcpdlcValues = new ConcurrentDictionary(); readonly ConcurrentDictionary adsflagValues = new ConcurrentDictionary(); readonly ConcurrentDictionary mntflagValues = new ConcurrentDictionary(); readonly ConcurrentDictionary altValues = new ConcurrentDictionary(); readonly ConcurrentDictionary radartoggle = new ConcurrentDictionary(); - readonly ConcurrentDictionary adsflagtoggle = new ConcurrentDictionary(); readonly ConcurrentDictionary mntflagtoggle = new ConcurrentDictionary(); readonly ConcurrentDictionary downlink = new ConcurrentDictionary(); // key: callsign, value: acknowledged status - readonly ConcurrentDictionary acknowledgedConflicts = new ConcurrentDictionary(); + readonly ConcurrentDictionary advisoryConflict = new ConcurrentDictionary(); + readonly ConcurrentDictionary imminentConflict = new ConcurrentDictionary(); public AuroraLabelItemsPlugin() { @@ -98,9 +104,11 @@ public void OnFDRUpdate(FDP2.FDR updated) mntflagValues.TryRemove(updated.Callsign, out _); altValues.TryRemove(updated.Callsign, out _); radartoggle.TryRemove(updated.Callsign, out _); - adsflagtoggle.TryRemove(updated.Callsign, out _); mntflagtoggle.TryRemove(updated.Callsign, out _); downlink.TryRemove(updated.Callsign, out _); + advisoryConflict.TryRemove(updated.Callsign, out _); + imminentConflict.TryRemove(updated.Callsign, out _); + } else { @@ -180,7 +188,7 @@ public void OnFDRUpdate(FDP2.FDR updated) } } } - + public class Segment { public string callsign; @@ -190,7 +198,7 @@ public class Segment public DateTime endTime = DateTime.MaxValue; public FDP2.FDR.ExtractedRoute.Segment routeSegment; } - + private static List CreatePolygon(Coordinate point1, Coordinate point2, int value) { List polygon = new List(); @@ -212,7 +220,7 @@ private static List CreatePolygon(Coordinate point1, Coordinate poin polygon.Add(polygon[0]); return polygon; } - + private static List CalculatePolygonIntersections( List polygon, Coordinate point1, @@ -333,25 +341,37 @@ private void ProbeStandardConflict(FDP2.FDR fdr, int value) cfl2 > FDP2.RVSM_BAND_UPPER ? 2000 : 1000; - + if (delta < requiredAltSep) { var segments1 = CalculateAreaOfConflict(fdr, fdr2, value); // var segments2 = CalculateAreaOfConflict(fdr2, fdr, value); - if (segments1.Count > 0) + segments1.Sort((Comparison)((s, t) => s.startTime.CompareTo(t.startTime))); + var firstConflictTime = segments1.FirstOrDefault(); + var timeDiff = firstConflictTime != null + ? new DateTime().Subtract(firstConflictTime.startTime) + : TimeSpan.MaxValue; + var advisoryConflicts = timeDiff.CompareTo(new TimeSpan(0, 2, 0, 0, 0)) < 31; + var imminentConflicts = timeDiff.CompareTo(new TimeSpan(0, 0, 30, 0, 0)) < 0; + if (advisoryConflicts) { // auto acknowledge - acknowledgedConflicts.AddOrUpdate(fdr.Callsign, true, (k, v) => true); - acknowledgedConflicts.AddOrUpdate(fdr.Callsign, true, (k, v) => true); + advisoryConflict.AddOrUpdate(fdr.Callsign, true, (k, v) => true); + } + if (imminentConflicts) + { + imminentConflict.AddOrUpdate(fdr.Callsign, true, (k, v) => true); } else { - acknowledgedConflicts.TryRemove(fdr.Callsign, out never); + advisoryConflict.TryRemove(fdr.Callsign, out never); + imminentConflict.TryRemove(fdr.Callsign, out never); } } else { - acknowledgedConflicts.TryRemove(fdr.Callsign, out never); + advisoryConflict.TryRemove(fdr.Callsign, out never); + imminentConflict.TryRemove(fdr.Callsign, out never); } } } @@ -362,6 +382,7 @@ private static void AutoAssume(RDP.RadarTrack rt) if (fdr != null) { AutoAssume(fdr); + RDP.Couple(fdr, rt); } } @@ -371,7 +392,7 @@ private static void AutoAssume(FDP2.FDR fdr) { if (!fdr.ESTed && fdr.ControllingSector == null && MMI.IsMySectorConcerned(fdr)) { - MMI.EstFDR(fdr); + MMI.EstFDR(fdr); } if (MMI.SectorsControlled.ToList() @@ -394,12 +415,15 @@ private static void AutoDrop(RDP.RadarTrack rt) private static void AutoDrop(FDP2.FDR fdr) { + var rt = fdr.CoupledTrack; if (fdr != null) { if (fdr.IsTrackedByMe && MMI.SectorsControlled.ToList() .TrueForAll(s => !s.IsInSector(fdr.GetLocation(), fdr.PRL))) { MMI.HandoffToNone(fdr); + //Thread.Sleep(300000); + //RDP.DeCouple(rt); } } } @@ -429,37 +453,37 @@ private void HandleRadarFlagClick(CustomLabelItemMouseClickEventArgs e) e.Handled = true; } - private void HandleADSFlagClick(CustomLabelItemMouseClickEventArgs e) - { - bool adsflagToggled = radartoggle.TryGetValue(e.Track.GetFDR().Callsign, out _); - - if (adsflagToggled) - { - adsflagtoggle.TryRemove(e.Track.GetFDR().Callsign, out _); - } - else - { - adsflagtoggle.TryAdd(e.Track.GetFDR().Callsign, 0); - } - - e.Handled = true; - } - - private void HandleMNTFlagClick(CustomLabelItemMouseClickEventArgs e) - { - bool mntflagToggled = radartoggle.TryGetValue(e.Track.GetFDR().Callsign, out _); - - if (mntflagToggled) - { - mntflagtoggle.TryRemove(e.Track.GetFDR().Callsign, out _); - } - else - { - mntflagtoggle.TryAdd(e.Track.GetFDR().Callsign, 0); - } - - e.Handled = true; - } + //private void HandleADSFlagClick(CustomLabelItemMouseClickEventArgs e) + //{ + // bool adsflagToggled = radartoggle.TryGetValue(e.Track.GetFDR().Callsign, out _); + // + // if (adsflagToggled) + // { + // adsflagtoggle.TryRemove(e.Track.GetFDR().Callsign, out _); + // } + // else + // { + // adsflagtoggle.TryAdd(e.Track.GetFDR().Callsign, 0); + // } + // + // e.Handled = true; + //} + // + //private void HandleMNTFlagClick(CustomLabelItemMouseClickEventArgs e) + //{ + // bool mntflagToggled = radartoggle.TryGetValue(e.Track.GetFDR().Callsign, out _); + // + // if (mntflagToggled) + // { + // mntflagtoggle.TryRemove(e.Track.GetFDR().Callsign, out _); + // } + // else + // { + // mntflagtoggle.TryAdd(e.Track.GetFDR().Callsign, 0); + // } + // + // e.Handled = true; + //} /// vatSys calls this function when it encounters a custom label item (defined in Labels.xml) during the label rendering. /// itemType is the value of the Type attribute in Labels.xml @@ -481,22 +505,23 @@ public CustomLabelItem GetCustomLabelItem(string itemType, Track track, FDP2.FDR altValues.TryGetValue(flightDataRecord.Callsign, out h1); bool radarToggled = radartoggle.TryGetValue(flightDataRecord.Callsign, out _); - bool adsflagToggled = adsflagtoggle.TryGetValue(flightDataRecord.Callsign, out _); bool mntflagToggled = mntflagtoggle.TryGetValue(flightDataRecord.Callsign, out _); bool downLink = downlink.TryGetValue(flightDataRecord.Callsign, out _); bool selectedCallsign = MMI.SelectedTrack?.GetFDR()?.Callsign == flightDataRecord.Callsign; - + bool isAdvisory = advisoryConflict.TryGetValue(flightDataRecord.Callsign, out _); + bool isImminent = imminentConflict.TryGetValue(flightDataRecord.Callsign, out _); switch (itemType) { case LABEL_ITEM_SELECT_HORI: - if (selectedCallsign) + if (selectedCallsign)// || isAdvisory || isImminent) { return new CustomLabelItem() { - Border = BorderFlags.Top + Border = BorderFlags.Top, + //CustomBorderColour = isAdvisory ? Advisory : null }; } @@ -505,18 +530,20 @@ public CustomLabelItem GetCustomLabelItem(string itemType, Track track, FDP2.FDR return new CustomLabelItem() { - Border = BorderFlags.None + Border = BorderFlags.None, + }; } case LABEL_ITEM_SELECT_VERT: - if (selectedCallsign) + if (selectedCallsign)// || isAdvisory || isImminent) { return new CustomLabelItem() { Text = "", - Border = BorderFlags.Left + Border = BorderFlags.Left, + //CustomBorderColour = isAdvisory ? Advisory : null }; } @@ -525,7 +552,7 @@ public CustomLabelItem GetCustomLabelItem(string itemType, Track track, FDP2.FDR return new CustomLabelItem() { Text = "", - Border = BorderFlags.None + Border = BorderFlags.None, }; } @@ -570,21 +597,11 @@ public CustomLabelItem GetCustomLabelItem(string itemType, Track track, FDP2.FDR case LABEL_ITEM_ADS_FLAGS: - if (adsflagToggled) - { return new CustomLabelItem() { - Text = c2.ToString(), - OnMouseClick = HandleADSFlagClick, + Text = c2.ToString() }; - } - else - return new CustomLabelItem() - { - Text = "", - OnMouseClick = HandleADSFlagClick, - }; case LABEL_ITEM_MNT_FLAGS: @@ -592,8 +609,7 @@ public CustomLabelItem GetCustomLabelItem(string itemType, Track track, FDP2.FDR { return new CustomLabelItem() { - Text = c3.ToString(), - OnMouseClick = HandleMNTFlagClick, + Text = c3.ToString() }; } @@ -601,7 +617,6 @@ public CustomLabelItem GetCustomLabelItem(string itemType, Track track, FDP2.FDR return new CustomLabelItem() { Text = "", - OnMouseClick = HandleMNTFlagClick, }; @@ -669,7 +684,7 @@ public CustomLabelItem GetCustomLabelItem(string itemType, Track track, FDP2.FDR return new CustomLabelItem() { - Text = (track.NewCFL && radarTrack.ReachedCFL) ? string.Empty : flightDataRecord.CFLString, + Text = (track.NewCFL == radarTrack.ReachedCFL) ? string.Empty : flightDataRecord.CFLString, ForeColourIdentity = Colours.Identities.Custom, CustomForeColour = !flightDataRecord.RVSM ? NonRVSM : Probe }; @@ -720,17 +735,24 @@ public CustomLabelItem GetCustomLabelItem(string itemType, Track track, FDP2.FDR public CustomColour SelectASDTrackColour(Track track) { - //only apply East/West colour to jurisdiction state - if (track.State != MMI.HMIStates.Jurisdiction) - return null; - var fdr = track.GetFDR(); //if track doesn't have an FDR coupled do nothing if (fdr == null) return null; - //read our dictionary of stored bools (true means is easterly) and return the correct colour - return GetDirectionColour(fdr.Callsign); + + + //only apply East/West colour to jurisdiction state + if (track.State == MMI.HMIStates.Jurisdiction) + + //read our dictionary of stored bools (true means is easterly) and return the correct colour + return GetDirectionColour(fdr.Callsign); + + if (MMI.IsMySectorConcerned(fdr)) + return GetConflictColour(fdr.Callsign); + + return null; + } public CustomColour SelectGroundTrackColour(Track track) @@ -750,5 +772,20 @@ private CustomColour GetDirectionColour(string callsign) return null; } + + private CustomColour GetConflictColour(string callsign) + { + if (advisoryConflict.TryGetValue(callsign, out _)) + { + return Advisory; + } + + if (imminentConflict.TryGetValue(callsign, out _)) + { + return Imminent; + } + + return null; + } } } \ No newline at end of file From c8cf60ffd1a7edc8c8c3149a44b95253a0e4727e Mon Sep 17 00:00:00 2001 From: Dominic Nguyen Date: Mon, 14 Aug 2023 17:51:02 -0700 Subject: [PATCH 25/76] Introducing.... 1 sided conflict --- AuroraLabelItemsPlugin.cs | 260 +++++++++++++++++++------------------- AuroraStripItemPlugin.cs | 59 ++++++--- 2 files changed, 172 insertions(+), 147 deletions(-) diff --git a/AuroraLabelItemsPlugin.cs b/AuroraLabelItemsPlugin.cs index 3f29dff..7e0c3a8 100644 --- a/AuroraLabelItemsPlugin.cs +++ b/AuroraLabelItemsPlugin.cs @@ -3,9 +3,7 @@ using System.Collections.Concurrent; using System.Collections.Generic; using System.ComponentModel.Composition; -using System.Diagnostics; using System.Linq; //<--Need to add a reference to System.ComponentModel.Composition -using System.Runtime.CompilerServices; using System.Text.RegularExpressions; using vatsys; using vatsys.Plugin; @@ -22,7 +20,6 @@ public class AuroraLabelItemsPlugin : ILabelPlugin /// The name of the custom label item we've added to Labels /// in the Profile const string LABEL_ITEM_SELECT_HORI = "SELECT_HORI"; - const string LABEL_ITEM_SELECT_VERT = "SELECT_VERT"; const string LABEL_ITEM_COMM_ICON = "AURORA_COMM_ICON"; //field a(2) const string LABEL_ITEM_ADSB_CPDLC = "AURORA_ADSB_CPDLC"; //field c(4) @@ -41,8 +38,8 @@ public class AuroraLabelItemsPlugin : ILabelPlugin readonly static CustomColour NonRVSM = new CustomColour(242, 133, 0); readonly static CustomColour Probe = new CustomColour(0, 255, 0); readonly static CustomColour NotCDA = new CustomColour(100, 0, 100); - readonly static CustomColour Advisory = new CustomColour(255, 0, 0); - readonly static CustomColour Imminent = new CustomColour(255, 165, 0); + readonly static CustomColour Advisory = new CustomColour(255, 165, 0); + readonly static CustomColour Imminent = new CustomColour(255, 0, 0); readonly ConcurrentDictionary eastboundCallsigns = new ConcurrentDictionary(); readonly ConcurrentDictionary adsbcpdlcValues = new ConcurrentDictionary(); readonly ConcurrentDictionary adsflagValues = new ConcurrentDictionary(); @@ -59,6 +56,7 @@ public AuroraLabelItemsPlugin() { Network.PrivateMessagesChanged += Network_PrivateMessagesChanged; Network.RadioMessageAcknowledged += Network_RadioMessageAcknowledged; + } @@ -81,6 +79,7 @@ private void Network_PrivateMessagesChanged(object sender, Network.GenericMessag } } + /// Plugin Name public string Name { @@ -93,9 +92,33 @@ public string Name /// the flight planned PBN category and store the character we want to display in the label in the dictionary. public void OnFDRUpdate(FDP2.FDR updated) { + Match pbn = Regex.Match(updated.Remarks, @"PBN\/\w+\s"); + bool rnp10 = Regex.IsMatch(pbn.Value, @"A1"); + bool rnp4 = Regex.IsMatch(pbn.Value, @"L1"); + bool cpdlc = Regex.IsMatch(updated.AircraftEquip, @"J5") || Regex.IsMatch(updated.AircraftEquip, @"J7"); + bool adsc = Regex.IsMatch(updated.AircraftSurvEquip, @"D1"); + bool jet = updated.PerformanceData?.IsJet ?? false; + var vs = updated.PredictedPosition.VerticalSpeed; + int prl = updated.PRL / 100; + int cfl = updated.CFLUpper; + int rfl = updated.RFL; + int alt = cfl == -1 ? rfl : cfl; + AutoAssume(updated); AutoDrop(updated); - ProbeStandardConflict(updated, 23); + if (jet & rnp4 & cpdlc & adsc) + { + ConflictProbe(updated, 23); + } + else if (rnp4 || rnp10) + { + ConflictProbe(updated, 50); + } + else + { + ConflictProbe(updated, 100); + } + if (FDP2.GetFDRIndex(updated.Callsign) == -1) { eastboundCallsigns.TryRemove(updated.Callsign, out _); @@ -112,15 +135,7 @@ public void OnFDRUpdate(FDP2.FDR updated) } else { - Match pbn = Regex.Match(updated.Remarks, @"PBN\/\w+\s"); - bool rnp10 = Regex.IsMatch(pbn.Value, @"A1"); - bool rnp4 = Regex.IsMatch(pbn.Value, @"L1"); - bool cpdlc = Regex.IsMatch(updated.AircraftEquip, @"J5") || Regex.IsMatch(updated.AircraftEquip, @"J7"); - bool adsc = Regex.IsMatch(updated.AircraftSurvEquip, @"D1"); - int cfl; - bool isCfl = Int32.TryParse(updated.CFLString, out cfl); - var vs = updated.PredictedPosition.VerticalSpeed; - int level = updated.PRL / 100; + char c1 = default; @@ -134,7 +149,7 @@ public void OnFDRUpdate(FDP2.FDR updated) else if (cpdlc) - c1 = '*'; + c1 = '✱'; adsbcpdlcValues.AddOrUpdate(updated.Callsign, c1, (k, v) => c1); @@ -151,7 +166,7 @@ public void OnFDRUpdate(FDP2.FDR updated) char c3 = default; - if (AuroraStripItemsPlugin.AuroraStripItemsPlugin.MachNumberTech(updated.PerformanceData)) + if (updated.PerformanceData?.IsJet ?? false) c3 = 'M'; mntflagValues.AddOrUpdate(updated.Callsign, c3, (k, v) => c3); @@ -159,19 +174,19 @@ public void OnFDRUpdate(FDP2.FDR updated) char h1 = default; - if (level == cfl || level == updated.RFL) //level + if (prl == alt) //level flight h1 = default; - else if (cfl > level || vs > 300) //Issued or trending climb + else if (alt / 100 > prl || vs > 300) //Issued or trending climb h1 = '↑'; - else if (cfl > 0 && cfl < level || vs < -300) //Issued or trending descent + else if (alt / 100 > 0 && alt < prl || vs < -300) //Issued or trending descent h1 = '↓'; - else if (level - updated.RFL / 100 >= 3) //deviating above + else if (prl - alt / 100 >= 3) //deviating above h1 = '+'; - else if (level - updated.RFL / 100 <= -3) //deviating below + else if (prl - alt / 100 <= -3) //deviating below h1 = '-'; @@ -317,63 +332,64 @@ private static List CalculateAreaOfConflict(FDP2.FDR fdr1, FDP2.FDR fdr return segs; } - private void ProbeStandardConflict(FDP2.FDR fdr, int value) + public void ConflictProbe(FDP2.FDR fdr, int value) { if (fdr == null) return; - int cfl; - bool isCfl = Int32.TryParse(fdr.CFLString, out cfl); - if (!isCfl) return; + int cfl = fdr.CFLUpper; + int rfl = fdr.RFL; + int alt = cfl == -1 ? rfl : cfl; + var isRvsm = fdr.RVSM; - bool never; + bool clean; foreach (var fdr2 in FDP2.GetFDRs) { if (fdr2 == null || fdr.Callsign == fdr2.Callsign || !MMI.IsMySectorConcerned(fdr2)) continue; - int cfl2; - bool isCfl2 = Int32.TryParse(fdr.CFLString, out cfl2); - if (!isCfl2) continue; + int cfl2 = fdr2.CFLUpper; + int rfl2 = fdr2.RFL; + int alt2 = cfl2 == -1 ? rfl2 : cfl2; var isRvsm2 = fdr2.RVSM; - var delta = Math.Abs(cfl - cfl2); - int requiredAltSep = (cfl > FDP2.RVSM_BAND_LOWER && !isRvsm) || - (cfl2 > FDP2.RVSM_BAND_LOWER && !isRvsm2) || cfl > FDP2.RVSM_BAND_UPPER || - cfl2 > FDP2.RVSM_BAND_UPPER + var delta = Math.Abs(alt - alt2); + int verticalSep = (alt > FDP2.RVSM_BAND_LOWER && !isRvsm) || + (alt2 > FDP2.RVSM_BAND_LOWER && !isRvsm2) || alt > FDP2.RVSM_BAND_UPPER || + alt2 > FDP2.RVSM_BAND_UPPER ? 2000 : 1000; - if (delta < requiredAltSep) + if (delta < verticalSep) { var segments1 = CalculateAreaOfConflict(fdr, fdr2, value); - // var segments2 = CalculateAreaOfConflict(fdr2, fdr, value); - segments1.Sort((Comparison)((s, t) => s.startTime.CompareTo(t.startTime))); + segments1.Sort((Comparison)((s, t) => s.startTime.CompareTo(t.startTime))); //sort by first conflict time var firstConflictTime = segments1.FirstOrDefault(); var timeDiff = firstConflictTime != null ? new DateTime().Subtract(firstConflictTime.startTime) - : TimeSpan.MaxValue; - var advisoryConflicts = timeDiff.CompareTo(new TimeSpan(0, 2, 0, 0, 0)) < 31; - var imminentConflicts = timeDiff.CompareTo(new TimeSpan(0, 0, 30, 0, 0)) < 0; - if (advisoryConflicts) - { - // auto acknowledge - advisoryConflict.AddOrUpdate(fdr.Callsign, true, (k, v) => true); - } + : TimeSpan.MaxValue; //how much time before conflict resolution + var advisoryConflicts = timeDiff.CompareTo(new TimeSpan(0, 2, 0, 0, 0)) < 0; //check if timediff < 2 hours + var imminentConflicts = timeDiff.CompareTo(new TimeSpan(0, 0, 30, 0, 0)) < 0; //check if timediff < 30 mins + if (imminentConflicts) { imminentConflict.AddOrUpdate(fdr.Callsign, true, (k, v) => true); + imminentConflict.AddOrUpdate(fdr2.Callsign, true, (k, v) => true); + } - else + if (advisoryConflicts) { - advisoryConflict.TryRemove(fdr.Callsign, out never); - imminentConflict.TryRemove(fdr.Callsign, out never); + // auto acknowledge + advisoryConflict.AddOrUpdate(fdr.Callsign, true, (k, v) => true); + advisoryConflict.AddOrUpdate(fdr2.Callsign, true, (k, v) => true); } - } - else - { - advisoryConflict.TryRemove(fdr.Callsign, out never); - imminentConflict.TryRemove(fdr.Callsign, out never); - } - } + } + else + { + advisoryConflict.TryRemove(fdr.Callsign, out clean); + advisoryConflict.TryRemove(fdr2.Callsign, out clean); + imminentConflict.TryRemove(fdr.Callsign, out clean); + imminentConflict.TryRemove(fdr2.Callsign, out clean); + } + } } private static void AutoAssume(RDP.RadarTrack rt) @@ -390,7 +406,7 @@ private static void AutoAssume(FDP2.FDR fdr) { if (fdr != null) { - if (!fdr.ESTed && fdr.ControllingSector == null && MMI.IsMySectorConcerned(fdr)) + if (!fdr.ESTed && MMI.IsMySectorConcerned(fdr)) { MMI.EstFDR(fdr); } @@ -407,7 +423,7 @@ private static void AutoAssume(FDP2.FDR fdr) private static void AutoDrop(RDP.RadarTrack rt) { var fdr = rt.CoupledFDR; - if (fdr != null) + if (fdr != null && rt != null) { AutoDrop(fdr); } @@ -416,14 +432,15 @@ private static void AutoDrop(RDP.RadarTrack rt) private static void AutoDrop(FDP2.FDR fdr) { var rt = fdr.CoupledTrack; - if (fdr != null) - { - if (fdr.IsTrackedByMe && MMI.SectorsControlled.ToList() - .TrueForAll(s => !s.IsInSector(fdr.GetLocation(), fdr.PRL))) + if (fdr != null && rt != null) + { + if (fdr.IsTrackedByMe && MMI.GetSectorEntryTime(fdr) < DateTime.Now && MMI.SectorsControlled.ToList() + .TrueForAll(s => !s.IsInSector(fdr.GetLocation(), fdr.PRL))) //MMI.GetSectorEntryTime(fdr) == null { MMI.HandoffToNone(fdr); - //Thread.Sleep(300000); - //RDP.DeCouple(rt); + //MMI.Inhibit(fdr); + Thread.Sleep(300000); + RDP.DeCouple(rt); } } } @@ -453,37 +470,7 @@ private void HandleRadarFlagClick(CustomLabelItemMouseClickEventArgs e) e.Handled = true; } - //private void HandleADSFlagClick(CustomLabelItemMouseClickEventArgs e) - //{ - // bool adsflagToggled = radartoggle.TryGetValue(e.Track.GetFDR().Callsign, out _); - // - // if (adsflagToggled) - // { - // adsflagtoggle.TryRemove(e.Track.GetFDR().Callsign, out _); - // } - // else - // { - // adsflagtoggle.TryAdd(e.Track.GetFDR().Callsign, 0); - // } - // - // e.Handled = true; - //} - // - //private void HandleMNTFlagClick(CustomLabelItemMouseClickEventArgs e) - //{ - // bool mntflagToggled = radartoggle.TryGetValue(e.Track.GetFDR().Callsign, out _); - // - // if (mntflagToggled) - // { - // mntflagtoggle.TryRemove(e.Track.GetFDR().Callsign, out _); - // } - // else - // { - // mntflagtoggle.TryAdd(e.Track.GetFDR().Callsign, 0); - // } - // - // e.Handled = true; - //} + /// vatSys calls this function when it encounters a custom label item (defined in Labels.xml) during the label rendering. /// itemType is the value of the Type attribute in Labels.xml @@ -492,7 +479,7 @@ private void HandleRadarFlagClick(CustomLabelItemMouseClickEventArgs e) public CustomLabelItem GetCustomLabelItem(string itemType, Track track, FDP2.FDR flightDataRecord, RDP.RadarTrack radarTrack) { - if (flightDataRecord == null || track == null) + if (flightDataRecord == null && track == null) return null; char c1; @@ -510,18 +497,22 @@ public CustomLabelItem GetCustomLabelItem(string itemType, Track track, FDP2.FDR bool selectedCallsign = MMI.SelectedTrack?.GetFDR()?.Callsign == flightDataRecord.Callsign; bool isAdvisory = advisoryConflict.TryGetValue(flightDataRecord.Callsign, out _); bool isImminent = imminentConflict.TryGetValue(flightDataRecord.Callsign, out _); + bool isNonRVSM = !flightDataRecord.RVSM; + int prl = flightDataRecord.PRL / 100; + int cfl = flightDataRecord.CFLUpper / 100; + int rfl = flightDataRecord.RFL / 100; + int alt = flightDataRecord.CFLUpper == -1 ? rfl : cfl; switch (itemType) { case LABEL_ITEM_SELECT_HORI: - if (selectedCallsign)// || isAdvisory || isImminent) + if (selectedCallsign) { return new CustomLabelItem() { Border = BorderFlags.Top, - //CustomBorderColour = isAdvisory ? Advisory : null }; } @@ -537,13 +528,12 @@ public CustomLabelItem GetCustomLabelItem(string itemType, Track track, FDP2.FDR case LABEL_ITEM_SELECT_VERT: - if (selectedCallsign)// || isAdvisory || isImminent) + if (selectedCallsign) { return new CustomLabelItem() { Text = "", Border = BorderFlags.Left, - //CustomBorderColour = isAdvisory ? Advisory : null }; } @@ -576,7 +566,7 @@ public CustomLabelItem GetCustomLabelItem(string itemType, Track track, FDP2.FDR case LABEL_ITEM_ADSB_CPDLC: bool useCustomForeColour = - track.State == MMI.HMIStates.Preactive || track.State == MMI.HMIStates.Announced; + flightDataRecord.State == (FDR.FDRStates.STATE_PREACTIVE | FDR.FDRStates.STATE_COORDINATED); if (useCustomForeColour) { @@ -596,13 +586,15 @@ public CustomLabelItem GetCustomLabelItem(string itemType, Track track, FDP2.FDR } case LABEL_ITEM_ADS_FLAGS: - + return new CustomLabelItem() { - Text = c2.ToString() + Text = c2.ToString(), + }; + case LABEL_ITEM_MNT_FLAGS: if (mntflagToggled) @@ -624,7 +616,7 @@ public CustomLabelItem GetCustomLabelItem(string itemType, Track track, FDP2.FDR // // return new CustomLabelItem() // { - // Text = pos //| ca | la | ra | rcf | dup | spd + // Text = pos | ca | la | ra | rcf | dup | spd // }; @@ -660,34 +652,44 @@ public CustomLabelItem GetCustomLabelItem(string itemType, Track track, FDP2.FDR return null; case LABEL_ITEM_VMI: - bool isNonRVSMOrNewCFL = !flightDataRecord.RVSM || track.NewCFL; - - if (isNonRVSMOrNewCFL) - { + return new CustomLabelItem() { Text = h1.ToString(), - ForeColourIdentity = Colours.Identities.Custom, - CustomForeColour = !flightDataRecord.RVSM ? NonRVSM : Probe + ForeColourIdentity = isNonRVSM + ? Colours.Identities.Custom + : default, + CustomForeColour = NonRVSM }; - } + + + + case LABEL_ITEM_CLEARED_LEVEL: + + if (radarTrack != null && radarTrack.ReachedCFL || prl == alt) //track.NewCFL + return new CustomLabelItem() + { + Text = "" + }; + else { return new CustomLabelItem() { - Text = h1.ToString() + Text = alt.ToString(), + ForeColourIdentity = isNonRVSM + ? Colours.Identities.Custom + : default, + CustomForeColour = NonRVSM, + Border = flightDataRecord.State == (FDR.FDRStates.STATE_PREACTIVE | FDR.FDRStates.STATE_COORDINATED) + ? BorderFlags.All + : BorderFlags.None, + BorderColourIdentity = Colours.Identities.Custom, + CustomBorderColour = NotCDA }; } - case LABEL_ITEM_CLEARED_LEVEL: - - return new CustomLabelItem() - { - Text = (track.NewCFL == radarTrack.ReachedCFL) ? string.Empty : flightDataRecord.CFLString, - ForeColourIdentity = Colours.Identities.Custom, - CustomForeColour = !flightDataRecord.RVSM ? NonRVSM : Probe - }; case LABEL_ITEM_RADAR_IND: @@ -711,7 +713,7 @@ public CustomLabelItem GetCustomLabelItem(string itemType, Track track, FDP2.FDR } case LABEL_ITEM_FILED_SPEED: - var mach = flightDataRecord.TAS / 581.0; + var mach = Conversions.CalculateMach(flightDataRecord.TAS, GRIB.FindTemperature(flightDataRecord.PRL, track.GetLocation(), true)); return new CustomLabelItem() { Text = "M" + Convert.ToDecimal(mach).ToString("F2").Replace(".", "") @@ -740,18 +742,22 @@ public CustomColour SelectASDTrackColour(Track track) if (fdr == null) return null; - - + //only apply East/West colour to jurisdiction state - if (track.State == MMI.HMIStates.Jurisdiction) - - //read our dictionary of stored bools (true means is easterly) and return the correct colour + if (track.State == MMI.HMIStates.Jurisdiction) //read our dictionary of stored bools (true means is easterly) and return the correct colour + { + return GetDirectionColour(fdr.Callsign); + } - if (MMI.IsMySectorConcerned(fdr)) + if (MMI.IsMySectorConcerned(fdr) && fdr.State != (FDR.FDRStates.STATE_PREACTIVE | FDR.FDRStates.STATE_COORDINATED)) //only apply conflict colours if planes are of concern + { return GetConflictColour(fdr.Callsign); + } - return null; + else + + return default; } diff --git a/AuroraStripItemPlugin.cs b/AuroraStripItemPlugin.cs index 725949c..830eaf7 100644 --- a/AuroraStripItemPlugin.cs +++ b/AuroraStripItemPlugin.cs @@ -7,6 +7,9 @@ using System.ComponentModel.Composition; //<--Need to add a reference to System.ComponentModel.Composition using static vatsys.Performance; using static vatsys.Network; +using static vatsys.FDP2; +using System.Linq; +using static vatsys.SectorsVolumes; namespace AuroraStripItemsPlugin { @@ -66,11 +69,6 @@ public void OnRadarTrackUpdate(RDP.RadarTrack updated) { } - public static bool MachNumberTech(PerformanceData mnt) - { - if (mnt == null) return false; - return mnt.IsJet; - } //public void Estimates(FDP2.FDR.ExtractedRoute.Segment estimate) //{ @@ -107,7 +105,7 @@ public CustomStripItem GetCustomStripItem(string itemType, Track track, FDP2.FDR bool isEastBound = true; - if (flightDataRecord is null) + if (flightDataRecord == null) return null; switch (itemType) @@ -137,25 +135,46 @@ public CustomStripItem GetCustomStripItem(string itemType, Track track, FDP2.FDR case STRIP_ITEM_CTLSECTOR: - bool pendingCoordination = track.State == MMI.HMIStates.Preactive || track.State == MMI.HMIStates.Announced; + bool pendingCoordination = flightDataRecord.State == (FDR.FDRStates.STATE_PREACTIVE | FDR.FDRStates.STATE_COORDINATED); + if (pendingCoordination) + { return new CustomStripItem() { - ForeColourIdentity = pendingCoordination ? Colours.Identities.Custom : default, + ForeColourIdentity = Colours.Identities.Custom, CustomForeColour = Pending, - Text = flightDataRecord.ControllingSector != null ? flightDataRecord.ControllingSector.Name : null + Text = flightDataRecord.ControllingSector.Name ?? null + }; + } + else + { + return new CustomStripItem() + { + Text = flightDataRecord.ControllingSector.Name ?? null }; + } + - // case STRIP_ITEM_NXTSECTOR: - // - // return new CustomStripItem() - // { - // ForeColourIdentity = Colours.Identities.Custom, - // CustomForeColour = Pending, - // Text = - // }; - + //case STRIP_ITEM_NXTSECTOR: + // + // var zpoints = flightDataRecord.ParsedRoute.ToList().Where(s => s.Type == FDP2.FDR.ExtractedRoute.Segment.SegmentTypes.ZPOINT); + // + // foreach (var zpoint in zpoints) + // + // { + // if (zpoint.ETO > DateTime.UtcNow) + // { + // SectorsVolumes.Sector sector = SectorsVolumes.FindSector(); + // } + // } + // return new CustomStripItem() + // { + // ForeColourIdentity = Colours.Identities.Custom, + // CustomForeColour = Pending, + // Text = + // }; + case LABEL_ITEM_ADSB_CPDLC: @@ -196,7 +215,7 @@ public CustomStripItem GetCustomStripItem(string itemType, Track track, FDP2.FDR case STRIP_ITEM_T10_FLAG: - if (MachNumberTech(flightDataRecord.PerformanceData)) + if (flightDataRecord.PerformanceData?.IsJet ?? false) return new CustomStripItem() { @@ -210,7 +229,7 @@ public CustomStripItem GetCustomStripItem(string itemType, Track track, FDP2.FDR case STRIP_ITEM_MNT_FLAG: - if (MachNumberTech(flightDataRecord.PerformanceData)) + if (flightDataRecord.PerformanceData?.IsJet ?? false) return new CustomStripItem() { From 4388ee7b4ae225e5d63e073b9c723c4dba51df47 Mon Sep 17 00:00:00 2001 From: Dominic Nguyen Date: Sun, 27 Aug 2023 10:15:57 -0700 Subject: [PATCH 26/76] The SalikhovSloth --- AuroraLabelItemsPlugin.cs | 465 ++++++++++++++++++++------------------ 1 file changed, 240 insertions(+), 225 deletions(-) diff --git a/AuroraLabelItemsPlugin.cs b/AuroraLabelItemsPlugin.cs index 7e0c3a8..cce010e 100644 --- a/AuroraLabelItemsPlugin.cs +++ b/AuroraLabelItemsPlugin.cs @@ -1,14 +1,13 @@ using System; using System.Threading; using System.Collections.Concurrent; -using System.Collections.Generic; using System.ComponentModel.Composition; using System.Linq; //<--Need to add a reference to System.ComponentModel.Composition using System.Text.RegularExpressions; using vatsys; using vatsys.Plugin; using static vatsys.FDP2; - +using System.Linq.Expressions; //Note the reference to vatsys (set Copy Local to false) -----> @@ -28,9 +27,12 @@ public class AuroraLabelItemsPlugin : ILabelPlugin const string LABEL_ITEM_SCC = "AURORA_SCC"; //field c(5) const string LABEL_ITEM_ANNOT_IND = "AURORA_ANNOT_IND"; //field e(1) const string LABEL_ITEM_RESTR = "AURORA_RESTR"; //field f(1) + const string LABEL_ITEM_LEVEL = "AURORA_LEVEL"; //field g(3) const string LABEL_ITEM_VMI = "AURORA_VMI"; //field h(1) const string LABEL_ITEM_CLEARED_LEVEL = "AURORA_CLEARED_LEVEL"; //field i(7) + const string LABEL_ITEM_HANDOFF_IND = "AURORA_HO_IND"; //field j(4) const string LABEL_ITEM_RADAR_IND = "AURORA_RADAR_IND"; //field k(1) + const string LABEL_ITEM_INHIBIT_IND = "AURORA_INHIBIT_IND"; //field l(1) const string LABEL_ITEM_FILED_SPEED = "AURORA_FILEDSPEED"; //field m(4) const string LABEL_ITEM_3DIGIT_GROUNDSPEED = "AURORA_GROUNDSPEED"; //field n(5) readonly static CustomColour EastboundColour = new CustomColour(240, 255, 255); @@ -49,6 +51,8 @@ public class AuroraLabelItemsPlugin : ILabelPlugin readonly ConcurrentDictionary mntflagtoggle = new ConcurrentDictionary(); readonly ConcurrentDictionary downlink = new ConcurrentDictionary(); // key: callsign, value: acknowledged status + //readonly ConcurrentDictionary> advisoryConflict = new ConcurrentDictionary>(); + //readonly ConcurrentDictionary> imminentConflict = new ConcurrentDictionary>(); readonly ConcurrentDictionary advisoryConflict = new ConcurrentDictionary(); readonly ConcurrentDictionary imminentConflict = new ConcurrentDictionary(); @@ -56,7 +60,6 @@ public AuroraLabelItemsPlugin() { Network.PrivateMessagesChanged += Network_PrivateMessagesChanged; Network.RadioMessageAcknowledged += Network_RadioMessageAcknowledged; - } @@ -106,7 +109,8 @@ public void OnFDRUpdate(FDP2.FDR updated) AutoAssume(updated); AutoDrop(updated); - if (jet & rnp4 & cpdlc & adsc) + //ConflictProbe(updated); ///Using TimeOfPassing method + if (jet & rnp4 & cpdlc & adsc) ///Using CalculateAreaofConflict method { ConflictProbe(updated, 23); } @@ -204,146 +208,68 @@ public void OnFDRUpdate(FDP2.FDR updated) } } - public class Segment + private static void AutoAssume(RDP.RadarTrack rt) { - public string callsign; - public Coordinate startLatlong; - public Coordinate endLatlong; - public DateTime startTime = DateTime.MaxValue; - public DateTime endTime = DateTime.MaxValue; - public FDP2.FDR.ExtractedRoute.Segment routeSegment; + var fdr = rt.CoupledFDR; + if (fdr != null) + { + AutoAssume(fdr); + RDP.Couple(fdr, rt); + } } - private static List CreatePolygon(Coordinate point1, Coordinate point2, int value) + private static void AutoAssume(FDP2.FDR fdr) { - List polygon = new List(); - double track = Conversions.CalculateTrack(point1, point2); - double num1 = track - 90.0; - for (int index = 0; index <= 180; index += 10) - { - double heading = num1 - (double)index; - Coordinate fromBearingRange = Conversions.CalculateLLFromBearingRange(point1, (double)value, heading); - polygon.Add(fromBearingRange); - } - double num2 = track + 90.0; - for (int index = 0; index <= 180; index += 10) + if (fdr != null) { - double heading = num2 - (double)index; - Coordinate fromBearingRange = Conversions.CalculateLLFromBearingRange(point2, (double)value, heading); - polygon.Add(fromBearingRange); + if (!fdr.ESTed && MMI.IsMySectorConcerned(fdr)) + { + MMI.EstFDR(fdr); + } + + if (MMI.SectorsControlled.ToList() + .Exists(s => s.IsInSector(fdr.GetLocation(), fdr.PRL)) && !fdr.IsTrackedByMe && + MMI.SectorsControlled.Contains(fdr.ControllingSector) || fdr.ControllingSector == null) + { + MMI.AcceptJurisdiction(fdr); + } } - polygon.Add(polygon[0]); - return polygon; } - private static List CalculatePolygonIntersections( - List polygon, - Coordinate point1, - Coordinate point2) + private static void AutoDrop(RDP.RadarTrack rt) { - List polygonIntersections = new List(); - for (int index = 1; index < polygon.Count; ++index) - { - List gcIntersectionLl = Conversions.CalculateAllGCIntersectionLL(polygon[index - 1], polygon[index], point1, point2); - if (gcIntersectionLl != null) - polygonIntersections.AddRange(gcIntersectionLl); - } - for (int index = 0; index < polygonIntersections.Count; ++index) + var fdr = rt.CoupledFDR; + if (fdr != null && rt != null) { - Coordinate intsect = polygonIntersections[index]; - polygonIntersections.RemoveAll(c => c != intsect && Conversions.CalculateDistance(intsect, c) < 0.01); + AutoDrop(fdr); } - return polygonIntersections; } - private static List CalculateAreaOfConflict(FDP2.FDR fdr1, FDP2.FDR fdr2, int value) + private static void AutoDrop(FDP2.FDR fdr) { - List segs = new List(); - List route1waypoints = fdr1.ParsedRoute.ToList().Where(s => s.Type == FDP2.FDR.ExtractedRoute.Segment.SegmentTypes.WAYPOINT).ToList(); - List route2waypoints = fdr2.ParsedRoute.ToList().Where(s => s.Type == FDP2.FDR.ExtractedRoute.Segment.SegmentTypes.WAYPOINT).ToList(); - for (int wp1index = 1; wp1index < route1waypoints.Count; ++wp1index) + var rt = fdr.CoupledTrack; + if (fdr != null && rt != null) { - List route1Segment = CreatePolygon(route1waypoints[wp1index - 1].Intersection.LatLong, route1waypoints[wp1index].Intersection.LatLong, value); - for (int wp2index = 1; wp2index < route2waypoints.Count; wp2index++) + if (MMI.GetSectorEntryTime(fdr) == null && MMI.SectorsControlled.ToList() + .TrueForAll(s => !s.IsInSector(fdr.GetLocation(), fdr.PRL))) { - List source = new List(); - List intersectionPoints = new List(); - source.AddRange((IEnumerable)CalculatePolygonIntersections(route1Segment, route2waypoints[wp2index - 1].Intersection.LatLong, route2waypoints[wp2index].Intersection.LatLong)); - int num1 = 0; - int num2 = 0; - foreach (Coordinate coordinate in source.ToList()) - { - if (Conversions.IsLatLonOnGC(route2waypoints[wp2index - 1].Intersection.LatLong, route2waypoints[wp2index].Intersection.LatLong, coordinate)) - { - intersectionPoints.Add(coordinate); - } - else - { - double track = Conversions.CalculateTrack(route2waypoints[wp2index - 1].Intersection.LatLong, route2waypoints[wp2index].Intersection.LatLong); - if (Math.Abs(track - Conversions.CalculateTrack(route2waypoints[wp2index - 1].Intersection.LatLong, coordinate)) > 90.0) - ++num1; - if (Math.Abs(track - Conversions.CalculateTrack(coordinate, route2waypoints[wp2index].Intersection.LatLong)) > 90.0) - ++num2; - } - } - if (num1 % 2 != 0 && num2 % 2 != 0) - { - intersectionPoints.Clear(); - intersectionPoints.Add(route2waypoints[wp2index - 1].Intersection.LatLong); - intersectionPoints.Add(route2waypoints[wp2index].Intersection.LatLong); - } - else if (num2 % 2 != 0) - intersectionPoints.Add(route2waypoints[wp2index].Intersection.LatLong); - else if (num1 % 2 != 0) - intersectionPoints.Add(route2waypoints[wp2index - 1].Intersection.LatLong); - intersectionPoints.Sort((x, y) => Conversions.CalculateDistance(route2waypoints[wp2index - 1].Intersection.LatLong, x).CompareTo(Conversions.CalculateDistance(route2waypoints[wp2index - 1].Intersection.LatLong, y))); - for (int ipIndex = 1; ipIndex < intersectionPoints.Count; ipIndex += 2) - { - Segment seg = new Segment(); - seg.startLatlong = intersectionPoints[ipIndex - 1]; - seg.endLatlong = intersectionPoints[ipIndex]; - List conflictSegments = segs.Where((Func)(s => s.routeSegment == route2waypoints[wp2index])).Where((Func)(s => Conversions.CalculateDistance(s.startLatlong, route2waypoints[wp2index - 1].Intersection.LatLong) < Conversions.CalculateDistance(seg.startLatlong, route2waypoints[wp2index - 1].Intersection.LatLong) && Conversions.CalculateDistance(s.endLatlong, route2waypoints[wp2index - 1].Intersection.LatLong) > Conversions.CalculateDistance(seg.startLatlong, route2waypoints[wp2index - 1].Intersection.LatLong) || Conversions.CalculateDistance(s.endLatlong, route2waypoints[wp2index - 1].Intersection.LatLong) > Conversions.CalculateDistance(seg.endLatlong, route2waypoints[wp2index - 1].Intersection.LatLong) && Conversions.CalculateDistance(s.startLatlong, route2waypoints[wp2index - 1].Intersection.LatLong) < Conversions.CalculateDistance(seg.endLatlong, route2waypoints[wp2index - 1].Intersection.LatLong) || Conversions.CalculateDistance(s.startLatlong, route2waypoints[wp2index - 1].Intersection.LatLong) > Conversions.CalculateDistance(seg.startLatlong, route2waypoints[wp2index - 1].Intersection.LatLong) && Conversions.CalculateDistance(s.endLatlong, route2waypoints[wp2index - 1].Intersection.LatLong) < Conversions.CalculateDistance(seg.endLatlong, route2waypoints[wp2index - 1].Intersection.LatLong) || Conversions.CalculateDistance(s.startLatlong, seg.startLatlong) < 0.01 || Conversions.CalculateDistance(s.endLatlong, seg.endLatlong) < 0.01)).ToList(); - if (conflictSegments.Count > 0) - { - foreach (Segment segment in conflictSegments) - { - if (Conversions.CalculateDistance(segment.endLatlong, route2waypoints[wp2index - 1].Intersection.LatLong) < Conversions.CalculateDistance(seg.endLatlong, route2waypoints[wp2index - 1].Intersection.LatLong)) - segment.endLatlong = seg.endLatlong; - if (Conversions.CalculateDistance(seg.startLatlong, route2waypoints[wp2index - 1].Intersection.LatLong) < Conversions.CalculateDistance(segment.startLatlong, route2waypoints[wp2index - 1].Intersection.LatLong)) - segment.startLatlong = seg.startLatlong; - } - } - else - { - seg.callsign = fdr2.Callsign; - seg.routeSegment = route2waypoints[wp2index]; - segs.Add(seg); - } - } + MMI.HandoffToNone(fdr); + //MMI.Inhibit(fdr); + Thread.Sleep(300000); + RDP.DeCouple(rt); } } - for (int i = 0; i < segs.Count; i++) - { - if (!segs.Exists((Predicate)(s => Conversions.CalculateDistance(segs[i].startLatlong, s.endLatlong) < 0.01))) - segs[i].startTime = FDP2.GetSystemEstimateAtPosition(fdr2, segs[i].startLatlong, segs[i].routeSegment); - if (!segs.Exists((Predicate)(s => Conversions.CalculateDistance(segs[i].endLatlong, s.startLatlong) < 0.01))) - segs[i].endTime = FDP2.GetSystemEstimateAtPosition(fdr2, segs[i].endLatlong, segs[i].routeSegment); - } - return segs; } public void ConflictProbe(FDP2.FDR fdr, int value) { - if (fdr == null) return; + if ((fdr == null) || !MMI.IsMySectorConcerned(fdr)) return; int cfl = fdr.CFLUpper; int rfl = fdr.RFL; int alt = cfl == -1 ? rfl : cfl; - var isRvsm = fdr.RVSM; - bool clean; - foreach (var fdr2 in FDP2.GetFDRs) { if (fdr2 == null || fdr.Callsign == fdr2.Callsign || !MMI.IsMySectorConcerned(fdr2)) continue; @@ -352,98 +278,128 @@ public void ConflictProbe(FDP2.FDR fdr, int value) int alt2 = cfl2 == -1 ? rfl2 : cfl2; var isRvsm2 = fdr2.RVSM; var delta = Math.Abs(alt - alt2); - int verticalSep = (alt > FDP2.RVSM_BAND_LOWER && !isRvsm) || - (alt2 > FDP2.RVSM_BAND_LOWER && !isRvsm2) || alt > FDP2.RVSM_BAND_UPPER || - alt2 > FDP2.RVSM_BAND_UPPER + int verticalSep = (alt > 45000 && alt < 60000) ? 4000 : alt > 60000 ? 5000 : (alt2 > 45000 && alt2 < 60000) ? 4000 : alt2 > 60000 ? 5000 : + (alt > FDP2.RVSM_BAND_LOWER && !isRvsm) || + (alt2 > FDP2.RVSM_BAND_LOWER && !isRvsm2) || (alt > FDP2.RVSM_BAND_UPPER || alt2 > FDP2.RVSM_BAND_UPPER) ? 2000 : 1000; if (delta < verticalSep) { - var segments1 = CalculateAreaOfConflict(fdr, fdr2, value); - segments1.Sort((Comparison)((s, t) => s.startTime.CompareTo(t.startTime))); //sort by first conflict time - var firstConflictTime = segments1.FirstOrDefault(); - var timeDiff = firstConflictTime != null - ? new DateTime().Subtract(firstConflictTime.startTime) - : TimeSpan.MaxValue; //how much time before conflict resolution - var advisoryConflicts = timeDiff.CompareTo(new TimeSpan(0, 2, 0, 0, 0)) < 0; //check if timediff < 2 hours - var imminentConflicts = timeDiff.CompareTo(new TimeSpan(0, 0, 30, 0, 0)) < 0; //check if timediff < 30 mins - - if (imminentConflicts) + var anInstanceofCPAR = new CPAR(); + var segments1 = anInstanceofCPAR.CalculateAreaOfConflict(fdr, fdr2, value); + segments1.Sort((Comparison)((s, t) => s.startTime.CompareTo(t.startTime))); //sort by first conflict time + var firstConflictTime = segments1.FirstOrDefault(); //segments1.startTime > DateTime.UtcNow + for (int i = 0; i < segments1.Count; i++) { - imminentConflict.AddOrUpdate(fdr.Callsign, true, (k, v) => true); - imminentConflict.AddOrUpdate(fdr2.Callsign, true, (k, v) => true); + var activeExitBuffer = firstConflictTime.endTime.Subtract(new TimeSpan(0, 0, 15, 0)); + var isWithinTime = firstConflictTime.endTime > DateTime.UtcNow && activeExitBuffer > DateTime.UtcNow //check if conflict times are relevant + && segments1[i].startTime < activeExitBuffer && segments1[i].startTime > firstConflictTime.startTime; + + var advisoryConflicts = isWithinTime && new TimeSpan(0, 2, 0, 0, 0).CompareTo(firstConflictTime.startTime.Subtract(DateTime.UtcNow)) > 0; //check if timediff < 2 hours + var imminentConflicts = isWithinTime && new TimeSpan(0, 0, 30, 0, 0).CompareTo(firstConflictTime.startTime.Subtract(DateTime.UtcNow)) > 0; //check if timediff < 30 mins + + + //TimeOfPassing top; + // + //try + //{ + // top = new TimeOfPassing(fdr, fdr2); + //} + // + //catch (Exception e) + //{ + // return; + //} + // + //var cs1 = top.FDR1.Callsign; + //var cs2 = top.FDR2.Callsign; + //Match pbn1 = Regex.Match(fdr.Remarks, @"PBN\/\w+\s"); + //Match pbn2 = Regex.Match(fdr2.Remarks, @"PBN\/\w+\s"); + //bool rnp10 = Regex.IsMatch(pbn1.Value, @"A1") && Regex.IsMatch(pbn2.Value, @"A1"); + //bool rnp4 = Regex.IsMatch(pbn1.Value, @"L1") && Regex.IsMatch(pbn2.Value, @"L1"); + //bool cpdlc = (Regex.IsMatch(fdr.AircraftEquip, @"J5") || Regex.IsMatch(fdr.AircraftEquip, @"J7")) + // && (Regex.IsMatch(fdr2.AircraftEquip, @"J5") || Regex.IsMatch(fdr2.AircraftEquip, @"J7")); + //bool adsc = Regex.IsMatch(fdr.AircraftSurvEquip, @"D1") && Regex.IsMatch(fdr2.AircraftSurvEquip, @"D1"); + //bool jet = fdr.PerformanceData?.IsJet ?? false; + //var d23 = top.Distance < 23; + //var d50 = top.Distance < 50; + //var d100 = top.Distance < 100; + //var advisoryTimeFrame = new TimeSpan(0, 2, 0, 0, 0).CompareTo(top.Time.Subtract(DateTime.UtcNow)) > 0; + //var imminentTimeFrame = new TimeSpan(0, 0, 30, 0, 0).CompareTo(top.Time.Subtract(DateTime.UtcNow)) > 0; + //bool imminentConflicts = delta < verticalSep && ((jet && rnp4 && cpdlc && adsc && d23 && imminentTimeFrame) || ((rnp4 || rnp10) && d50 && imminentTimeFrame) || (d100 && imminentTimeFrame)); + //bool advisoryConflicts = delta < verticalSep && ((jet && rnp4 && cpdlc && adsc && d23 && advisoryTimeFrame) || ((rnp4 || rnp10) && d50 && advisoryTimeFrame) || (d100 && advisoryTimeFrame)); + + + if (imminentConflicts) + { + //imminentConflict.AddOrUpdate(fdr.Callsign, new List(new string[] { fdr2.Callsign }), + // (k, v) => v.Append(fdr2.Callsign).ToList()); + //imminentConflict.AddOrUpdate(fdr2.Callsign, new List(new string[] { fdr.Callsign }), + // (k, v) => v.Append(fdr.Callsign).ToList()); - } - if (advisoryConflicts) - { - // auto acknowledge - advisoryConflict.AddOrUpdate(fdr.Callsign, true, (k, v) => true); - advisoryConflict.AddOrUpdate(fdr2.Callsign, true, (k, v) => true); - } - } - else - { - advisoryConflict.TryRemove(fdr.Callsign, out clean); - advisoryConflict.TryRemove(fdr2.Callsign, out clean); - imminentConflict.TryRemove(fdr.Callsign, out clean); - imminentConflict.TryRemove(fdr2.Callsign, out clean); - } - } - } - private static void AutoAssume(RDP.RadarTrack rt) - { - var fdr = rt.CoupledFDR; - if (fdr != null) - { - AutoAssume(fdr); - RDP.Couple(fdr, rt); - } - } + imminentConflict.AddOrUpdate(fdr.Callsign, imminentConflicts, (k, v) => imminentConflicts); + //imminentConflict.AddOrUpdate(cs1, imminentConflicts, (k, v) => imminentConflicts); + //imminentConflict.AddOrUpdate(cs2, imminentConflicts, (k, v) => imminentConflicts); - private static void AutoAssume(FDP2.FDR fdr) - { - if (fdr != null) - { - if (!fdr.ESTed && MMI.IsMySectorConcerned(fdr)) - { - MMI.EstFDR(fdr); - } + } + else + { + //imminentConflict.AddOrUpdate(fdr2.Callsign, new List(), + // (k, v) => v.Where(e => e != fdr.Callsign).ToList()); + //imminentConflict.AddOrUpdate(fdr.Callsign, new List(), + // (k, v) => v.Where(e => e != fdr2.Callsign).ToList()); - if (MMI.SectorsControlled.ToList() - .Exists(s => s.IsInSector(fdr.GetLocation(), fdr.PRL)) && !fdr.IsTrackedByMe && - MMI.SectorsControlled.Contains(fdr.ControllingSector) || fdr.ControllingSector == null) - { - MMI.AcceptJurisdiction(fdr); - } - } - } - private static void AutoDrop(RDP.RadarTrack rt) - { - var fdr = rt.CoupledFDR; - if (fdr != null && rt != null) - { - AutoDrop(fdr); - } - } + imminentConflict.TryRemove(fdr.Callsign, out _); + //imminentConflict.TryRemove(cs1, out _); + //imminentConflict.TryRemove(cs2, out _); + } + if (advisoryConflicts) + { + //advisoryConflict.AddOrUpdate(fdr2.Callsign, new List(new string[] { fdr.Callsign }), + // (k, v) => v.Append(fdr.Callsign).ToList()); + //advisoryConflict.AddOrUpdate(fdr.Callsign, new List(new string[] { fdr2.Callsign }), + // (k, v) => v.Append(fdr2.Callsign).ToList()); - private static void AutoDrop(FDP2.FDR fdr) - { - var rt = fdr.CoupledTrack; - if (fdr != null && rt != null) - { - if (fdr.IsTrackedByMe && MMI.GetSectorEntryTime(fdr) < DateTime.Now && MMI.SectorsControlled.ToList() - .TrueForAll(s => !s.IsInSector(fdr.GetLocation(), fdr.PRL))) //MMI.GetSectorEntryTime(fdr) == null - { - MMI.HandoffToNone(fdr); - //MMI.Inhibit(fdr); - Thread.Sleep(300000); - RDP.DeCouple(rt); + + advisoryConflict.AddOrUpdate(fdr.Callsign, advisoryConflicts, (k, v) => advisoryConflicts); + //advisoryConflict.AddOrUpdate(cs1, advisoryConflicts, (k, v) => advisoryConflicts); + //advisoryConflict.AddOrUpdate(cs2, advisoryConflicts, (k, v) => advisoryConflicts); + } + else + { + //advisoryConflict.AddOrUpdate(fdr.Callsign, new List(), + // (k, v) => v.Where(e => e != fdr2.Callsign).ToList()); + //advisoryConflict.AddOrUpdate(fdr2.Callsign, new List(), + // (k, v) => v.Where(e => e != fdr.Callsign).ToList()); + + + advisoryConflict.TryRemove(fdr.Callsign, out _); + //advisoryConflict.TryRemove(cs1, out _); + //advisoryConflict.TryRemove(cs2, out _); + } + } } } } + + //var emptyAdvisoryConflicts = advisoryConflict.Where(pair => pair.Value.Count == 0) + // .Select(pair => pair.Key) + // .ToList(); + //foreach (var callsign in emptyAdvisoryConflicts) + //{ + // advisoryConflict.TryRemove(callsign, out _); + //} + //var emptyImminentConflicts = imminentConflict.Where(pair => pair.Value.Count == 0) + // .Select(pair => pair.Key) + // .ToList(); + //foreach (var callsign in emptyImminentConflicts) + //{ + // imminentConflict.TryRemove(callsign, out _); + //} + /// Could use the new position of the radar track or its change in state (cancelled, etc.) to do some processing. @@ -476,8 +432,7 @@ private void HandleRadarFlagClick(CustomLabelItemMouseClickEventArgs e) /// itemType is the value of the Type attribute in Labels.xml /// If it's not our item being called (another plugins, for example), return null. /// As a general rule, don't do processing in here as you'll slow down the ASD refresh. In the case of parsing a level to a string though, that's fine. - public CustomLabelItem GetCustomLabelItem(string itemType, Track track, FDP2.FDR flightDataRecord, - RDP.RadarTrack radarTrack) + public CustomLabelItem GetCustomLabelItem(string itemType, Track track, FDP2.FDR flightDataRecord, RDP.RadarTrack radarTrack) { if (flightDataRecord == null && track == null) return null; @@ -586,13 +541,11 @@ public CustomLabelItem GetCustomLabelItem(string itemType, Track track, FDP2.FDR } case LABEL_ITEM_ADS_FLAGS: - - return new CustomLabelItem() - { - Text = c2.ToString(), - - }; + return new CustomLabelItem() + { + Text = c2.ToString() + }; case LABEL_ITEM_MNT_FLAGS: @@ -651,16 +604,33 @@ public CustomLabelItem GetCustomLabelItem(string itemType, Track track, FDP2.FDR return null; - case LABEL_ITEM_VMI: - + case LABEL_ITEM_LEVEL: + int level = radarTrack == null ? flightDataRecord.PRL / 100 : radarTrack.CorrectedAltitude / 100; + return new CustomLabelItem() { - Text = h1.ToString(), - ForeColourIdentity = isNonRVSM + Text = level.ToString(), + ForeColourIdentity = isNonRVSM ? Colours.Identities.Custom : default, - CustomForeColour = NonRVSM - }; + CustomForeColour = NonRVSM, + Border = flightDataRecord.State == (FDR.FDRStates.STATE_PREACTIVE | FDR.FDRStates.STATE_COORDINATED) + ? BorderFlags.All + : BorderFlags.None, + BorderColourIdentity = Colours.Identities.Custom, + CustomBorderColour = NotCDA + }; + + case LABEL_ITEM_VMI: + + return new CustomLabelItem() + { + Text = h1.ToString(), + ForeColourIdentity = isNonRVSM + ? Colours.Identities.Custom + : default, + CustomForeColour = NonRVSM + }; @@ -669,7 +639,7 @@ public CustomLabelItem GetCustomLabelItem(string itemType, Track track, FDP2.FDR if (radarTrack != null && radarTrack.ReachedCFL || prl == alt) //track.NewCFL return new CustomLabelItem() { - Text = "" + Text = "" }; else @@ -678,18 +648,43 @@ public CustomLabelItem GetCustomLabelItem(string itemType, Track track, FDP2.FDR { Text = alt.ToString(), ForeColourIdentity = isNonRVSM - ? Colours.Identities.Custom + ? Colours.Identities.Custom : default, CustomForeColour = NonRVSM, - Border = flightDataRecord.State == (FDR.FDRStates.STATE_PREACTIVE | FDR.FDRStates.STATE_COORDINATED) - ? BorderFlags.All + Border = flightDataRecord.State == (FDR.FDRStates.STATE_PREACTIVE | FDR.FDRStates.STATE_COORDINATED) + ? BorderFlags.All : BorderFlags.None, BorderColourIdentity = Colours.Identities.Custom, CustomBorderColour = NotCDA }; } - + //case LABEL_ITEM_HANDOFF_IND: + // + // + // if (flightDataRecord.IsHandoff) + // { + // return new CustomLabelItem() + // { + // Text = "H" + flightDataRecord.HandoffController.ToString(), + // }; + // } + // + // else if (flightDataRecord.State == FDR.FDRStates.STATE_HANDOVER_FIRST) + // { + // return new CustomLabelItem() + // { + // Text = "O" + flightDataRecord.HandoffController.ToString(), + // }; + // } + // + // else + // { + // return new CustomLabelItem() + // { + // Text = "" + // }; + // } case LABEL_ITEM_RADAR_IND: @@ -712,8 +707,28 @@ public CustomLabelItem GetCustomLabelItem(string itemType, Track track, FDP2.FDR }; } + case LABEL_ITEM_INHIBIT_IND: + + + if (flightDataRecord.State == FDR.FDRStates.STATE_INHIBITED) + { + return new CustomLabelItem() + { + Text = "^" + }; + } + + else + { + return new CustomLabelItem() + { + Text = "" + }; + } + + case LABEL_ITEM_FILED_SPEED: - var mach = Conversions.CalculateMach(flightDataRecord.TAS, GRIB.FindTemperature(flightDataRecord.PRL, track.GetLocation(), true)); + var mach = Conversions.CalculateMach(flightDataRecord.TAS, GRIB.FindTemperature(flightDataRecord.PRL, track.GetLocation(), true)); return new CustomLabelItem() { Text = "M" + Convert.ToDecimal(mach).ToString("F2").Replace(".", "") @@ -738,26 +753,27 @@ public CustomLabelItem GetCustomLabelItem(string itemType, Track track, FDP2.FDR public CustomColour SelectASDTrackColour(Track track) { var fdr = track.GetFDR(); + var fdr2 = track.GetFDR(); //if track doesn't have an FDR coupled do nothing if (fdr == null) return null; - + //only apply East/West colour to jurisdiction state if (track.State == MMI.HMIStates.Jurisdiction) //read our dictionary of stored bools (true means is easterly) and return the correct colour { - - return GetDirectionColour(fdr.Callsign); + + return GetConflictColour(fdr.Callsign) ?? GetDirectionColour(fdr.Callsign); } - if (MMI.IsMySectorConcerned(fdr) && fdr.State != (FDR.FDRStates.STATE_PREACTIVE | FDR.FDRStates.STATE_COORDINATED)) //only apply conflict colours if planes are of concern + if (fdr.State != (FDR.FDRStates.STATE_PREACTIVE | FDR.FDRStates.STATE_COORDINATED)) //only apply conflict colours if planes are of concern { - return GetConflictColour(fdr.Callsign); + return GetConflictColour(fdr.Callsign) ?? default; } else - return default; + return default; } @@ -781,17 +797,16 @@ private CustomColour GetDirectionColour(string callsign) private CustomColour GetConflictColour(string callsign) { - if (advisoryConflict.TryGetValue(callsign, out _)) - { - return Advisory; - } - if (imminentConflict.TryGetValue(callsign, out _)) { return Imminent; } - return null; + if (advisoryConflict.TryGetValue(callsign, out _)) + { + return Advisory; + } + return null; } } } \ No newline at end of file From 05a00378afb06e7d20658450a69ca93eaf41cd3d Mon Sep 17 00:00:00 2001 From: Dominic Nguyen Date: Wed, 6 Sep 2023 22:13:09 -0700 Subject: [PATCH 27/76] CPAR --- CPAR.cs | 164 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 164 insertions(+) create mode 100644 CPAR.cs diff --git a/CPAR.cs b/CPAR.cs new file mode 100644 index 0000000..e0839a5 --- /dev/null +++ b/CPAR.cs @@ -0,0 +1,164 @@ +// Decompiled with JetBrains decompiler +// Type: vatsys.LATC +// Assembly: vatSys, Version=0.4.8114.34539, Culture=neutral, PublicKeyToken=null +// MVID: E82FB2F8-DAB0-42FD-91AA-1C44F8E62564 +// Assembly location: E:\vatsys\bin\vatSys.exe +// XML documentation location: E:\vatsys\bin\vatSys.xml + +using System; +using System.Collections.Generic; +using System.Linq; + +namespace vatsys +{ + public class CPAR + { + public List Segments = new List(); + public DateTime Timeout = DateTime.MaxValue; + + public CPAR(Track track1, Track track2, int value) => this.CalculateLATC(track1, track2, value); + + public CPAR() + { + } + + private void CalculateLATC(Track track1, Track track2, int value) + { + FDP2.FDR fdr1 = track1.GetFDR(); + FDP2.FDR fdr2 = track2.GetFDR(); + if (fdr1 == null || fdr2 == null) + return; + this.Segments.AddRange((IEnumerable)this.CalculateAreaOfConflict(fdr1, fdr2, value)); + this.Segments.AddRange((IEnumerable)this.CalculateAreaOfConflict(fdr2, fdr1, value)); + } + + public List CalculateAreaOfConflict(FDP2.FDR fdr1, FDP2.FDR fdr2, int value) + { + List segs = new List(); + List route1waypoints = fdr1.ParsedRoute.ToList().Where(s => s.Type == FDP2.FDR.ExtractedRoute.Segment.SegmentTypes.WAYPOINT).ToList(); + List route2waypoints = fdr2.ParsedRoute.ToList().Where(s => s.Type == FDP2.FDR.ExtractedRoute.Segment.SegmentTypes.WAYPOINT).ToList(); + for (int wp1index = 1; wp1index < route1waypoints.Count; ++wp1index) + { + List route1Segment = CreatePolygon(route1waypoints[wp1index - 1].Intersection.LatLong, route1waypoints[wp1index].Intersection.LatLong, value); + for (int wp2index = 1; wp2index < route2waypoints.Count; wp2index++) + { + List source = new List(); + List intersectionPoints = new List(); + source.AddRange((IEnumerable)CalculatePolygonIntersections(route1Segment, route2waypoints[wp2index - 1].Intersection.LatLong, route2waypoints[wp2index].Intersection.LatLong)); + int num1 = 0; + int num2 = 0; + foreach (Coordinate coordinate in source.ToList()) + { + if (Conversions.IsLatLonOnGC(route2waypoints[wp2index - 1].Intersection.LatLong, route2waypoints[wp2index].Intersection.LatLong, coordinate)) + { + intersectionPoints.Add(coordinate); + } + else + { + double track = Conversions.CalculateTrack(route2waypoints[wp2index - 1].Intersection.LatLong, route2waypoints[wp2index].Intersection.LatLong); + if (Math.Abs(track - Conversions.CalculateTrack(route2waypoints[wp2index - 1].Intersection.LatLong, coordinate)) > 90.0) + ++num1; + if (Math.Abs(track - Conversions.CalculateTrack(coordinate, route2waypoints[wp2index].Intersection.LatLong)) > 90.0) + ++num2; + } + } + if (num1 % 2 != 0 && num2 % 2 != 0) + { + intersectionPoints.Clear(); + intersectionPoints.Add(route2waypoints[wp2index - 1].Intersection.LatLong); + intersectionPoints.Add(route2waypoints[wp2index].Intersection.LatLong); + } + else if (num2 % 2 != 0) + intersectionPoints.Add(route2waypoints[wp2index].Intersection.LatLong); + else if (num1 % 2 != 0) + intersectionPoints.Add(route2waypoints[wp2index - 1].Intersection.LatLong); + intersectionPoints.Sort((x, y) => Conversions.CalculateDistance(route2waypoints[wp2index - 1].Intersection.LatLong, x).CompareTo(Conversions.CalculateDistance(route2waypoints[wp2index - 1].Intersection.LatLong, y))); + for (int ipIndex = 1; ipIndex < intersectionPoints.Count; ipIndex += 2) + { + Segment seg = new Segment(); + seg.startLatlong = intersectionPoints[ipIndex - 1]; + seg.endLatlong = intersectionPoints[ipIndex]; + List conflictSegments = segs.Where((Func)(s => s.routeSegment == route2waypoints[wp2index])).Where((Func)(s => Conversions.CalculateDistance(s.startLatlong, route2waypoints[wp2index - 1].Intersection.LatLong) < Conversions.CalculateDistance(seg.startLatlong, route2waypoints[wp2index - 1].Intersection.LatLong) && Conversions.CalculateDistance(s.endLatlong, route2waypoints[wp2index - 1].Intersection.LatLong) > Conversions.CalculateDistance(seg.startLatlong, route2waypoints[wp2index - 1].Intersection.LatLong) || Conversions.CalculateDistance(s.endLatlong, route2waypoints[wp2index - 1].Intersection.LatLong) > Conversions.CalculateDistance(seg.endLatlong, route2waypoints[wp2index - 1].Intersection.LatLong) && Conversions.CalculateDistance(s.startLatlong, route2waypoints[wp2index - 1].Intersection.LatLong) < Conversions.CalculateDistance(seg.endLatlong, route2waypoints[wp2index - 1].Intersection.LatLong) || Conversions.CalculateDistance(s.startLatlong, route2waypoints[wp2index - 1].Intersection.LatLong) > Conversions.CalculateDistance(seg.startLatlong, route2waypoints[wp2index - 1].Intersection.LatLong) && Conversions.CalculateDistance(s.endLatlong, route2waypoints[wp2index - 1].Intersection.LatLong) < Conversions.CalculateDistance(seg.endLatlong, route2waypoints[wp2index - 1].Intersection.LatLong) || Conversions.CalculateDistance(s.startLatlong, seg.startLatlong) < 0.01 || Conversions.CalculateDistance(s.endLatlong, seg.endLatlong) < 0.01)).ToList(); + if (conflictSegments.Count > 0) + { + foreach (Segment segment in conflictSegments) + { + if (Conversions.CalculateDistance(segment.endLatlong, route2waypoints[wp2index - 1].Intersection.LatLong) < Conversions.CalculateDistance(seg.endLatlong, route2waypoints[wp2index - 1].Intersection.LatLong)) + segment.endLatlong = seg.endLatlong; + if (Conversions.CalculateDistance(seg.startLatlong, route2waypoints[wp2index - 1].Intersection.LatLong) < Conversions.CalculateDistance(segment.startLatlong, route2waypoints[wp2index - 1].Intersection.LatLong)) + segment.startLatlong = seg.startLatlong; + } + } + else + { + seg.callsign = fdr2.Callsign; + seg.routeSegment = route2waypoints[wp2index]; + segs.Add(seg); + } + } + } + } + for (int i = 0; i < segs.Count; i++) + { + if (!segs.Exists((Predicate)(s => Conversions.CalculateDistance(segs[i].startLatlong, s.endLatlong) < 0.01))) + segs[i].startTime = FDP2.GetSystemEstimateAtPosition(fdr2, segs[i].startLatlong, segs[i].routeSegment); + if (!segs.Exists((Predicate)(s => Conversions.CalculateDistance(segs[i].endLatlong, s.startLatlong) < 0.01))) + segs[i].endTime = FDP2.GetSystemEstimateAtPosition(fdr2, segs[i].endLatlong, segs[i].routeSegment); + } + return segs; + } + + public static List CreatePolygon(Coordinate point1, Coordinate point2, int value) + { + List polygon = new List(); + double track = Conversions.CalculateTrack(point1, point2); + double num1 = track - 90.0; + for (int index = 0; index <= 180; index += 10) + { + double heading = num1 - (double)index; + Coordinate fromBearingRange = Conversions.CalculateLLFromBearingRange(point1, (double)value, heading); + polygon.Add(fromBearingRange); + } + double num2 = track + 90.0; + for (int index = 0; index <= 180; index += 10) + { + double heading = num2 - (double)index; + Coordinate fromBearingRange = Conversions.CalculateLLFromBearingRange(point2, (double)value, heading); + polygon.Add(fromBearingRange); + } + polygon.Add(polygon[0]); + return polygon; + } + + public static List CalculatePolygonIntersections( + List polygon, + Coordinate point1, + Coordinate point2) + { + List polygonIntersections = new List(); + for (int index = 1; index < polygon.Count; ++index) + { + List gcIntersectionLl = Conversions.CalculateAllGCIntersectionLL(polygon[index - 1], polygon[index], point1, point2); + if (gcIntersectionLl != null) + polygonIntersections.AddRange(gcIntersectionLl); + } + for (int index = 0; index < polygonIntersections.Count; ++index) + { + Coordinate intsect = polygonIntersections[index]; + polygonIntersections.RemoveAll(c => c != intsect && Conversions.CalculateDistance(intsect, c) < 0.01); + } + return polygonIntersections; + } + + + public class Segment + { + public string callsign; + public Coordinate startLatlong; + public Coordinate endLatlong; + public DateTime startTime = DateTime.MaxValue; + public DateTime endTime = DateTime.MaxValue; + public FDP2.FDR.ExtractedRoute.Segment routeSegment; + } + } +} From 022abae62ef281436635af069f9472e5ae9dd63d Mon Sep 17 00:00:00 2001 From: Dominic Nguyen Date: Tue, 12 Sep 2023 21:19:40 -0700 Subject: [PATCH 28/76] LongitudinalLogicSloth Now renders slow as fuck --- AuroraLabelItemsPlugin.cs | 90 +++++++++++++++++++++++---------------- 1 file changed, 54 insertions(+), 36 deletions(-) diff --git a/AuroraLabelItemsPlugin.cs b/AuroraLabelItemsPlugin.cs index cce010e..18f19b3 100644 --- a/AuroraLabelItemsPlugin.cs +++ b/AuroraLabelItemsPlugin.cs @@ -267,12 +267,21 @@ public void ConflictProbe(FDP2.FDR fdr, int value) int cfl = fdr.CFLUpper; int rfl = fdr.RFL; int alt = cfl == -1 ? rfl : cfl; - var isRvsm = fdr.RVSM; + foreach (var fdr2 in FDP2.GetFDRs) { if (fdr2 == null || fdr.Callsign == fdr2.Callsign || !MMI.IsMySectorConcerned(fdr2)) continue; + var rte = fdr.ParsedRoute; + var rte2 = fdr2.ParsedRoute; + double trk = Conversions.CalculateTrack(rte.First().Intersection.LatLong, + rte.Last().Intersection.LatLong); + double trk2 = Conversions.CalculateTrack(rte2.First().Intersection.LatLong, + rte2.Last().Intersection.LatLong); + var sameDir = Math.Abs(trk2 - trk) < 45; + var crossing = Math.Abs(trk2 - trk) >= 45 && Math.Abs(trk2 - trk) <= 135; + var oppoDir = Math.Abs(trk2 - trk) >= 136 && Math.Abs(trk2 - trk) <= 180; int cfl2 = fdr2.CFLUpper; int rfl2 = fdr2.RFL; int alt2 = cfl2 == -1 ? rfl2 : cfl2; @@ -289,47 +298,56 @@ public void ConflictProbe(FDP2.FDR fdr, int value) var anInstanceofCPAR = new CPAR(); var segments1 = anInstanceofCPAR.CalculateAreaOfConflict(fdr, fdr2, value); segments1.Sort((Comparison)((s, t) => s.startTime.CompareTo(t.startTime))); //sort by first conflict time - var firstConflictTime = segments1.FirstOrDefault(); //segments1.startTime > DateTime.UtcNow + var firstConflictTime = segments1.FirstOrDefault(); for (int i = 0; i < segments1.Count; i++) { - var activeExitBuffer = firstConflictTime.endTime.Subtract(new TimeSpan(0, 0, 15, 0)); - var isWithinTime = firstConflictTime.endTime > DateTime.UtcNow && activeExitBuffer > DateTime.UtcNow //check if conflict times are relevant - && segments1[i].startTime < activeExitBuffer && segments1[i].startTime > firstConflictTime.startTime; - - var advisoryConflicts = isWithinTime && new TimeSpan(0, 2, 0, 0, 0).CompareTo(firstConflictTime.startTime.Subtract(DateTime.UtcNow)) > 0; //check if timediff < 2 hours - var imminentConflicts = isWithinTime && new TimeSpan(0, 0, 30, 0, 0).CompareTo(firstConflictTime.startTime.Subtract(DateTime.UtcNow)) > 0; //check if timediff < 30 mins - - - //TimeOfPassing top; - // - //try - //{ - // top = new TimeOfPassing(fdr, fdr2); - //} - // - //catch (Exception e) - //{ - // return; - //} - // - //var cs1 = top.FDR1.Callsign; - //var cs2 = top.FDR2.Callsign; - //Match pbn1 = Regex.Match(fdr.Remarks, @"PBN\/\w+\s"); - //Match pbn2 = Regex.Match(fdr2.Remarks, @"PBN\/\w+\s"); - //bool rnp10 = Regex.IsMatch(pbn1.Value, @"A1") && Regex.IsMatch(pbn2.Value, @"A1"); - //bool rnp4 = Regex.IsMatch(pbn1.Value, @"L1") && Regex.IsMatch(pbn2.Value, @"L1"); - //bool cpdlc = (Regex.IsMatch(fdr.AircraftEquip, @"J5") || Regex.IsMatch(fdr.AircraftEquip, @"J7")) - // && (Regex.IsMatch(fdr2.AircraftEquip, @"J5") || Regex.IsMatch(fdr2.AircraftEquip, @"J7")); - //bool adsc = Regex.IsMatch(fdr.AircraftSurvEquip, @"D1") && Regex.IsMatch(fdr2.AircraftSurvEquip, @"D1"); - //bool jet = fdr.PerformanceData?.IsJet ?? false; - //var d23 = top.Distance < 23; - //var d50 = top.Distance < 50; - //var d100 = top.Distance < 100; + + TimeOfPassing top; + + try + { + top = new TimeOfPassing(fdr, fdr2); + } + + catch (Exception e) + { + return; + } + + var cs1 = top.FDR1.Callsign; + var cs2 = top.FDR2.Callsign; + Match pbn1 = Regex.Match(fdr.Remarks, @"PBN\/\w+\s"); + Match pbn2 = Regex.Match(fdr2.Remarks, @"PBN\/\w+\s"); + bool rnp10 = Regex.IsMatch(pbn1.Value, @"A1") && Regex.IsMatch(pbn2.Value, @"A1"); + bool rnp4 = Regex.IsMatch(pbn1.Value, @"L1") && Regex.IsMatch(pbn2.Value, @"L1"); + bool cpdlc = (Regex.IsMatch(fdr.AircraftEquip, @"J5") || Regex.IsMatch(fdr.AircraftEquip, @"J7")) + && (Regex.IsMatch(fdr2.AircraftEquip, @"J5") || Regex.IsMatch(fdr2.AircraftEquip, @"J7")); + bool adsc = Regex.IsMatch(fdr.AircraftSurvEquip, @"D1") && Regex.IsMatch(fdr2.AircraftSurvEquip, @"D1"); + bool jet = fdr.PerformanceData?.IsJet ?? false; + var d23 = top.Distance < 23; + var d50 = top.Distance < 50; + var d100 = top.Distance < 100; //var advisoryTimeFrame = new TimeSpan(0, 2, 0, 0, 0).CompareTo(top.Time.Subtract(DateTime.UtcNow)) > 0; //var imminentTimeFrame = new TimeSpan(0, 0, 30, 0, 0).CompareTo(top.Time.Subtract(DateTime.UtcNow)) > 0; //bool imminentConflicts = delta < verticalSep && ((jet && rnp4 && cpdlc && adsc && d23 && imminentTimeFrame) || ((rnp4 || rnp10) && d50 && imminentTimeFrame) || (d100 && imminentTimeFrame)); //bool advisoryConflicts = delta < verticalSep && ((jet && rnp4 && cpdlc && adsc && d23 && advisoryTimeFrame) || ((rnp4 || rnp10) && d50 && advisoryTimeFrame) || (d100 && advisoryTimeFrame)); - + //var activeExitBuffer = firstConflictTime.endTime.Subtract(new TimeSpan(0, 0, 15, 0)); + //var lossOfSep = firstConflictTime.endTime > DateTime.UtcNow && activeExitBuffer > DateTime.UtcNow //check if conflict times are relevant + //&& segments1[i].startTime < activeExitBuffer && segments1[i].startTime > firstConflictTime.startTime; + var timeLongSame = sameDir && firstConflictTime.endTime > DateTime.UtcNow && segments1[1].startTime - segments1[2].startTime < (jet ? (new TimeSpan(0, 0, 10, 0)) : (new TimeSpan(0, 0, 15, 0)));//check time based longitudinal for same direction + var timeLongOpposite = oppoDir && top.Time > DateTime.UtcNow + && (top.Time.Add(new TimeSpan(0, 0, 10, 0)) > DateTime.UtcNow) && (top.Time.Subtract(new TimeSpan(0, 0, 10, 0)) > DateTime.UtcNow); + var timeLongCross = crossing && firstConflictTime.endTime > DateTime.UtcNow && segments1[1].startTime - segments1[2].startTime < (new TimeSpan(0, 0, 15, 0)); + var distLongSame = sameDir && firstConflictTime.endTime > DateTime.UtcNow + && Conversions.CalculateDistance(segments1[1].startLatlong, segments1[2].startLatlong) + < (jet && rnp4 && cpdlc && adsc ? 30 : (rnp4 || rnp10) ? 50 : 50); + var distLongOpposite = oppoDir && firstConflictTime.endTime > DateTime.UtcNow + && Conversions.CalculateDistance(segments1[1].endLatlong, segments1[2].endLatlong) + < (jet && rnp4 && cpdlc && adsc ? 30 : (rnp4 || rnp10) ? 50 : 50); + + var lossOfSep = timeLongSame || timeLongOpposite || timeLongCross || distLongSame || distLongOpposite; + var advisoryConflicts = lossOfSep && new TimeSpan(0, 2, 0, 0, 0).CompareTo(firstConflictTime.startTime.Subtract(DateTime.UtcNow)) > 0; //check if timediff < 2 hours + var imminentConflicts = lossOfSep && new TimeSpan(0, 0, 30, 0, 0).CompareTo(firstConflictTime.startTime.Subtract(DateTime.UtcNow)) > 0; //check if timediff < 30 mins if (imminentConflicts) { From 595cc640470cc83731285ea049d480be6e98f4d3 Mon Sep 17 00:00:00 2001 From: Dominic Nguyen Date: Thu, 14 Sep 2023 08:35:06 -0700 Subject: [PATCH 29/76] More EastBound logic --- AuroraStripItemPlugin.cs | 46 +++++++++++++++++++++++----------------- 1 file changed, 27 insertions(+), 19 deletions(-) diff --git a/AuroraStripItemPlugin.cs b/AuroraStripItemPlugin.cs index 830eaf7..f83539e 100644 --- a/AuroraStripItemPlugin.cs +++ b/AuroraStripItemPlugin.cs @@ -5,11 +5,8 @@ using vatsys.Plugin; using System.Collections.Concurrent; using System.ComponentModel.Composition; //<--Need to add a reference to System.ComponentModel.Composition -using static vatsys.Performance; -using static vatsys.Network; using static vatsys.FDP2; -using System.Linq; -using static vatsys.SectorsVolumes; + namespace AuroraStripItemsPlugin { @@ -135,26 +132,20 @@ public CustomStripItem GetCustomStripItem(string itemType, Track track, FDP2.FDR case STRIP_ITEM_CTLSECTOR: - bool pendingCoordination = flightDataRecord.State == (FDR.FDRStates.STATE_PREACTIVE | FDR.FDRStates.STATE_COORDINATED); + bool pendingCoordination = flightDataRecord.State == (FDR.FDRStates.STATE_PREACTIVE | FDR.FDRStates.STATE_COORDINATED); + string sectorName = flightDataRecord.ControllingSector == null ? "" : flightDataRecord.ControllingSector.Name; - if (pendingCoordination) { return new CustomStripItem() { - ForeColourIdentity = Colours.Identities.Custom, + ForeColourIdentity = pendingCoordination ? Colours.Identities.Custom : default, CustomForeColour = Pending, - Text = flightDataRecord.ControllingSector.Name ?? null - }; - } - else - { - return new CustomStripItem() - { - Text = flightDataRecord.ControllingSector.Name ?? null + Text = sectorName }; } + //case STRIP_ITEM_NXTSECTOR: // @@ -180,7 +171,7 @@ public CustomStripItem GetCustomStripItem(string itemType, Track track, FDP2.FDR case LABEL_ITEM_ADSB_CPDLC: - if (isEastBound & !adsb & cpdlc) + if (isEastBound && !adsb && cpdlc) return new CustomStripItem() { @@ -189,22 +180,39 @@ public CustomStripItem GetCustomStripItem(string itemType, Track track, FDP2.FDR Text = "⧆" }; - else if (!adsb & cpdlc) + else if (!isEastBound && !adsb && cpdlc) return new CustomStripItem() { Text = "⧆" }; + else if (isEastBound && !adsb) - else if (!adsb) + return new CustomStripItem() + { + BackColourIdentity = Colours.Identities.StripText, + ForeColourIdentity = Colours.Identities.StripBackground, + Text = "⎕" + }; + + else if (!isEastBound && !adsb) return new CustomStripItem() { Text = "⎕" }; - else if (cpdlc) + else if (isEastBound && cpdlc) + + return new CustomStripItem() + { + BackColourIdentity = Colours.Identities.StripText, + ForeColourIdentity = Colours.Identities.StripBackground, + Text = "*" + }; + + else if (!isEastBound && cpdlc) return new CustomStripItem() { From 67606fbd313fc18255941199f4455883aff7f3af Mon Sep 17 00:00:00 2001 From: Dominic Nguyen Date: Thu, 7 Dec 2023 19:59:07 -0800 Subject: [PATCH 30/76] Conflictual --- AuroraLabelItemsPlugin.cs | 562 ++-- AuroraStripItemPlugin.cs | 172 +- ConflictSummaryWindw.Designer.cs | 267 ++ ConflictSummaryWindw.cs | 34 + ConflictSummaryWindw.resx | 4632 ++++++++++++++++++++++++++++++ 5 files changed, 5366 insertions(+), 301 deletions(-) create mode 100644 ConflictSummaryWindw.Designer.cs create mode 100644 ConflictSummaryWindw.cs create mode 100644 ConflictSummaryWindw.resx diff --git a/AuroraLabelItemsPlugin.cs b/AuroraLabelItemsPlugin.cs index 18f19b3..67c695d 100644 --- a/AuroraLabelItemsPlugin.cs +++ b/AuroraLabelItemsPlugin.cs @@ -7,7 +7,14 @@ using vatsys; using vatsys.Plugin; using static vatsys.FDP2; -using System.Linq.Expressions; +using static vatsys.SectorsVolumes; +using static vatsys.Network; +using System.Collections.Generic; +using System.Net; + + + + //Note the reference to vatsys (set Copy Local to false) -----> @@ -24,7 +31,7 @@ public class AuroraLabelItemsPlugin : ILabelPlugin const string LABEL_ITEM_ADSB_CPDLC = "AURORA_ADSB_CPDLC"; //field c(4) const string LABEL_ITEM_ADS_FLAGS = "AURORA_ADS_FLAGS"; //field c(4) const string LABEL_ITEM_MNT_FLAGS = "AURORA_MNT_FLAGS"; //field c(4) - const string LABEL_ITEM_SCC = "AURORA_SCC"; //field c(5) + const string LABEL_ITEM_SCC = "AURORA_SCC"; //field d(5) const string LABEL_ITEM_ANNOT_IND = "AURORA_ANNOT_IND"; //field e(1) const string LABEL_ITEM_RESTR = "AURORA_RESTR"; //field f(1) const string LABEL_ITEM_LEVEL = "AURORA_LEVEL"; //field g(3) @@ -42,19 +49,21 @@ public class AuroraLabelItemsPlugin : ILabelPlugin readonly static CustomColour NotCDA = new CustomColour(100, 0, 100); readonly static CustomColour Advisory = new CustomColour(255, 165, 0); readonly static CustomColour Imminent = new CustomColour(255, 0, 0); + readonly static CustomColour SpecialConditionCode = new CustomColour(255, 255, 0); readonly ConcurrentDictionary eastboundCallsigns = new ConcurrentDictionary(); readonly ConcurrentDictionary adsbcpdlcValues = new ConcurrentDictionary(); readonly ConcurrentDictionary adsflagValues = new ConcurrentDictionary(); readonly ConcurrentDictionary mntflagValues = new ConcurrentDictionary(); + readonly ConcurrentDictionary sccflagValues = new ConcurrentDictionary(); readonly ConcurrentDictionary altValues = new ConcurrentDictionary(); readonly ConcurrentDictionary radartoggle = new ConcurrentDictionary(); readonly ConcurrentDictionary mntflagtoggle = new ConcurrentDictionary(); readonly ConcurrentDictionary downlink = new ConcurrentDictionary(); // key: callsign, value: acknowledged status - //readonly ConcurrentDictionary> advisoryConflict = new ConcurrentDictionary>(); - //readonly ConcurrentDictionary> imminentConflict = new ConcurrentDictionary>(); - readonly ConcurrentDictionary advisoryConflict = new ConcurrentDictionary(); - readonly ConcurrentDictionary imminentConflict = new ConcurrentDictionary(); + readonly ConcurrentDictionary> advisoryConflict = new ConcurrentDictionary>(); + readonly ConcurrentDictionary> imminentConflict = new ConcurrentDictionary>(); + //readonly ConcurrentDictionary advisoryConflict = new ConcurrentDictionary(); + //readonly ConcurrentDictionary imminentConflict = new ConcurrentDictionary(); public AuroraLabelItemsPlugin() { @@ -95,11 +104,11 @@ public string Name /// the flight planned PBN category and store the character we want to display in the label in the dictionary. public void OnFDRUpdate(FDP2.FDR updated) { - Match pbn = Regex.Match(updated.Remarks, @"PBN\/\w+\s"); - bool rnp10 = Regex.IsMatch(pbn.Value, @"A1"); - bool rnp4 = Regex.IsMatch(pbn.Value, @"L1"); - bool cpdlc = Regex.IsMatch(updated.AircraftEquip, @"J5") || Regex.IsMatch(updated.AircraftEquip, @"J7"); - bool adsc = Regex.IsMatch(updated.AircraftSurvEquip, @"D1"); + var pbn = Regex.Match(updated.Remarks, @"PBN\/\w+\s"); + bool rnp10 = pbn.Value.Contains ("A1"); + bool rnp4 = pbn.Value.Contains("L1"); + bool cpdlc = updated.AircraftEquip.Contains("J5") || updated.AircraftEquip.Contains("J7"); + bool adsc = updated.AircraftSurvEquip.Contains("D1"); bool jet = updated.PerformanceData?.IsJet ?? false; var vs = updated.PredictedPosition.VerticalSpeed; int prl = updated.PRL / 100; @@ -107,9 +116,8 @@ public void OnFDRUpdate(FDP2.FDR updated) int rfl = updated.RFL; int alt = cfl == -1 ? rfl : cfl; - AutoAssume(updated); - AutoDrop(updated); - //ConflictProbe(updated); ///Using TimeOfPassing method + TransferOfControl(updated); + if (jet & rnp4 & cpdlc & adsc) ///Using CalculateAreaofConflict method { ConflictProbe(updated, 23); @@ -129,6 +137,7 @@ public void OnFDRUpdate(FDP2.FDR updated) adsbcpdlcValues.TryRemove(updated.Callsign, out _); adsflagValues.TryRemove(updated.Callsign, out _); mntflagValues.TryRemove(updated.Callsign, out _); + sccflagValues.TryRemove(updated.Callsign, out _); altValues.TryRemove(updated.Callsign, out _); radartoggle.TryRemove(updated.Callsign, out _); mntflagtoggle.TryRemove(updated.Callsign, out _); @@ -175,10 +184,31 @@ public void OnFDRUpdate(FDP2.FDR updated) mntflagValues.AddOrUpdate(updated.Callsign, c3, (k, v) => c3); + NetworkPilot code; + code = new NetworkPilot(); + + string d1 = string.Empty; + + if (!rnp10 || !rnp4) + d1 = "RNP"; + + else if (code.TransponderCode == 7700) + d1 = "EMG"; + + else if (code.TransponderCode == 7600) + d1 = "RCF"; + + else if (code.TransponderCode == 7777) + d1 = "MTI"; + + else if (code.TransponderCode == 7700) + d1 = "EMG"; + + sccflagValues.AddOrUpdate(updated.Callsign, d1, (k, v) => d1); char h1 = default; - if (prl == alt) //level flight + if (Math.Abs(updated.PRL - alt) <= 299) //level flight h1 = default; else if (alt / 100 > prl || vs > 300) //Issued or trending climb @@ -208,59 +238,75 @@ public void OnFDRUpdate(FDP2.FDR updated) } } - private static void AutoAssume(RDP.RadarTrack rt) + + private static void TOC(RDP.RadarTrack rt) { var fdr = rt.CoupledFDR; - if (fdr != null) + if (fdr != null && rt != null) { - AutoAssume(fdr); - RDP.Couple(fdr, rt); + TransferOfControl(fdr); } } - private static void AutoAssume(FDP2.FDR fdr) + + private static void TransferOfControl(FDP2.FDR fdr) { + TOC toc; + toc = new TOC(fdr); + + var rt = fdr.CoupledTrack; if (fdr != null) - { if (!fdr.ESTed && MMI.IsMySectorConcerned(fdr)) { MMI.EstFDR(fdr); } - if (MMI.SectorsControlled.ToList() - .Exists(s => s.IsInSector(fdr.GetLocation(), fdr.PRL)) && !fdr.IsTrackedByMe && - MMI.SectorsControlled.Contains(fdr.ControllingSector) || fdr.ControllingSector == null) - { - MMI.AcceptJurisdiction(fdr); - } - } - } - - private static void AutoDrop(RDP.RadarTrack rt) - { - var fdr = rt.CoupledFDR; - if (fdr != null && rt != null) + if (MMI.SectorsControlled.ToList() + .Exists(s => s.IsInSector(fdr.GetLocation(), fdr.PRL)) && !fdr.IsTrackedByMe && !fdr.IsTracked) //MMI.SectorsControlled.Contains(fdr.ControllingSector) || fdr.ControllingSector == null { - AutoDrop(fdr); + MMI.AcceptJurisdiction(fdr); } - } - private static void AutoDrop(FDP2.FDR fdr) - { - var rt = fdr.CoupledTrack; - if (fdr != null && rt != null) + + + foreach (Volume volume in Volumes) { - if (MMI.GetSectorEntryTime(fdr) == null && MMI.SectorsControlled.ToList() - .TrueForAll(s => !s.IsInSector(fdr.GetLocation(), fdr.PRL))) + if (rt != null && (fdr.PRL == -1 || (fdr.PRL <= volume.UpperLevel && fdr.PRL > volume.LowerLevel)) && Conversions.IsLatlonInPoly(fdr.GetLocation(), volume.Boundary)) { - MMI.HandoffToNone(fdr); - //MMI.Inhibit(fdr); - Thread.Sleep(300000); - RDP.DeCouple(rt); + + var whichVol = volume; + var whichFIR = SectorsVolumes.FindSector(whichVol); + if (MMI.GetSectorEntryTime(fdr) == DateTime.MaxValue && MMI.SectorsControlled.ToList().TrueForAll(s => !s.IsInSector(fdr.GetLocation(), fdr.PRL))) // && whichFIR != fdr.ControllingSector + + { + toc.HandoffNextSector(); + MMI.HandoffJurisdiction(fdr, whichFIR); + //FDP2.AcceptJurisdiction(fdr, whichFIR); + MMI.Inhibit(fdr); + Thread.Sleep(300000); + RDP.DeCouple(rt); + } } } + } + //void SendNextDataAuthority(Network network, NetworkPilot pilot, VSCSFrequency freq) + //{ + // + // if (network.ValidATC && network.HaveConnection && !((DateTime.UtcNow - pilot.LastContactMe).TotalMinutes < 1.0)) + // { + // string text = "NEXT DATA AUTHORITY KZAK"; + // if (freq.AliasFrequency != VSCSFrequency.None.Frequency) + // { + // text = text + " (" + Conversions.FrequencyToString(freq.AliasFrequency) + ")"; + // } + // + // network.SendTextMessage(pilot.Callsign, text); + // pilot.LastContactMe = DateTime.UtcNow; + // } + //} + public void ConflictProbe(FDP2.FDR fdr, int value) { if ((fdr == null) || !MMI.IsMySectorConcerned(fdr)) return; @@ -268,7 +314,6 @@ public void ConflictProbe(FDP2.FDR fdr, int value) int rfl = fdr.RFL; int alt = cfl == -1 ? rfl : cfl; var isRvsm = fdr.RVSM; - foreach (var fdr2 in FDP2.GetFDRs) { @@ -279,9 +324,10 @@ public void ConflictProbe(FDP2.FDR fdr, int value) rte.Last().Intersection.LatLong); double trk2 = Conversions.CalculateTrack(rte2.First().Intersection.LatLong, rte2.Last().Intersection.LatLong); - var sameDir = Math.Abs(trk2 - trk) < 45; - var crossing = Math.Abs(trk2 - trk) >= 45 && Math.Abs(trk2 - trk) <= 135; - var oppoDir = Math.Abs(trk2 - trk) >= 136 && Math.Abs(trk2 - trk) <= 180; + var trkdelta = Math.Abs(trk2 - trk); + bool sameDir = trkdelta < 45; + bool crossing = (trkdelta >= 45 && trkdelta <= 135) || (trkdelta >= 315 && trkdelta <= 225); + bool oppoDir = trkdelta > 135 && trkdelta < 225; int cfl2 = fdr2.CFLUpper; int rfl2 = fdr2.RFL; int alt2 = cfl2 == -1 ? rfl2 : cfl2; @@ -295,15 +341,56 @@ public void ConflictProbe(FDP2.FDR fdr, int value) if (delta < verticalSep) { - var anInstanceofCPAR = new CPAR(); - var segments1 = anInstanceofCPAR.CalculateAreaOfConflict(fdr, fdr2, value); + Match pbn2 = Regex.Match(fdr2.Remarks, @"PBN\/\w+\s"); + bool rnp10 = pbn2.Value.Contains("A1"); + bool rnp4 = pbn2.Value.Contains("L1"); + bool cpdlc = (Regex.IsMatch(fdr2.AircraftEquip, @"J5") || Regex.IsMatch(fdr2.AircraftEquip, @"J7")); + bool adsc = Regex.IsMatch(fdr2.AircraftSurvEquip, @"D1"); + bool jet = fdr2.PerformanceData?.IsJet ?? false; + + var newValue = value; + + if (rnp4 && adsc && cpdlc) + { + newValue = Math.Max(newValue, 23); + } + + + else if (rnp10 && adsc && cpdlc) + { + newValue = Math.Max(newValue, 50); + } + + else + { + newValue = Math.Max(newValue, 100); + } + var cpar = new CPAR(fdr2, fdr, newValue); + var segments1 = cpar.Segments1; + var segments2 = cpar.Segments2; + segments1.Sort((Comparison)((s, t) => s.startTime.CompareTo(t.startTime))); //sort by first conflict time + segments2.Sort((Comparison)((s, t) => s.startTime.CompareTo(t.startTime))); + var firstConflictTime = segments1.FirstOrDefault(); - for (int i = 0; i < segments1.Count; i++) + var firstConflictTime2 = segments2.FirstOrDefault(); + var isConflictPair = segments1.Count > 0; + if (firstConflictTime == null || firstConflictTime2 == null) continue; + + + var timeLongSame = sameDir && isConflictPair && firstConflictTime.endTime > DateTime.UtcNow + && (firstConflictTime2.startTime - firstConflictTime.startTime).Duration() < (jet ? (new TimeSpan(0, 0, 10, 0)) : (new TimeSpan(0, 0, 15, 0)));//check time based longitudinal for same direction + var timeLongCross = crossing && isConflictPair && firstConflictTime.endTime > DateTime.UtcNow + && (firstConflictTime2.startTime - firstConflictTime.startTime).Duration() < (new TimeSpan(0, 0, 15, 0)); + var distLongSame = sameDir && isConflictPair && firstConflictTime.endTime > DateTime.UtcNow + && Conversions.CalculateDistance(firstConflictTime.startLatlong, firstConflictTime2.startLatlong) + < (jet && rnp4 && cpdlc && adsc ? 30 : (rnp4 || rnp10) ? 50 : 50); + + var timeLongOpposite = false; + TimeOfPassing top = null; + + if (isConflictPair && oppoDir) { - - TimeOfPassing top; - try { top = new TimeOfPassing(fdr, fdr2); @@ -313,118 +400,103 @@ public void ConflictProbe(FDP2.FDR fdr, int value) { return; } + timeLongOpposite = top.Time > DateTime.UtcNow + && (top.Time.Add(new TimeSpan(0, 0, 10, 0)) > DateTime.UtcNow) && (top.Time.Subtract(new TimeSpan(0, 0, 10, 0)) < DateTime.UtcNow); + } + + + + + //var distLongOpposite = oppoDir && isConflictPair && firstConflictTime.endTime > DateTime.UtcNow + // && Conversions.CalculateDistance(firstConflictTime.endLatlong, firstConflictTime.endLatlong) + // < (jet && rnp4 && cpdlc && adsc ? 30 : (rnp4 || rnp10) ? 50 : 50); + + + var lossOfSep = (delta < verticalSep) && timeLongSame || timeLongCross || distLongSame || timeLongOpposite; // || distLongOpposite + var earliestLOS = (isConflictPair && oppoDir ? top.Time.Subtract(new TimeSpan(0, 0, 10, 0)) + : (DateTime.Compare(firstConflictTime.startTime, firstConflictTime2.startTime) < 0 ? firstConflictTime.startTime : firstConflictTime2.startTime)); + var imminentConflicts = (isConflictPair && oppoDir && (delta < verticalSep)) ? (new TimeSpan(0, 0, 30, 0, 0) >= earliestLOS.Subtract(DateTime.UtcNow).Duration()) + : (lossOfSep && new TimeSpan(0, 0, 30, 0, 0) >= earliestLOS.Subtract(DateTime.UtcNow).Duration()); //check if timediff < 30 mins + var advisoryConflicts = (isConflictPair && oppoDir && (delta < verticalSep)) ? (new TimeSpan(0, 2, 0, 0, 0) > earliestLOS.Subtract(DateTime.UtcNow).Duration()) + && (earliestLOS.Subtract(DateTime.UtcNow).Duration() >= new TimeSpan(0, 0, 30, 0, 0)) + : (lossOfSep && new TimeSpan(0, 2, 0, 0, 0) > earliestLOS.Subtract(DateTime.UtcNow).Duration()) + && (earliestLOS.Subtract(DateTime.UtcNow).Duration() >= new TimeSpan(0, 0, 30, 0, 0)); //check if timediff < 2 hours + + - var cs1 = top.FDR1.Callsign; - var cs2 = top.FDR2.Callsign; - Match pbn1 = Regex.Match(fdr.Remarks, @"PBN\/\w+\s"); - Match pbn2 = Regex.Match(fdr2.Remarks, @"PBN\/\w+\s"); - bool rnp10 = Regex.IsMatch(pbn1.Value, @"A1") && Regex.IsMatch(pbn2.Value, @"A1"); - bool rnp4 = Regex.IsMatch(pbn1.Value, @"L1") && Regex.IsMatch(pbn2.Value, @"L1"); - bool cpdlc = (Regex.IsMatch(fdr.AircraftEquip, @"J5") || Regex.IsMatch(fdr.AircraftEquip, @"J7")) - && (Regex.IsMatch(fdr2.AircraftEquip, @"J5") || Regex.IsMatch(fdr2.AircraftEquip, @"J7")); - bool adsc = Regex.IsMatch(fdr.AircraftSurvEquip, @"D1") && Regex.IsMatch(fdr2.AircraftSurvEquip, @"D1"); - bool jet = fdr.PerformanceData?.IsJet ?? false; - var d23 = top.Distance < 23; - var d50 = top.Distance < 50; - var d100 = top.Distance < 100; - //var advisoryTimeFrame = new TimeSpan(0, 2, 0, 0, 0).CompareTo(top.Time.Subtract(DateTime.UtcNow)) > 0; - //var imminentTimeFrame = new TimeSpan(0, 0, 30, 0, 0).CompareTo(top.Time.Subtract(DateTime.UtcNow)) > 0; - //bool imminentConflicts = delta < verticalSep && ((jet && rnp4 && cpdlc && adsc && d23 && imminentTimeFrame) || ((rnp4 || rnp10) && d50 && imminentTimeFrame) || (d100 && imminentTimeFrame)); - //bool advisoryConflicts = delta < verticalSep && ((jet && rnp4 && cpdlc && adsc && d23 && advisoryTimeFrame) || ((rnp4 || rnp10) && d50 && advisoryTimeFrame) || (d100 && advisoryTimeFrame)); - //var activeExitBuffer = firstConflictTime.endTime.Subtract(new TimeSpan(0, 0, 15, 0)); - //var lossOfSep = firstConflictTime.endTime > DateTime.UtcNow && activeExitBuffer > DateTime.UtcNow //check if conflict times are relevant - //&& segments1[i].startTime < activeExitBuffer && segments1[i].startTime > firstConflictTime.startTime; - var timeLongSame = sameDir && firstConflictTime.endTime > DateTime.UtcNow && segments1[1].startTime - segments1[2].startTime < (jet ? (new TimeSpan(0, 0, 10, 0)) : (new TimeSpan(0, 0, 15, 0)));//check time based longitudinal for same direction - var timeLongOpposite = oppoDir && top.Time > DateTime.UtcNow - && (top.Time.Add(new TimeSpan(0, 0, 10, 0)) > DateTime.UtcNow) && (top.Time.Subtract(new TimeSpan(0, 0, 10, 0)) > DateTime.UtcNow); - var timeLongCross = crossing && firstConflictTime.endTime > DateTime.UtcNow && segments1[1].startTime - segments1[2].startTime < (new TimeSpan(0, 0, 15, 0)); - var distLongSame = sameDir && firstConflictTime.endTime > DateTime.UtcNow - && Conversions.CalculateDistance(segments1[1].startLatlong, segments1[2].startLatlong) - < (jet && rnp4 && cpdlc && adsc ? 30 : (rnp4 || rnp10) ? 50 : 50); - var distLongOpposite = oppoDir && firstConflictTime.endTime > DateTime.UtcNow - && Conversions.CalculateDistance(segments1[1].endLatlong, segments1[2].endLatlong) - < (jet && rnp4 && cpdlc && adsc ? 30 : (rnp4 || rnp10) ? 50 : 50); - - var lossOfSep = timeLongSame || timeLongOpposite || timeLongCross || distLongSame || distLongOpposite; - var advisoryConflicts = lossOfSep && new TimeSpan(0, 2, 0, 0, 0).CompareTo(firstConflictTime.startTime.Subtract(DateTime.UtcNow)) > 0; //check if timediff < 2 hours - var imminentConflicts = lossOfSep && new TimeSpan(0, 0, 30, 0, 0).CompareTo(firstConflictTime.startTime.Subtract(DateTime.UtcNow)) > 0; //check if timediff < 30 mins - - if (imminentConflicts) + if (imminentConflicts) { - //imminentConflict.AddOrUpdate(fdr.Callsign, new List(new string[] { fdr2.Callsign }), - // (k, v) => v.Append(fdr2.Callsign).ToList()); - //imminentConflict.AddOrUpdate(fdr2.Callsign, new List(new string[] { fdr.Callsign }), - // (k, v) => v.Append(fdr.Callsign).ToList()); + imminentConflict.AddOrUpdate(fdr.Callsign, new List(new string[] { fdr2.Callsign }), + (k, v) => v.Append(fdr2.Callsign).ToList()); + imminentConflict.AddOrUpdate(fdr2.Callsign, new List(new string[] { fdr.Callsign }), + (k, v) => v.Append(fdr.Callsign).ToList()); + + //imminentConflict.AddOrUpdate(fdr.Callsign, imminentConflicts, (k, v) => imminentConflicts); - imminentConflict.AddOrUpdate(fdr.Callsign, imminentConflicts, (k, v) => imminentConflicts); - //imminentConflict.AddOrUpdate(cs1, imminentConflicts, (k, v) => imminentConflicts); - //imminentConflict.AddOrUpdate(cs2, imminentConflicts, (k, v) => imminentConflicts); + //imminentConflict.AddOrUpdate(cs1, imminentConflicts, (k, v) => imminentConflict); + //imminentConflict.AddOrUpdate(cs2, imminentConflicts, (k, v) => imminentConflict); } - else - { - //imminentConflict.AddOrUpdate(fdr2.Callsign, new List(), - // (k, v) => v.Where(e => e != fdr.Callsign).ToList()); - //imminentConflict.AddOrUpdate(fdr.Callsign, new List(), - // (k, v) => v.Where(e => e != fdr2.Callsign).ToList()); + else + { + //imminentConflict.AddOrUpdate(fdr2.Callsign, new List(), + // (k, v) => v.Where(e => e != fdr.Callsign).ToList()); + //imminentConflict.AddOrUpdate(fdr.Callsign, new List(), + // (k, v) => v.Where(e => e != fdr2.Callsign).ToList()); - imminentConflict.TryRemove(fdr.Callsign, out _); - //imminentConflict.TryRemove(cs1, out _); - //imminentConflict.TryRemove(cs2, out _); - } - if (advisoryConflicts) + imminentConflict.TryRemove(fdr.Callsign, out _); + imminentConflict.TryRemove(fdr2.Callsign, out _); + + } + if (advisoryConflicts) { - //advisoryConflict.AddOrUpdate(fdr2.Callsign, new List(new string[] { fdr.Callsign }), - // (k, v) => v.Append(fdr.Callsign).ToList()); - //advisoryConflict.AddOrUpdate(fdr.Callsign, new List(new string[] { fdr2.Callsign }), - // (k, v) => v.Append(fdr2.Callsign).ToList()); + advisoryConflict.AddOrUpdate(fdr2.Callsign, new List(new string[] { fdr.Callsign }), + (k, v) => v.Append(fdr.Callsign).ToList()); + advisoryConflict.AddOrUpdate(fdr.Callsign, new List(new string[] { fdr2.Callsign }), + (k, v) => v.Append(fdr2.Callsign).ToList()); - advisoryConflict.AddOrUpdate(fdr.Callsign, advisoryConflicts, (k, v) => advisoryConflicts); - //advisoryConflict.AddOrUpdate(cs1, advisoryConflicts, (k, v) => advisoryConflicts); - //advisoryConflict.AddOrUpdate(cs2, advisoryConflicts, (k, v) => advisoryConflicts); } else - { - //advisoryConflict.AddOrUpdate(fdr.Callsign, new List(), - // (k, v) => v.Where(e => e != fdr2.Callsign).ToList()); - //advisoryConflict.AddOrUpdate(fdr2.Callsign, new List(), - // (k, v) => v.Where(e => e != fdr.Callsign).ToList()); + { + advisoryConflict.AddOrUpdate(fdr.Callsign, new List(), + (k, v) => v.Where(e => e != fdr2.Callsign).ToList()); + advisoryConflict.AddOrUpdate(fdr2.Callsign, new List(), + (k, v) => v.Where(e => e != fdr.Callsign).ToList()); advisoryConflict.TryRemove(fdr.Callsign, out _); - //advisoryConflict.TryRemove(cs1, out _); - //advisoryConflict.TryRemove(cs2, out _); - } + advisoryConflict.TryRemove(fdr2.Callsign, out _); + + } + var emptyAdvisoryConflicts = advisoryConflict.Where(pair => pair.Value.Count == 0) + .Select(pair => pair.Key) + .ToList(); + foreach (var callsign in emptyAdvisoryConflicts) + { + advisoryConflict.TryRemove(callsign, out _); + } + var emptyImminentConflicts = imminentConflict.Where(pair => pair.Value.Count == 0) + .Select(pair => pair.Key) + .ToList(); + foreach (var callsign in emptyImminentConflicts) + { + imminentConflict.TryRemove(callsign, out _); } } + } } - } - - //var emptyAdvisoryConflicts = advisoryConflict.Where(pair => pair.Value.Count == 0) - // .Select(pair => pair.Key) - // .ToList(); - //foreach (var callsign in emptyAdvisoryConflicts) - //{ - // advisoryConflict.TryRemove(callsign, out _); - //} - //var emptyImminentConflicts = imminentConflict.Where(pair => pair.Value.Count == 0) - // .Select(pair => pair.Key) - // .ToList(); - //foreach (var callsign in emptyImminentConflicts) - //{ - // imminentConflict.TryRemove(callsign, out _); - //} + + /// Could use the new position of the radar track or its change in state (cancelled, etc.) to do some processing. public void OnRadarTrackUpdate(RDP.RadarTrack updated) { - AutoAssume(updated); - AutoDrop(updated); + } @@ -452,7 +524,7 @@ private void HandleRadarFlagClick(CustomLabelItemMouseClickEventArgs e) /// As a general rule, don't do processing in here as you'll slow down the ASD refresh. In the case of parsing a level to a string though, that's fine. public CustomLabelItem GetCustomLabelItem(string itemType, Track track, FDP2.FDR flightDataRecord, RDP.RadarTrack radarTrack) { - if (flightDataRecord == null && track == null) + if (flightDataRecord == null || radarTrack == null) return null; char c1; @@ -461,63 +533,57 @@ public CustomLabelItem GetCustomLabelItem(string itemType, Track track, FDP2.FDR adsflagValues.TryGetValue(flightDataRecord.Callsign, out c2); char c3; mntflagValues.TryGetValue(flightDataRecord.Callsign, out c3); + string d1; + sccflagValues.TryGetValue(flightDataRecord.Callsign, out d1); char h1; altValues.TryGetValue(flightDataRecord.Callsign, out h1); bool radarToggled = radartoggle.TryGetValue(flightDataRecord.Callsign, out _); bool mntflagToggled = mntflagtoggle.TryGetValue(flightDataRecord.Callsign, out _); bool downLink = downlink.TryGetValue(flightDataRecord.Callsign, out _); - bool selectedCallsign = MMI.SelectedTrack?.GetFDR()?.Callsign == flightDataRecord.Callsign; + bool selectedCallsign = MMI.SelectedTrack?.GetFDR()?.Callsign == track.GetFDR().Callsign; bool isAdvisory = advisoryConflict.TryGetValue(flightDataRecord.Callsign, out _); bool isImminent = imminentConflict.TryGetValue(flightDataRecord.Callsign, out _); bool isNonRVSM = !flightDataRecord.RVSM; + var pbn = Regex.Match(flightDataRecord.Remarks, @"PBN\/\w+\s"); + bool rnp10 = pbn.Value.Contains("A1"); + bool rnp4 = pbn.Value.Contains("L1"); int prl = flightDataRecord.PRL / 100; int cfl = flightDataRecord.CFLUpper / 100; int rfl = flightDataRecord.RFL / 100; int alt = flightDataRecord.CFLUpper == -1 ? rfl : cfl; + var exConflict = (isAdvisory || isImminent && (track.State == MMI.HMIStates.Jurisdiction) ? GetDirectionColour(flightDataRecord.Callsign) : default); + var colour = (isNonRVSM ? NonRVSM : exConflict); + var notProbe = flightDataRecord.State == (FDR.FDRStates.STATE_PREACTIVE | FDR.FDRStates.STATE_COORDINATED) ? BorderFlags.All : BorderFlags.None; switch (itemType) { - case LABEL_ITEM_SELECT_HORI: - - if (selectedCallsign) - { - return new CustomLabelItem() - - { - Border = BorderFlags.Top, - }; - } - - else - { - return new CustomLabelItem() - - { - Border = BorderFlags.None, - - }; - } - - case LABEL_ITEM_SELECT_VERT: - - if (selectedCallsign) - { - return new CustomLabelItem() - { - Text = "", - Border = BorderFlags.Left, - }; - } - - else - { - return new CustomLabelItem() - { - Text = "", - Border = BorderFlags.None, - }; - } + //case LABEL_ITEM_SELECT_HORI: + // + // if (selectedCallsign) + // { + // return new CustomLabelItem() + // + // { + // Text = "", + // Border = BorderFlags.Top + // }; + // } + // + // return null; + // + //case LABEL_ITEM_SELECT_VERT: + // + // if (selectedCallsign) + // { + // return new CustomLabelItem() + // { + // Text = "", + // Border = BorderFlags.Left + // }; + // } + // + // return null; case LABEL_ITEM_COMM_ICON: @@ -525,15 +591,16 @@ public CustomLabelItem GetCustomLabelItem(string itemType, Track track, FDP2.FDR { return new CustomLabelItem() { - Text = "▼", - Border = BorderFlags.All + Text = "▽", //▼ + BackColourIdentity = Colours.Identities.Jurisdiction, + //Border = BorderFlags.All }; } else { return new CustomLabelItem() { - Text = "⬜" + Text = "⬜", }; } case LABEL_ITEM_ADSB_CPDLC: @@ -554,7 +621,7 @@ public CustomLabelItem GetCustomLabelItem(string itemType, Track track, FDP2.FDR { return new CustomLabelItem() { - Text = c1.ToString() + Text = c1.ToString(), }; } @@ -562,7 +629,7 @@ public CustomLabelItem GetCustomLabelItem(string itemType, Track track, FDP2.FDR return new CustomLabelItem() { - Text = c2.ToString() + Text = c2.ToString(), }; @@ -572,7 +639,7 @@ public CustomLabelItem GetCustomLabelItem(string itemType, Track track, FDP2.FDR { return new CustomLabelItem() { - Text = c3.ToString() + Text = c3.ToString(), }; } @@ -583,12 +650,16 @@ public CustomLabelItem GetCustomLabelItem(string itemType, Track track, FDP2.FDR }; - //case LABEL_ITEM_SCC: - // - // return new CustomLabelItem() - // { - // Text = pos | ca | la | ra | rcf | dup | spd - // }; + case LABEL_ITEM_SCC: + + { + return new CustomLabelItem() + { + Text = d1, + ForeColourIdentity = Colours.Identities.Custom, + CustomForeColour = SpecialConditionCode + }; + } case LABEL_ITEM_ANNOT_IND: @@ -598,7 +669,7 @@ public CustomLabelItem GetCustomLabelItem(string itemType, Track track, FDP2.FDR { return new CustomLabelItem() { - Text = "◦" + Text = "◦", }; } @@ -606,35 +677,31 @@ public CustomLabelItem GetCustomLabelItem(string itemType, Track track, FDP2.FDR { return new CustomLabelItem() { - Text = "&" + Text = "&", }; } case LABEL_ITEM_RESTR: - if (flightDataRecord.LabelOpData.Contains("AT") || flightDataRecord.LabelOpData.Contains("BY") || - flightDataRecord.LabelOpData.Contains("CLEARED TO")) + if (flightDataRecord.LabelOpData.Contains("AT ") || flightDataRecord.LabelOpData.Contains(" BY ") || + flightDataRecord.LabelOpData.Contains("CLEARED TO ")) return new CustomLabelItem() { - Text = "x" + Text = "x", }; return null; case LABEL_ITEM_LEVEL: - int level = radarTrack == null ? flightDataRecord.PRL / 100 : radarTrack.CorrectedAltitude / 100; - return new CustomLabelItem() + var level = prl == -1 ? null : (radarTrack.CorrectedAltitude / 100).ToString(); + + + return new CustomLabelItem() { Text = level.ToString(), - ForeColourIdentity = isNonRVSM - ? Colours.Identities.Custom - : default, - CustomForeColour = NonRVSM, - Border = flightDataRecord.State == (FDR.FDRStates.STATE_PREACTIVE | FDR.FDRStates.STATE_COORDINATED) - ? BorderFlags.All - : BorderFlags.None, + Border = notProbe, BorderColourIdentity = Colours.Identities.Custom, CustomBorderColour = NotCDA }; @@ -654,7 +721,8 @@ public CustomLabelItem GetCustomLabelItem(string itemType, Track track, FDP2.FDR case LABEL_ITEM_CLEARED_LEVEL: - if (radarTrack != null && radarTrack.ReachedCFL || prl == alt) //track.NewCFL + + if (radarTrack.ReachedCFL || prl == alt || Math.Abs(flightDataRecord.PRL - alt) <= 299) return new CustomLabelItem() { Text = "" @@ -665,44 +733,38 @@ public CustomLabelItem GetCustomLabelItem(string itemType, Track track, FDP2.FDR return new CustomLabelItem() { Text = alt.ToString(), - ForeColourIdentity = isNonRVSM - ? Colours.Identities.Custom - : default, - CustomForeColour = NonRVSM, - Border = flightDataRecord.State == (FDR.FDRStates.STATE_PREACTIVE | FDR.FDRStates.STATE_COORDINATED) - ? BorderFlags.All - : BorderFlags.None, + Border = notProbe, BorderColourIdentity = Colours.Identities.Custom, CustomBorderColour = NotCDA }; } - //case LABEL_ITEM_HANDOFF_IND: - // - // - // if (flightDataRecord.IsHandoff) - // { - // return new CustomLabelItem() - // { - // Text = "H" + flightDataRecord.HandoffController.ToString(), - // }; - // } - // - // else if (flightDataRecord.State == FDR.FDRStates.STATE_HANDOVER_FIRST) - // { - // return new CustomLabelItem() - // { - // Text = "O" + flightDataRecord.HandoffController.ToString(), - // }; - // } - // - // else - // { - // return new CustomLabelItem() - // { - // Text = "" - // }; - // } +// case LABEL_ITEM_HANDOFF_IND: +// +// +// if (flightDataRecord.IsHandoff) +// { +// return new CustomLabelItem() +// { +// Text = "H" + flightDataRecord.HandoffSector.Name, +// }; +// } +// +// else if (flightDataRecord.State == FDR.FDRStates.STATE_HANDOVER_FIRST) +// { +// return new CustomLabelItem() +// { +// Text = "O" + flightDataRecord.HandoffSector.Name, +// }; +// } +// +// else +// { +// return new CustomLabelItem() +// { +// Text = "" +// }; +// } case LABEL_ITEM_RADAR_IND: @@ -732,7 +794,7 @@ public CustomLabelItem GetCustomLabelItem(string itemType, Track track, FDP2.FDR { return new CustomLabelItem() { - Text = "^" + Text = "^", }; } @@ -749,7 +811,7 @@ public CustomLabelItem GetCustomLabelItem(string itemType, Track track, FDP2.FDR var mach = Conversions.CalculateMach(flightDataRecord.TAS, GRIB.FindTemperature(flightDataRecord.PRL, track.GetLocation(), true)); return new CustomLabelItem() { - Text = "M" + Convert.ToDecimal(mach).ToString("F2").Replace(".", "") + Text = "M" + Convert.ToDecimal(mach).ToString("F2").Replace(".", ""), //Text = "N" + flightDataRecord.TAS }; @@ -760,7 +822,7 @@ public CustomLabelItem GetCustomLabelItem(string itemType, Track track, FDP2.FDR : radarTrack.GroundSpeed; return new CustomLabelItem() { - Text = "N" + gs.ToString("000") //format as 3 digits (with leading zeros) + Text = "N" + gs.ToString("000"),//format as 3 digits (with leading zeros) }; default: @@ -786,12 +848,12 @@ public CustomColour SelectASDTrackColour(Track track) if (fdr.State != (FDR.FDRStates.STATE_PREACTIVE | FDR.FDRStates.STATE_COORDINATED)) //only apply conflict colours if planes are of concern { - return GetConflictColour(fdr.Callsign) ?? default; + return GetConflictColour(fdr.Callsign) ?? null; } else - return default; + return null; } diff --git a/AuroraStripItemPlugin.cs b/AuroraStripItemPlugin.cs index f83539e..3c2baa2 100644 --- a/AuroraStripItemPlugin.cs +++ b/AuroraStripItemPlugin.cs @@ -1,5 +1,4 @@ using System; -using System.Collections.Generic; using System.Text.RegularExpressions; using vatsys; using vatsys.Plugin; @@ -26,9 +25,14 @@ public class AuroraStripItemsPlugin : IStripPlugin const string STRIP_ITEM_DIST_FLAG = "AURORA_DIST_FLAG"; const string STRIP_ITEM_RVSM_FLAG = "AURORA_RVSM_FLAG"; const string STRIP_ITEM_VMI = "AURORA_STRIP_VMI"; + const string STRIP_ITEM_COMPLEX = "AURORA_STRIP_COMPLEX"; const string STRIP_ITEM_MAN_EST = "AURORA_MAN_EST"; - const string STRIP_ITEM_LATERAL_FLAG = "AURORA_LATERAL_FLAG"; + const string STRIP_ITEM_POINT = "AURORA_POINT"; + const string STRIP_ITEM_ROUTE = "AURORA_ROUTE_STRIP"; + const string STRIP_ITEM_RADAR_IND = "AURORA_RADAR_IND"; const string STRIP_ITEM_ANNOT_IND = "AURORA_ANNOT_STRIP"; + const string STRIP_ITEM_LATERAL_FLAG = "AURORA_LATERAL_FLAG"; + const string STRIP_ITEM_RESTR = "AURORA_RESTR_STRIP"; readonly static CustomColour NonRVSM = new CustomColour(242, 133, 0); readonly static CustomColour SepFlags = new CustomColour(0, 196, 253); readonly static CustomColour Pending = new CustomColour(46, 139, 87); @@ -72,7 +76,7 @@ public void OnRadarTrackUpdate(RDP.RadarTrack updated) // estimate.IsPETO = true; //} - private void ItemMouseClick(CustomLabelItemMouseClickEventArgs e) + private void ItemMouseClick(CustomStripItemMouseClickEventArgs e) { bool flagToggled = flagtoggle.TryGetValue(e.Track.GetFDR().Callsign, out _); @@ -89,28 +93,27 @@ private void ItemMouseClick(CustomLabelItemMouseClickEventArgs e) public CustomStripItem GetCustomStripItem(string itemType, Track track, FDP2.FDR flightDataRecord, RDP.RadarTrack radarTrack) { - Match pbn = Regex.Match(flightDataRecord.Remarks, @"PBN\/\w+\s"); - bool cpdlc = Regex.IsMatch(flightDataRecord.AircraftEquip, @"J5") || Regex.IsMatch(flightDataRecord.AircraftEquip, @"J7"); - bool adsc = Regex.IsMatch(flightDataRecord.AircraftSurvEquip, @"D1"); + var pbn = Regex.Match(flightDataRecord.Remarks, @"PBN\/\w+\s"); + bool rnp10 = pbn.Value.Contains("A1"); + bool rnp4 = pbn.Value.Contains("L1"); + bool cpdlc = flightDataRecord.AircraftEquip.Contains("J5") || flightDataRecord.AircraftEquip.Contains("J7"); + bool adsc = flightDataRecord.AircraftSurvEquip.Contains("D1"); bool adsb = flightDataRecord.ADSB; - bool rnp10 = Regex.IsMatch(pbn.Value, @"A1"); - bool rnp4 = Regex.IsMatch(pbn.Value, @"L1"); bool rvsm = flightDataRecord.RVSM; int level = radarTrack == null ? flightDataRecord.PRL / 100 : radarTrack.CorrectedAltitude / 100; int cfl; bool isCfl = Int32.TryParse(flightDataRecord.CFLString, out cfl); bool isEastBound = true; + eastboundCallsigns.TryGetValue(flightDataRecord.Callsign, out isEastBound); - - if (flightDataRecord == null) + if (flightDataRecord == null) return null; switch (itemType) { case STRIP_ITEM_CALLSIGN: - eastboundCallsigns.TryGetValue(flightDataRecord.Callsign, out isEastBound); - + if (isEastBound) { return new CustomStripItem() @@ -147,75 +150,78 @@ public CustomStripItem GetCustomStripItem(string itemType, Track track, FDP2.FDR - //case STRIP_ITEM_NXTSECTOR: - // - // var zpoints = flightDataRecord.ParsedRoute.ToList().Where(s => s.Type == FDP2.FDR.ExtractedRoute.Segment.SegmentTypes.ZPOINT); - // - // foreach (var zpoint in zpoints) - // - // { - // if (zpoint.ETO > DateTime.UtcNow) - // { - // SectorsVolumes.Sector sector = SectorsVolumes.FindSector(); - // } - // } - // return new CustomStripItem() - // { - // ForeColourIdentity = Colours.Identities.Custom, - // CustomForeColour = Pending, - // Text = - // }; + case STRIP_ITEM_NXTSECTOR: + + TOC toc; + toc = new TOC(flightDataRecord); + + string firName = toc.nextSector == null ? "" : toc.nextSector.Name; + + { + return new CustomStripItem() + { + ForeColourIdentity = Colours.Identities.Custom, + CustomForeColour = Pending, + Text = firName + }; + } case LABEL_ITEM_ADSB_CPDLC: - if (isEastBound && !adsb && cpdlc) + if (!isEastBound && !adsb && cpdlc) return new CustomStripItem() { - BackColourIdentity = Colours.Identities.StripText, - ForeColourIdentity = Colours.Identities.StripBackground, + BackColourIdentity = Colours.Identities.StripBackground, + ForeColourIdentity = Colours.Identities.StripText, Text = "⧆" }; - else if (!isEastBound && !adsb && cpdlc) + if (isEastBound && !adsb && cpdlc) return new CustomStripItem() { + BackColourIdentity = Colours.Identities.StripText, + ForeColourIdentity = Colours.Identities.StripBackground, Text = "⧆" }; - else if (isEastBound && !adsb) + if (!isEastBound && !adsb) return new CustomStripItem() { - BackColourIdentity = Colours.Identities.StripText, - ForeColourIdentity = Colours.Identities.StripBackground, + BackColourIdentity = Colours.Identities.StripBackground, + ForeColourIdentity = Colours.Identities.StripText, Text = "⎕" }; - else if (!isEastBound && !adsb) + if (isEastBound && !adsb) return new CustomStripItem() { + BackColourIdentity = Colours.Identities.StripText, + ForeColourIdentity = Colours.Identities.StripBackground, Text = "⎕" }; - else if (isEastBound && cpdlc) + if (!isEastBound && cpdlc) return new CustomStripItem() { - BackColourIdentity = Colours.Identities.StripText, - ForeColourIdentity = Colours.Identities.StripBackground, + BackColourIdentity = Colours.Identities.StripBackground, + ForeColourIdentity = Colours.Identities.StripText, Text = "*" }; - else if (!isEastBound && cpdlc) + if (isEastBound && cpdlc) return new CustomStripItem() { + BackColourIdentity = Colours.Identities.StripText, + ForeColourIdentity = Colours.Identities.StripBackground, Text = "*" }; @@ -229,8 +235,8 @@ public CustomStripItem GetCustomStripItem(string itemType, Track track, FDP2.FDR { //BackColourIdentity = Colours.Identities.Custom, //CustomBackColour = SepFlags, - Text = "M", - OnMouseClick = ItemMouseClick + Text = "M" + //OnMouseClick = ItemMouseClick }; return null; @@ -250,7 +256,7 @@ public CustomStripItem GetCustomStripItem(string itemType, Track track, FDP2.FDR case STRIP_ITEM_DIST_FLAG: - if (adsc & cpdlc & rnp4 || rnp10) + if (adsc & cpdlc & (rnp4 || rnp10)) return new CustomStripItem() @@ -299,6 +305,18 @@ public CustomStripItem GetCustomStripItem(string itemType, Track track, FDP2.FDR return null; + case STRIP_ITEM_COMPLEX: + + if (flightDataRecord.LabelOpData.Contains("AT ") || flightDataRecord.LabelOpData.Contains(" BY ") || + flightDataRecord.LabelOpData.Contains("CLEARED TO ")) + + return new CustomStripItem() + { + Text = "*" + }; + + return null; + //case STRIP_ITEM_MAN_EST: //if (Estimates) @@ -308,12 +326,51 @@ public CustomStripItem GetCustomStripItem(string itemType, Track track, FDP2.FDR // }; //return null; + //case STRIP_ITEM_POINT: + // Coordinate coordinate = Conversions.ConvertToCoordinate(FDR.ExtractedRoute); + // + // if (StripItemType.Point == ) + // return new CustomStripItem() + // { + // Text = Conversions.ConvertToFlightplanLatLong() + // }; + case STRIP_ITEM_ROUTE: + + return new CustomStripItem() + { + Text = "F", + //OnMouseClick = ItemMouseClick + }; + + + case STRIP_ITEM_RADAR_IND: + + return new CustomStripItem() + { + Text = "A", + //OnMouseClick = + }; + + case STRIP_ITEM_ANNOT_IND: - return new CustomStripItem() + bool scratch = String.IsNullOrEmpty(flightDataRecord.LabelOpData); + + if (scratch) + { + return new CustomStripItem() + { + Text = "." + }; + } + + else { - Text = "." //& - }; + return new CustomStripItem() + { + Text = "&" + }; + } case STRIP_ITEM_LATERAL_FLAG: @@ -323,10 +380,23 @@ public CustomStripItem GetCustomStripItem(string itemType, Track track, FDP2.FDR return new CustomStripItem() { - //BackColourIdentity = Colours.Identities.Custom, - Text = rnp4 ? "4" : "R", - OnMouseClick = ItemMouseClick + BackColourIdentity = Colours.Identities.Custom, + CustomBackColour = SepFlags, + Text = rnp4 ? "4" : rnp10 ? "R" : "", + //OnMouseClick = ItemMouseClick + }; + return null; + + case STRIP_ITEM_RESTR: + + if (flightDataRecord.LabelOpData.Contains("AT ") || flightDataRecord.LabelOpData.Contains(" BY ") || + flightDataRecord.LabelOpData.Contains("CLEARED TO ")) + + return new CustomStripItem() + { + Text = "x" }; + return null; default: return null; diff --git a/ConflictSummaryWindw.Designer.cs b/ConflictSummaryWindw.Designer.cs new file mode 100644 index 0000000..e796658 --- /dev/null +++ b/ConflictSummaryWindw.Designer.cs @@ -0,0 +1,267 @@ +namespace AuroraLabelItemsPlugin +{ + partial class Form1 + { + /// + /// Required designer variable. + /// + private System.ComponentModel.IContainer components = null; + + /// + /// Clean up any resources being used. + /// + /// true if managed resources should be disposed; otherwise, false. + protected override void Dispose(bool disposing) + { + if (disposing && (components != null)) + { + components.Dispose(); + } + base.Dispose(disposing); + } + + #region Windows Form Designer generated code + + /// + /// Required method for Designer support - do not modify + /// the contents of this method with the code editor. + /// + private void InitializeComponent() + { + System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(Form1)); + this.textBox1 = new System.Windows.Forms.TextBox(); + this.textBox2 = new System.Windows.Forms.TextBox(); + this.textBox3 = new System.Windows.Forms.TextBox(); + this.textBox4 = new System.Windows.Forms.TextBox(); + this.textBox5 = new System.Windows.Forms.TextBox(); + this.textBox6 = new System.Windows.Forms.TextBox(); + this.textBox7 = new System.Windows.Forms.TextBox(); + this.textBox8 = new System.Windows.Forms.TextBox(); + this.listView1 = new System.Windows.Forms.ListView(); + this.textBox9 = new System.Windows.Forms.TextBox(); + this.Intruder = ((System.Windows.Forms.ColumnHeader)(new System.Windows.Forms.ColumnHeader())); + this.Att = ((System.Windows.Forms.ColumnHeader)(new System.Windows.Forms.ColumnHeader())); + this.Active = ((System.Windows.Forms.ColumnHeader)(new System.Windows.Forms.ColumnHeader())); + this.Att2 = ((System.Windows.Forms.ColumnHeader)(new System.Windows.Forms.ColumnHeader())); + this.Ovrd = ((System.Windows.Forms.ColumnHeader)(new System.Windows.Forms.ColumnHeader())); + this.Type = ((System.Windows.Forms.ColumnHeader)(new System.Windows.Forms.ColumnHeader())); + this.StartTime = ((System.Windows.Forms.ColumnHeader)(new System.Windows.Forms.ColumnHeader())); + this.EndTime = ((System.Windows.Forms.ColumnHeader)(new System.Windows.Forms.ColumnHeader())); + this.SuspendLayout(); + // + // textBox1 + // + this.textBox1.BackColor = System.Drawing.SystemColors.Control; + this.textBox1.BorderStyle = System.Windows.Forms.BorderStyle.None; + this.textBox1.Cursor = System.Windows.Forms.Cursors.Default; + this.textBox1.Font = new System.Drawing.Font("Terminus (TTF)", 7.999999F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0))); + this.textBox1.Location = new System.Drawing.Point(17, 111); + this.textBox1.Name = "textBox1"; + this.textBox1.Size = new System.Drawing.Size(112, 18); + this.textBox1.TabIndex = 0; + this.textBox1.Text = "Intruder"; + // + // textBox2 + // + this.textBox2.BackColor = System.Drawing.SystemColors.Control; + this.textBox2.BorderStyle = System.Windows.Forms.BorderStyle.None; + this.textBox2.Cursor = System.Windows.Forms.Cursors.Default; + this.textBox2.Font = new System.Drawing.Font("Terminus (TTF)", 7.999999F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0))); + this.textBox2.Location = new System.Drawing.Point(146, 111); + this.textBox2.Name = "textBox2"; + this.textBox2.Size = new System.Drawing.Size(44, 18); + this.textBox2.TabIndex = 1; + this.textBox2.Text = "Att"; + // + // textBox3 + // + this.textBox3.BackColor = System.Drawing.SystemColors.Control; + this.textBox3.BorderStyle = System.Windows.Forms.BorderStyle.None; + this.textBox3.Cursor = System.Windows.Forms.Cursors.Default; + this.textBox3.Font = new System.Drawing.Font("Terminus (TTF)", 7.999999F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0))); + this.textBox3.Location = new System.Drawing.Point(317, 111); + this.textBox3.Name = "textBox3"; + this.textBox3.Size = new System.Drawing.Size(44, 18); + this.textBox3.TabIndex = 2; + this.textBox3.Text = "Att"; + // + // textBox4 + // + this.textBox4.BackColor = System.Drawing.SystemColors.Control; + this.textBox4.BorderStyle = System.Windows.Forms.BorderStyle.None; + this.textBox4.Cursor = System.Windows.Forms.Cursors.Default; + this.textBox4.Font = new System.Drawing.Font("Terminus (TTF)", 7.999999F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0))); + this.textBox4.Location = new System.Drawing.Point(215, 111); + this.textBox4.Name = "textBox4"; + this.textBox4.Size = new System.Drawing.Size(85, 18); + this.textBox4.TabIndex = 3; + this.textBox4.Text = "Active"; + // + // textBox5 + // + this.textBox5.BackColor = System.Drawing.SystemColors.Control; + this.textBox5.BorderStyle = System.Windows.Forms.BorderStyle.None; + this.textBox5.Cursor = System.Windows.Forms.Cursors.Default; + this.textBox5.Font = new System.Drawing.Font("Terminus (TTF)", 7.999999F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0))); + this.textBox5.Location = new System.Drawing.Point(378, 111); + this.textBox5.Name = "textBox5"; + this.textBox5.Size = new System.Drawing.Size(61, 18); + this.textBox5.TabIndex = 4; + this.textBox5.Text = "Ovrd"; + // + // textBox6 + // + this.textBox6.BackColor = System.Drawing.SystemColors.Control; + this.textBox6.BorderStyle = System.Windows.Forms.BorderStyle.None; + this.textBox6.Cursor = System.Windows.Forms.Cursors.Default; + this.textBox6.Font = new System.Drawing.Font("Terminus (TTF)", 7.999999F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0))); + this.textBox6.Location = new System.Drawing.Point(456, 111); + this.textBox6.Name = "textBox6"; + this.textBox6.Size = new System.Drawing.Size(61, 18); + this.textBox6.TabIndex = 5; + this.textBox6.Text = "Type"; + // + // textBox7 + // + this.textBox7.BackColor = System.Drawing.SystemColors.Control; + this.textBox7.BorderStyle = System.Windows.Forms.BorderStyle.None; + this.textBox7.Cursor = System.Windows.Forms.Cursors.Default; + this.textBox7.Font = new System.Drawing.Font("Terminus (TTF)", 7.999999F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0))); + this.textBox7.Location = new System.Drawing.Point(535, 111); + this.textBox7.Name = "textBox7"; + this.textBox7.Size = new System.Drawing.Size(121, 18); + this.textBox7.TabIndex = 6; + this.textBox7.Text = "StartTime"; + // + // textBox8 + // + this.textBox8.BackColor = System.Drawing.SystemColors.Control; + this.textBox8.BorderStyle = System.Windows.Forms.BorderStyle.None; + this.textBox8.Cursor = System.Windows.Forms.Cursors.Default; + this.textBox8.Font = new System.Drawing.Font("Terminus (TTF)", 7.999999F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0))); + this.textBox8.Location = new System.Drawing.Point(679, 111); + this.textBox8.Name = "textBox8"; + this.textBox8.Size = new System.Drawing.Size(94, 18); + this.textBox8.TabIndex = 7; + this.textBox8.Text = "EndTime"; + // + // listView1 + // + this.listView1.BackColor = System.Drawing.Color.Red; + this.listView1.Columns.AddRange(new System.Windows.Forms.ColumnHeader[] { + this.Intruder, + this.Att, + this.Active, + this.Att2, + this.Ovrd, + this.Type, + this.StartTime, + this.EndTime}); + this.listView1.ForeColor = System.Drawing.SystemColors.ButtonFace; + this.listView1.HideSelection = false; + this.listView1.Location = new System.Drawing.Point(29, 160); + this.listView1.Name = "listView1"; + this.listView1.Size = new System.Drawing.Size(744, 474); + this.listView1.TabIndex = 8; + this.listView1.UseCompatibleStateImageBehavior = false; + this.listView1.SelectedIndexChanged += new System.EventHandler(this.listView1_SelectedIndexChanged); + // + // textBox9 + // + this.textBox9.BackColor = System.Drawing.SystemColors.ButtonHighlight; + this.textBox9.Font = new System.Drawing.Font("Terminus (TTF)", 7.999999F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0))); + this.textBox9.Location = new System.Drawing.Point(6, 12); + this.textBox9.Name = "textBox9"; + this.textBox9.Size = new System.Drawing.Size(782, 25); + this.textBox9.TabIndex = 9; + this.textBox9.Text = "CONFLICT SUMMARY"; + this.textBox9.TextAlign = System.Windows.Forms.HorizontalAlignment.Center; + // + // Intruder + // + this.Intruder.Width = 8; + // + // Att + // + this.Att.TextAlign = System.Windows.Forms.HorizontalAlignment.Center; + this.Att.Width = 1; + // + // Active + // + this.Active.TextAlign = System.Windows.Forms.HorizontalAlignment.Center; + this.Active.Width = 8; + // + // Att2 + // + this.Att2.TextAlign = System.Windows.Forms.HorizontalAlignment.Center; + this.Att2.Width = 1; + // + // Ovrd + // + this.Ovrd.TextAlign = System.Windows.Forms.HorizontalAlignment.Center; + this.Ovrd.Width = 1; + // + // Type + // + this.Type.TextAlign = System.Windows.Forms.HorizontalAlignment.Center; + this.Type.Width = 3; + // + // StartTime + // + this.StartTime.TextAlign = System.Windows.Forms.HorizontalAlignment.Center; + this.StartTime.Width = 4; + // + // EndTime + // + this.EndTime.TextAlign = System.Windows.Forms.HorizontalAlignment.Center; + this.EndTime.Width = 4; + // + // Form1 + // + this.AutoScaleDimensions = new System.Drawing.SizeF(9F, 20F); + this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; + this.BackColor = System.Drawing.SystemColors.Control; + this.ClientSize = new System.Drawing.Size(800, 664); + this.Controls.Add(this.textBox9); + this.Controls.Add(this.listView1); + this.Controls.Add(this.textBox8); + this.Controls.Add(this.textBox7); + this.Controls.Add(this.textBox6); + this.Controls.Add(this.textBox5); + this.Controls.Add(this.textBox4); + this.Controls.Add(this.textBox3); + this.Controls.Add(this.textBox2); + this.Controls.Add(this.textBox1); + this.ForeColor = System.Drawing.SystemColors.ControlDark; + this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.None; + this.Icon = ((System.Drawing.Icon)(resources.GetObject("$this.Icon"))); + this.Name = "Form1"; + this.RightToLeft = System.Windows.Forms.RightToLeft.No; + this.Text = "CONFLICT SUMMARY"; + this.ResumeLayout(false); + this.PerformLayout(); + + } + + #endregion + + private System.Windows.Forms.TextBox textBox1; + private System.Windows.Forms.TextBox textBox2; + private System.Windows.Forms.TextBox textBox3; + private System.Windows.Forms.TextBox textBox4; + private System.Windows.Forms.TextBox textBox5; + private System.Windows.Forms.TextBox textBox6; + private System.Windows.Forms.TextBox textBox7; + private System.Windows.Forms.TextBox textBox8; + private System.Windows.Forms.ListView listView1; + private System.Windows.Forms.TextBox textBox9; + private System.Windows.Forms.ColumnHeader Intruder; + private System.Windows.Forms.ColumnHeader Att; + private System.Windows.Forms.ColumnHeader Active; + private System.Windows.Forms.ColumnHeader Att2; + private System.Windows.Forms.ColumnHeader Ovrd; + private System.Windows.Forms.ColumnHeader Type; + private System.Windows.Forms.ColumnHeader StartTime; + private System.Windows.Forms.ColumnHeader EndTime; + } +} \ No newline at end of file diff --git a/ConflictSummaryWindw.cs b/ConflictSummaryWindw.cs new file mode 100644 index 0000000..ff18f61 --- /dev/null +++ b/ConflictSummaryWindw.cs @@ -0,0 +1,34 @@ +using System; +using System.Collections.Generic; +using System.ComponentModel; +using System.Data; +using System.Drawing; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using System.Windows.Forms; +using vatsys; + +namespace AuroraLabelItemsPlugin +{ + public partial class Form1 : Form + { + AuroraLabelItemsPlugin type = new AuroraLabelItemsPlugin(); + CPAR conflicts = new CPAR(); + public Form1() + { + foreach (var segment in conflicts.Segments1) + { + segment.callsign.ToString(); + segment.startTime.ToString(); + segment.endTime.ToString(); + } + InitializeComponent(); + } + + private void listView1_SelectedIndexChanged(object sender, EventArgs e) + { + + } + } +} diff --git a/ConflictSummaryWindw.resx b/ConflictSummaryWindw.resx new file mode 100644 index 0000000..692ee50 --- /dev/null +++ b/ConflictSummaryWindw.resx @@ -0,0 +1,4632 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + + + AAABAAEAAAAAAAEAIAAoIAQAFgAAACgAAAAAAQAAAAIAAAEAIAAAAAAAACAEABMLAAATCwAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD//wAI//8An///AP///wD///8A//// + AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A//// + AP///wD///8A////AP///wD///8Ax///ADAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD//wBA//8A2f//AP///wD///8A//// + AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A//// + AP///wD///8A////AP///wD///8A////AP///wD///8AagAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD//wB6//8A////AP///wD///8A//// + AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A//// + AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wB6AAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD//wB6//8A////AP///wD///8A//// + AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A//// + AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AHoAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD//wB6//8A////AP///wD///8A//// + AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A//// + AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8AegAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD//wB6//8A////AP///wD///8A//// + AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A//// + AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A//// + AP///wB6AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD//wB6//8A////AP///wD///8A//// + AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A//// + AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A//// + AP///wD///8A////AHoAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD//wB6//8A////AP///wD///8A//// + AP///wD///8A////AP///wD///8A////AP///wD///8A////AP/i4gn/oaEf/2pqKv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/1paLf+HhyX/w8MV////AP///wD///8A////AP///wD///8A////AP///wD///8A//// + AP///wD///8A////AP///wD///8AegAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD//wB6//8A////AP///wD///8A//// + AP///wD///8A////AP///wD///8A////AP///wD///8A/+zsBf95eSj/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv9aWi3/zs4S////AP///wD///8A////AP///wD///8A//// + AP///wD///8A////AP///wD///8A////AP///wB6AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD//wB6//8A////AP///wD///8A//// + AP///wD///8A////AP///wD///8A////AP///wD///8A/8PDFf9HRzD/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv/DwxX///8A////AP///wD///8A//// + AP///wD///8A////AP///wD///8A////AP///wD///8A////AHoAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD//wB6//8A////AP///wD///8A//// + AP///wD///8A////AP///wD///8A////AP///wD///8A/8PDFf8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/8PDFf///wD///8A//// + AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8AegAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD//wB6//8A////AP///wD///8A//// + AP///wD///8A////AP///wD///8A////AP///wD///8A/8PDFf8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/w8MV//// + AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wB6AAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD//wB6//8A////AP///wD///8A//// + AP///wD///8A////AP///wD///8A////AP///wD///8A/8PDFf8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv/DwxX///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A//// + AHoAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD//wB6//8A////AP///wD///8A//// + AP///wD///8A////AP///wD///8A////AP///wD///8A/8PDFf8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/8PDFf///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A//// + AP///wD///8AegAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD//wB6//8A////AP///wD///8A//// + AP///wD///8A////AP///wD///8A////AP///wD///8A/8PDFf8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/w8MV////AP///wD///8A////AP///wD///8A////AP///wD///8A//// + AP///wD///8A////AP///wB6AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD//wB6//8A////AP///wD///8A//// + AP///wD///8A////AP///wD///8A////AP///wD///8A/8PDFf8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv/DwxX///8A////AP///wD///8A////AP///wD///8A//// + AP///wD///8A////AP///wD///8A////AHoAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD//wB6//8A////AP///wD///8A//// + AP///wD///8A////AP///wD///8A////AP///wD///8A/8PDFf8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/8PDFf///wD///8A////AP///wD///8A//// + AP///wD///8A////AP///wD///8A////AP///wD///8AegAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD//wB6//8A////AP///wD///8A//// + AP///wD///8A////AP///wD///8A////AP///wD///8A/8PDFf8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/w8MV////AP///wD///8A//// + AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wB6AAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD//wB6//8A////AP///wD///8A//// + AP///wD///8A////AP///wD///8A////AP///wD///8A/8PDFf8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv/DwxX///8A//// + AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AHoAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD//wB6//8A////AP///wD///8A//// + AP///wD///8A////AP///wD///8A////AP///wD///8A/8PDFf8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/8PD + Ff///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8AegAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD//wB6//8A////AP///wD///8A//// + AP///wD///8A////AP///wD///8A////AP///wD///8A/8PDFf8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/w8MV////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A//// + AP///wB6AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD//wB6//8A////AP///wD///8A//// + AP///wD///8A////AP///wD///8A////AP///wD///8A/8PDFf8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv/DwxX///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A//// + AP///wD///8A////AHoAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD//wB6//8A////AP///wD///8A//// + AP///wD///8A////AP///wD///8A////AP///wD///8A/8PDFf8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/8PDFf///wD///8A////AP///wD///8A////AP///wD///8A//// + AP///wD///8A////AP///wD///8AegAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD//wB6//8A////AP///wD///8A//// + AP///wD///8A////AP///wD///8A////AP///wD///8A/8PDFf8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/w8MV////AP///wD///8A////AP///wD///8A//// + AP///wD///8A////AP///wD///8A////AP///wB6AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD//wB6//8A////AP///wD///8A//// + AP///wD///8A////AP///wD///8A////AP///wD///8A/8PDFf8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv/DwxX///8A////AP///wD///8A//// + AP///wD///8A////AP///wD///8A////AP///wD///8A////AHoAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD//wB6//8A////AP///wD///8A//// + AP///wD///8A////AP///wD///8A////AP///wD///8A/8PDFf8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/8PDFf///wD///8A//// + AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8AigAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD//wB6//8A////AP///wD///8A//// + AP///wD///8A////AP///wD///8A////AP///wD///8A/8PDFf8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/w8MV//// + AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wC5AAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD//wB6//8A////AP///wD///8A//// + AP///wD///8A////AP///wD///8A////AP///wD///8A/8PDFf8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv/DwxX///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A//// + ALkAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD//wB6//8A////AP///wD///8A//// + AP///wD///8A////AP///wD///8A////AP///wD///8A/8PDFf8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/8PDFf///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A//// + AP///wD///8AuQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD//wB6//8A////AP///wD///8A//// + AP///wD///8A////AP///wD///8A////AP///wD///8A/8PDFf8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/w8MV////AP///wD///8A////AP///wD///8A////AP///wD///8A//// + AP///wD///8A////AP///wC5AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD//wB6//8A////AP///wD///8A//// + AP///wD///8A////AP///wD///8A////AP///wD///8A/8PDFf8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv/DwxX///8A////AP///wD///8A////AP///wD///8A//// + AP///wD///8A////AP///wD///8A////ALkAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD//wB6//8A////AP///wD///8A//// + AP///wD///8A////AP///wD///8A////AP///wD///8A/8PDFf8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/8PDFf///wD///8A////AP///wD///8A//// + AP///wD///8A////AP///wD///8A////AP///wD///8AuQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD//wB6//8A////AP///wD///8A//// + AP///wD///8A////AP///wD///8A////AP///wD///8A/8PDFf8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/uLgZ////AP///wD///8A//// + AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wC5AAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD//wB6//8A////AP///wD///8A//// + AP///wD///8A////AP///wD///8A////AP///wD///8A/8PDFf8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv+VlSL///8A//// + AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////ALkAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD//wB6//8A////AP///wD///8A//// + AP///wD///8A////AP///wD///8A////AP///wD///8A/8PDFf8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/5WV + Iv///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8AuQAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD//wB6//8A////AP///wD///8A//// + AP///wD///8A////AP///wD///8A////AP///wD///8A/8PDFf8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/lZUi////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A//// + AP///wC5AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD//wB6//8A////AP///wD///8A//// + AP///wD///8A////AP///wD///8A////AP///wD///8A/8PDFf8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv+VlSL///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A//// + AP///wD///8A////ALkAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD//wB6//8A////AP///wD///8A//// + AP///wD///8A////AP///wD///8A////AP///wD///8A/8PDFf8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/5WVIv///wD///8A////AP///wD///8A////AP///wD///8A//// + AP///wD///8A////AP///wD///8AuQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD//wB6//8A////AP///wD///8A//// + AP///wD///8A////AP///wD///8A////AP///wD///8A/8PDFf8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/lZUi////AP///wD///8A////AP///wD///8A//// + AP///wD///8A////AP///wD///8A////AP///wC5AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD//wB6//8A////AP///wD///8A//// + AP///wD///8A////AP///wD///8A////AP///wD///8A/8PDFf8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv+VlSL///8A////AP///wD///8A//// + AP///wD///8A////AP///wD///8A////AP///wD///8A////ALkAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD//wB///8A////AP///wD///8A//// + AP///wD///8A////AP///wD///8A////AP///wD///8A/8PDFf8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/5WVIv///wD///8A//// + AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8AuQAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD//wC5//8A////AP///wD///8A//// + AP///wD///8A////AP///wD///8A////AP///wD///8A/8PDFf8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/lZUi//// + AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wC5AAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD//wC5//8A////AP///wD///8A//// + AP///wD///8A////AP///wD///8A////AP///wD///8A/8PDFf8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv+VlSL///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A//// + ALkAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD//wC5//8A////AP///wD///8A//// + AP///wD///8A////AP///wD///8A////AP///wD///8A/8PDFf8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/5WVIv///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A//// + AP///wD///8AuQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD//wC5//8A////AP///wD///8A//// + AP///wD///8A////AP///wD///8A////AP///wD///8A/8PDFf8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/lZUi////AP///wD///8A////AP///wD///8A////AP///wD///8A//// + AP///wD///8A////AP///wC5AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD//wC5//8A////AP///wD///8A//// + AP///wD///8A////AP///wD///8A////AP///wD///8A/8PDFf8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv+VlSL///8A////AP///wD///8A////AP///wD///8A//// + AP///wD///8A////AP///wD///8A////ALkAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD//wC5//8A////AP///wD///8A//// + AP///wD///8A////AP///wD///8A////AP///wD///8A/8PDFf8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/5WVIv///wD///8A////AP///wD///8A//// + AP///wD///8A////AP///wD///8A////AP///wD///8AuQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD//wC5//8A////AP///wD///8A//// + AP///wD///8A////AP///wD///8A////AP///wD///8A/8PDFf8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/lZUi////AP///wD///8A//// + AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wC5AAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD//wC5//8A////AP///wD///8A//// + AP///wD///8A////AP///wD///8A////AP///wD///8A/5WVIv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv+VlSL///8A//// + AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////ALkAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD//wC5//8A////AP///wD///8A//// + AP///wD///8A////AP///wD///8A////AP///wD///8A/5WVIv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/5WV + Iv///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8AuQAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD//wC5//8A////AP///wD///8A//// + AP///wD///8A////AP///wD///8A////AP///wD///8A/5WVIv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/lZUi////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A//// + AP///wC5AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD//wC5//8A////AP///wD///8A//// + AP///wD///8A////AP///wD///8A////AP///wD///8A/5WVIv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv+VlSL///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A//// + AP///wD///8A////ALkAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD//wC5//8A////AP///wD///8A//// + AP///wD///8A////AP///wD///8A////AP///wD///8A/5WVIv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/5WVIv///wD///8A////AP///wD///8A////AP///wD///8A//// + AP///wD///8A////AP///wD///8AuQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD//wC5//8A////AP///wD///8A//// + AP///wD///8A////AP///wD///8A////AP///wD///8A/5WVIv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/lZUi////AP///wD///8A////AP///wD///8A//// + AP///wD///8A////AP///wD///8A////AP///wC5AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD//wC5//8A////AP///wD///8A//// + AP///wD///8A////AP///wD///8A////AP///wD///8A/5WVIv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv+VlSL///8A////AP///wD///8A//// + AP///wD///8A////AP///wD///8A////AP///wD///8A////ALkAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD//wC5//8A////AP///wD///8A//// + AP///wD///8A////AP///wD///8A////AP///wD///8A/5WVIv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/5WVIv///wD///8A//// + AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8AuQAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD//wC5//8A////AP///wD///8A//// + AP///wD///8A////AP///wD///8A////AP///wD///8A/5WVIv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/lZUi//// + AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wC5AAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD//wC5//8A////AP///wD///8A//// + AP///wD///8A////AP///wD///8A////AP///wD///8A/5WVIv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv+VlSL///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A//// + ALkAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD//wC5//8A////AP///wD///8A//// + AP///wD///8A////AP///wD///8A////AP///wD///8A/5WVIv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/5WVIv///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A//// + AP///wD///8AuQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD//wC5//8A////AP///wD///8A//// + AP///wD///8A////AP///wD///8A////AP///wD///8A/5WVIv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/lZUi////AP///wD///8A////AP///wD///8A////AP///wD///8A//// + AP///wD///8A////AP///wC5AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD//wC5//8A////AP///wD///8A//// + AP///wD///8A////AP///wD///8A////AP///wD///8A/5WVIv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv+VlSL///8A////AP///wD///8A////AP///wD///8A//// + AP///wD///8A////AP///wD///8A////ALkAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD//wC5//8A////AP///wD///8A//// + AP///wD///8A////AP///wD///8A////AP///wD///8A/5WVIv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/5WVIv///wD///8A////AP///wD///8A//// + AP///wD///8A////AP///wD///8A////AP///wD///8AuQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD//wC5//8A////AP///wD///8A//// + AP///wD///8A////AP///wD///8A////AP///wD///8A/5WVIv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/lZUi////AP///wD///8A//// + AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wC5AAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD//wC5//8A////AP///wD///8A//// + AP///wD///8A////AP///wD///8A////AP///wD///8A/5WVIv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv+VlSL///8A//// + AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////ALkAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD//wC5//8A////AP///wD///8A//// + AP///wD///8A////AP///wD///8A////AP///wD///8A/5WVIv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/5WV + Iv///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8AuQAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD//wC5//8A////AP///wD///8A//// + AP///wD///8A////AP///wD///8A////AP///wD///8A/5WVIv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/lZUi////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A//// + AP///wC5AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD//wC5//8A////AP///wD///8A//// + AP///wD///8A////AP///wD///8A////AP///wD///8A/5WVIv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv+VlSL///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A//// + AP///wD///8A////ALkAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD//wC5//8A////AP///wD///8A//// + AP///wD///8A////AP///wD///8A////AP///wD///8A/5WVIv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/3l5 + KP8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/5WVIv///wD///8A////AP///wD///8A////AP///wD///8A//// + AP///wD///8A////AP///wD///8AuQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD//wC5//8A////AP///wD///8A//// + AP///wD///8A////AP///wD///8A////AP///wD///8A/5WVIv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/5WV + Iv///wD/w8MV/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/lZUi////AP///wD///8A////AP///wD///8A//// + AP///wD///8A////AP///wD///8A////AP///wC5AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD//wC5//8A////AP///wD///8A//// + AP///wD///8A////AP///wD///8A////AP///wD///8A/5WVIv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/5WV + Iv///wD///8A////AP/DwxX/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv+VlSL///8A////AP///wD///8A//// + AP///wD///8A////AP///wD///8A////AP///wD///8A////ALkAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD//wC5//8A////AP///wD///8A//// + AP///wD///8A////AP///wD///8A////AP///wD///8A/5WVIv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/5WV + Iv///wD///8A////AP///wD///8A/8PDFf8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/5WVIv///wD///8A//// + AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8AuQAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD//wC5//8A////AP///wD///8A//// + AP///wD///8A////AP///wD///8A////AP///wD///8A/5WVIv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/5WV + Iv///wD///8A////AP///wD///8A////AP///wD/w8MV/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/lZUi//// + AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wC5AAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD//wC5//8A////AP///wD///8A//// + AP///wD///8A////AP///wD///8A////AP///wD///8A/5WVIv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/5WV + Iv///wD///8A////AP///wD///8A////AP///wD///8A////AP/DwxX/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv+VlSL///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A//// + ALkAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD//wC5//8A////AP///wD///8A//// + AP///wD///8A////AP///wD///8A////AP///wD///8A/5WVIv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/5WV + Iv///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A/8PDFf8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/5WVIv///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A//// + AP///wD///8AuQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD//wC5//8A////AP///wD///8A//// + AP///wD///8A////AP///wD///8A////AP///wD///8A/5WVIv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/5WV + Iv///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD/w8MV/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/lZUi////AP///wD///8A////AP///wD///8A////AP///wD///8A//// + AP///wD///8A////AP///wC5AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD//wC5//8A////AP///wD///8A//// + AP///wD///8A////AP///wD///8A////AP///wD///8A/5WVIv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/5WV + Iv///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A//// + AP/DwxX/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv+VlSL///8A////AP///wD///8A////AP///wD///8A//// + AP///wD///8A////AP///wD///8A////ALn//wAYAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD//wC5//8A////AP///wD///8A//// + AP///wD///8A////AP///wD///8A////AP///wD///8A/5WVIv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/5WV + Iv///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A//// + AP///wD///8A/8PDFf8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/5WVIv///wD///8A////AP///wD///8A//// + AP///wD///8A////AP///wD///8A////AP///wD///8A6f//ACoAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD//wC5//8A////AP///wD///8A//// + AP///wD///8A////AP///wD///8A////AP///wD///8A/5WVIv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/5WV + Iv///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A//// + AP///wD///8A////AP///wD/w8MV/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/lZUi////AP///wD///8A//// + AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wDp//8AKgAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD//wC5//8A////AP///wD///8A//// + AP///wD///8A////AP///wD///8A////AP///wD///8A/5WVIv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/5WV + Iv///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A//// + AP///wD///8A////AP///wD///8A////AP/DwxX/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv+VlSL///8A//// + AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AOn//wAqAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD//wC5//8A////AP///wD///8A//// + AP///wD///8A////AP///wD///8A////AP///wD///8A/5WVIv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/5WV + Iv///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A//// + AP///wD///8A////AP///wD///8A////AP///wD///8A/8PDFf8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/5WV + Iv///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A6f// + ACoAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD//wC5//8A////AP///wD///8A//// + AP///wD///8A////AP///wD///8A////AP///wD///8A/5WVIv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/5WV + Iv///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A//// + AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD/w8MV/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/lZUi////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A//// + AP///wDp//8AKgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD//wC5//8A////AP///wD///8A//// + AP///wD///8A////AP///wD///8A////AP///wD///8A/5WVIv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/5WV + Iv///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8Auf// + AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP/DwxX/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv+VlSL///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A//// + AP///wD///8A////AOn//wAqAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD//wC5//8A////AP///wD///8A//// + AP///wD///8A////AP///wD///8A////AP///wD///8A/5WVIv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/5WV + Iv///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8AuQAA + AAD//wB6//8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A/8PD + Ff8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/5WVIv///wD///8A////AP///wD///8A////AP///wD///8A//// + AP///wD///8A////AP///wD///8A6f//ACoAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD//wC5//8A////AP///wD///8A//// + AP///wD///8A////AP///wD///8A////AP///wD///8A/5WVIv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/5WV + Iv///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8AuQAA + AAAAAAAAAAAAAP//AHr//wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A//// + AP///wD/w8MV/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/amoq//b2Av///wD///8A////AP///wD///8A//// + AP///wD///8A////AP///wD///8A////AP///wDp//8AKgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD//wC5//8A////AP///wD///8A//// + AP///wD///8A////AP///wD///8A////AP///wD///8A/5WVIv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/5WV + Iv///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8AuQAA + AAAAAAAAAAAAAAAAAAAAAAAA//8Aev//AP///wD///8A////AP///wD///8A////AP///wD///8A//// + AP///wD///8A////AP/DwxX/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv9qair/9vYC////AP///wD///8A//// + AP///wD///8A////AP///wD///8A////AP///wD///8A////AOn//wAqAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD//wC5//8A////AP///wD///8A//// + AP///wD///8A////AP///wD///8A////AP///wD///8A/5WVIv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/5WV + Iv///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8AuQAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD//wB6//8A////AP///wD///8A////AP///wD///8A//// + AP///wD///8A////AP///wD///8A/8PDFf8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/2pqKv/29gL///8A//// + AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A6f//ACoAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD//wC5//8A////AP///wD///8A//// + AP///wD///8A////AP///wD///8A////AP///wD///8A/5WVIv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/5WV + Iv///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8AuQAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP//AHr//wD///8A////AP///wD///8A//// + AP///wD///8A////AP///wD///8A////AP///wD/w8MV/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/amoq//b2 + Av///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wDp//8AKgAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD//wC5//8A////AP///wD///8A//// + AP///wD///8A////AP///wD///8A////AP///wD///8A/5WVIv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/5WV + Iv///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8AuQAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA//8Aev//AP///wD///8A//// + AP///wD///8A////AP///wD///8A////AP///wD///8A////AP/DwxX/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv9qair/9vYC////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A//// + AOn//wAqAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD//wC5//8A////AP///wD///8A//// + AP///wD///8A////AP///wD///8A////AP///wD///8A/5WVIv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/5WV + Iv///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8AuQAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD//wB6//8A//// + AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A/8PDFf8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/2pqKv/29gL///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A//// + AP///wD///8A6f//ACoAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD//wC5//8A////AP///wD///8A//// + AP///wD///8A////AP///wD///8A////AP///wD///8A/5WVIv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/6Gh + H////wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8AuQAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP// + AHr//wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD/w8MV/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/amoq//b2Av///wD///8A////AP///wD///8A////AP///wD///8A//// + AP///wD///8A////AP///wDp//8AKgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD//wC5//8A////AP///wD///8A//// + AP///wD///8A////AP///wD///8A////AP///wD///8A/5WVIv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/8PD + Ff///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8AuQAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAA//8Aev//AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A//// + AP/DwxX/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv9qair/9vYC////AP///wD///8A////AP///wD///8A//// + AP///wD///8A////AP///wD///8A////AOn//wAqAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP//ACr//wDJ//8A////AP///wD///8A//// + AP///wD///8A////AP///wD///8A////AP///wD///8A/5WVIv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/8PD + Ff///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8AuQAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAD//wB6//8A////AP///wD///8A////AP///wD///8A////AP///wD///8A//// + AP///wD///8A/8PDFf8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/2pqKv/29gL///8A////AP///wD///8A//// + AP///wD///8A////AP///wD///8A////AP///wD///8A6f//ACoAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP//ACr//wDp//8A////AP///wD///8A//// + AP///wD///8A////AP///wD///8A////AP///wD///8A/5WVIv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/8PD + Ff///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8AuQAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAP//AHr//wD///8A////AP///wD///8A////AP///wD///8A//// + AP///wD///8A////AP///wD/w8MV/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/amoq//b2Av///wD///8A//// + AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wDp//8AKgAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP//ACr//wDp//8A////AP///wD///8A//// + AP///wD///8A////AP///wD///8A////AP///wD///8A/5WVIv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/8PD + Ff///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8AuQAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA//8Aev//AP///wD///8A////AP///wD///8A//// + AP///wD///8A////AP///wD///8A////AP/DwxX/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv9qair/9vYC//// + AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AOn//wAqAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP//ACr//wDp//8A////AP///wD///8A//// + AP///wD///8A////AP///wD///8A////AP///wD///8A/5WVIv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/8PD + Ff///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8AuQAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD//wB6//8A////AP///wD///8A//// + AP///wD///8A////AP///wD///8A////AP///wD///8A/+LiCf9HRzD/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/2pq + Kv/29gL///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A6f// + ACoAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP//ACr//wDp//8A////AP///wD///8A//// + AP///wD///8A////AP///wD///8A////AP///wD///8A/5WVIv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/8PD + Ff///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8AuQAA + AAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP//AHr//wD///8A//// + AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD/4uIJ/0dHMP8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/amoq//b2Av///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A//// + AP///wDp//8AKgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP//ACr//wDp//8A////AP///wD///8A//// + AP///wD///8A////AP///wD///8A////AP///wD///8A/5WVIv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/8PD + Ff///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD//PwAqwAA + AAQAAAACAAAAAQAAAAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA//8Aev// + AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP/i4gn/R0cw/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv9qair/9vYC////AP///wD///8A////AP///wD///8A////AP///wD///8A//// + AP///wD///8A////AOn//wAqAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP//ACr//wDp//8A////AP///wD///8A//// + AP///wD///8A////AP///wD///8A////AP///wD///8A/5WVIv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/8PD + Ff///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD/7e0AgwAA + AAwAAAAIAAAABQAAAAMAAAABAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAD//wB6//8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A/+Li + Cf9HRzD/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/2pqKv/29gL///8A////AP///wD///8A////AP///wD///8A//// + AP///wD///8A////AP///wD///8A6f//ACoAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP//ACr//wDp//8A////AP///wD///8A//// + AP///wD///8A////AP///wD///8A////AP///wD/9vYC/4eHJf8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/8PD + Ff///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD/3d0AjQAA + ABwAAAAVAAAADgAAAAoAAAAGAAAAAwAAAAEAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAP//AHr//wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A//// + AP///wD/4uIJ/0dHMP8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/amoq//b2Av///wD///8A////AP///wD///8A//// + AP///wD///8A////AP///wD///8A////AP///wDp//8AKgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP//ACr//wDp//8A////AP///wD///8A//// + AP///wD///8A////AP///wD///8A////AP///wD/9vYC/2pqKv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/8PD + Ff///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD/yckAmwAA + ADUAAAArAAAAIAAAABcAAAAQAAAACgAAAAYAAAADAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAA//8Aev//AP///wD///8A////AP///wD///8A////AP///wD///8A//// + AP///wD///8A////AP/i4gn/R0cw/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv9qair/9vYC////AP///wD///8A//// + AP///wD///8A////AP///wD///8A////AP///wD///8A////AOn//wAqAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP//ACr//wDp//8A////AP///wD///8A//// + AP///wD///8A////AP///wD///8A////AP///wD/9vYC/2pqKv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/8PD + Ff///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD/tbUArAAA + AFUAAABJAAAAOwAAAC4AAAAiAAAAGAAAABAAAAAKAAAABQAAAAIAAAABAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD//wB6//8A////AP///wD///8A////AP///wD///8A//// + AP///wD///8A////AP///wD///8A/+LiCf9HRzD/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/2pqKv/29gL///8A//// + AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A6f//ACoAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP//ACr//wDp//8A////AP///wD///8A//// + AP///wD///8A////AP///wD///8A////AP///wD/9vYC/2pqKv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/8PD + Ff///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD/paUAvQAA + AHYAAABqAAAAXQAAAE8AAAA/AAAAMAAAACIAAAAXAAAADgAAAAgAAAAEAAAAAQAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP//AEr//wD///8A////AP///wD///8A//// + AP///wD///8A////AP///wD///8A////AP///wD/4uIJ/0dHMP8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/amoq//b2 + Av///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wDp//8AKgAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP//ACr//wDp//8A////AP///wD///8A//// + AP///wD///8A////AP///wD///8A////AP///wD/9vYC/2pqKv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/8PD + Ff///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD/mpoAygAA + AJQAAACLAAAAfwAAAHEAAABhAAAAUAAAAD8AAAAuAAAAIAAAABUAAAAMAAAABgAAAAMAAAABAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA//8ASv//AP///wD///8A//// + AP///wD///8A////AP///wD///8A////AP///wD///8A////AP/i4gn/R0cw/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv9qair/9vYC////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A//// + AOn//wAqAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP//ACr//wDp//8A////AP///wD///8A//// + AP///wD///8A////AP///wD///8A////AP///wD/9vYC/2pqKv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/8PD + Ff///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD/k5MA1AAA + AKkAAACjAAAAnAAAAJEAAACDAAAAcwAAAGEAAABPAAAAPAAAACsAAAAcAAAAEQAAAAkAAAAEAAAAAQAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD//wBK//8A//// + AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A/+LiCf9HRzD/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/2pqKv/29gL///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A//// + AP///wD///8A6f//ACoAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP//ACr//wDp//8A////AP///wD///8A//// + AP///wD///8A////AP///wD///8A////AP///wD/9vYC/2pqKv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/8PD + Ff///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD/j48A2gAA + ALYAAAC0AAAArwAAAKkAAACgAAAAkwAAAIMAAABxAAAAXQAAAEkAAAA1AAAAJAAAABcAAAANAAAABgAA + AAIAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP// + AEr//wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD/4uIJ/0dH + MP8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/amoq//b2Av///wD///8A////AP///wD///8A////AP///wD///8A//// + AP///wD///8A////AP///wDp//8AKgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP//ACr//wDp//8A////AP///wD///8A//// + AP///wD///8A////AP///wD///8A////AP///wD/9vYC/2pqKv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/8PD + Ff///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD/jY0A3QAA + AL0AAAC8AAAAuwAAALgAAACzAAAAqwAAAKAAAACRAAAAfwAAAGsAAABVAAAAQAAAACwAAAAcAAAAEQAA + AAgAAAADAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAA//8ASv//AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A//// + AP/i4gn/R0cw/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv9qair/9vYC////AP///wD///8A////AP///wD///8A//// + AP///wD///8A////AP///wD///8A////AOn//wAqAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP//ACr//wDp//8A////AP///wD///8A//// + AP///wD///8A////AP///wD///8A////AP///wD/9vYC/2pqKv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/8PD + Ff///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD/jIwA3gAA + AL8AAAC/AAAAvgAAAL4AAAC8AAAAuQAAALMAAACpAAAAnAAAAIsAAAB3AAAAYQAAAEkAAAA0AAAAIgAA + ABUAAAALAAAABAAAAAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAD//wBK//8A////AP///wD///8A////AP///wD///8A////AP///wD///8A//// + AP///wD///8A/+LiCf9HRzD/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/2pqKv/29gL///8A////AP///wD///8A//// + AP///wD///8A////AP///wD///8A////AP///wD///8A6f//ACoAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP//ACr//wDp//8A////AP///wD///8A//// + AP///wD///8A////AP///wD///8A////AP///wD/9vYC/2pqKv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/8PD + Ff///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD/jIwA3gAA + AL8AAAC/AAAAvwAAAL8AAAC/AAAAvgAAALwAAAC4AAAArwAAAKMAAACUAAAAgAAAAGoAAABSAAAAOwAA + ACgAAAAZAAAADQAAAAYAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAP//AEr//wD///8A////AP///wD///8A////AP///wD///8A//// + AP///wD///8A////AP///wD/4uIJ/0dHMP8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/amoq//b2Av///wD///8A//// + AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wDp//8AKgAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP//ACr//wDp//8A////AP///wD///8A//// + AP///wD///8A////AP///wD///8A////AP///wD/9vYC/2pqKv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/8PD + Ff///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD/jIwA3gAA + AL8AAAC/AAAAvwAAAL8AAAC/AAAAvwAAAL8AAAC+AAAAuwAAALQAAACpAAAAmgAAAIgAAAByAAAAWQAA + AEEAAAAtAAAAHAAAABAAAAAHAAAAAgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA//8ASv//AP///wD///8A////AP///wD///8A//// + AP///wD///8A////AP///wD///8A////AP/i4gn/R0cw/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv9qair/9vYC//// + AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AOn//wAqAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP//AAj//wDZ//8A////AP///wD///8A//// + AP///wD///8A////AP///wD///8A////AP///wD/9vYC/2pqKv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/8PD + Ff///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD/jIwA3gAA + AL8AAAC/AAAAvwAAAL8AAAC/AAAAvwAAAL8AAAC/AAAAvgAAALwAAAC2AAAArAAAAJ8AAACNAAAAdwAA + AF8AAABGAAAAMQAAAB8AAAARAAAACAAAAAIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD//wBK//8A////AP///wD///8A//// + AP///wD///8A////AP///wD///8A////AP///wD///8A/+LiCf9HRzD/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/2pq + Kv/29gL///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A6f// + ACoAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD//wCf//8A////AP///wD///8A//// + AP///wD///8A////AP///wD///8A////AP///wD/9vYC/2pqKv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/8PD + Ff///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD/jIwA3gAA + AL8AAAC/AAAAvwAAAL8AAAC/AAAAvwAAAL8AAAC/AAAAvwAAAL8AAAC+AAAAuAAAAK8AAAChAAAAkAAA + AHsAAABiAAAASQAAADMAAAAhAAAAEwAAAAkAAAACAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP//AEr//wD///8A//// + AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD/4uIJ/0dHMP8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/amoq//b2Av///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A//// + AP///wDZ//8ACAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD//wBk//8A////AP///wD///8A//// + AP///wD///8A////AP///wD///8A////AP///wD/9vYC/2pqKv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/8PD + Ff///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD/zexU/Kfo + rP+e3KP6ir+O8WGHZN8aJBvHAAAAvwAAAL8AAAC/AAAAvwAAAL8AAAC/AAAAvgAAALgAAACvAAAAogAA + AJEAAAB8AAAAYwAAAEkAAAA0AAAAIgAAABMAAAAJAAAAAgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA//8ASv// + AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP/i4gn/R0cw/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv9qair/9vYC////AP///wD///8A////AP///wD///8A////AP///wD///8A//// + AP///wD///8A////AJ8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD//wAV//8A5///AP///wD///8A//// + AP///wD///8A////AP///wD///8A////AP///wD/9vYC/2pqKv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/8PD + Ff///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD/0fNa/6fo + rP+n6Kz/p+is/6forP+n6Kz/peWq/muVb+QJDAnCAAAAvwAAAL8AAAC/AAAAvwAAAL4AAAC4AAAArwAA + AKEAAACQAAAAewAAAGIAAABJAAAAMwAAACEAAAATAAAACQAAAAIAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAD//wBK//8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A/+Li + Cf9HRzD/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/2pqKv/29gL///8A////AP///wD///8A////AP///wD///8A//// + AP///wD///8A////AP///wD///8AZAAAAAAAAAAAAAAAAAAAAAAAAAAA//8AlP//AP///wD///8A//// + AP///wD///8A////AP///wD///8A////AP///wD/9vYC/2pqKv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/8PD + Ff///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD/0fNa/6fo + rP+n6Kz/p+is/6forP+n6Kz/p+is/6forP+n6Kz/j8eU9BQcFcUAAAC/AAAAvwAAAL4AAAC8AAAAtgAA + AKwAAACfAAAAjQAAAHcAAABfAAAARgAAADEAAAAfAAAAEgAAAAgAAAACAAAAAAAAAAAAAAAAAAAAAQAA + AAEAAAABAAAAAQAAAAIAAAACAAAAAwAAAAMAAAADAAAABAAAAAQAAAADAAAAAwAAAAMAAAACAAAAAgAA + AAEAAAABAAAAAQAAAAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAP//AEr//wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A//// + AP///wD/4uIJ/0dHMP8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/amoq//b2Av///wD///8A////AP///wD///8A//// + AP///wD///8A////AP///wD///8A////ANf//wAFAAAAAAAAAAAAAAAA//8AH///AP///wD///8A//// + AP///wD///8A////AP///wD///8A////AP///wD/9vYC/2pqKv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/8PD + Ff///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD/0fNa/6fo + rP+n6Kz/p+is/6forP+n6Kz/p+is/6forP+n6Kz/p+is/6forP+Px5TzCQwJwgAAAL8AAAC+AAAAuwAA + ALQAAACpAAAAmgAAAIgAAAByAAAAWgAAAEEAAAAtAAAAHAAAABAAAAAHAAAAAwAAAAEAAAABAAAAAgAA + AAQAAAAEAAAABQAAAAcAAAAHAAAACQAAAAoAAAAKAAAACgAAAAoAAAAKAAAACgAAAAoAAAAKAAAACQAA + AAcAAAAHAAAABQAAAAQAAAAEAAAAAgAAAAEAAAABAAAAAQAAAAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAA//8ASv//AP///wD///8A////AP///wD///8A////AP///wD///8A//// + AP///wD///8A////AP/i4gn/R0cw/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv9qair/9vYC////AP///wD///8A//// + AP///wD///8A////AP///wD///8A////AP///wD///8AhAAAAAAAAAAAAAAAAP//AG///wD///8A//// + AP///wD///8A////AP///wD///8A////AP///wD/9vYC/2pqKv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/8PD + Ff///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD/0fNa/6fo + rP+n6Kz/p+is/6forP+n6Kz/p+is/6forP+n6Kz/p+is/6forP+n6Kz/p+is/26ZceUAAAC+AAAAvAAA + ALgAAACvAAAAowAAAJQAAACBAAAAagAAAFIAAAA7AAAAKAAAABkAAAAPAAAACAAAAAQAAAAEAAAABgAA + AAgAAAAKAAAADAAAAA0AAAAQAAAAEQAAABMAAAAUAAAAFQAAABYAAAAWAAAAFgAAABYAAAAVAAAAFAAA + ABMAAAARAAAAEAAAAA0AAAAMAAAACgAAAAgAAAAGAAAABAAAAAMAAAACAAAAAQAAAAEAAAABAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD//wBK//8A////AP///wD///8A////AP///wD///8A//// + AP///wD///8A////AP///wD///8A/+LiCf9HRzD/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/2pqKv/29gL///8A//// + AP///wD///8A////AP///wD///8A////AP///wD///8A////AO4AAAAAAAAAAAAAAAD//wDO//8A//// + AP///wD///8A////AP///wD///8A////AP///wD///8A/3l5KP8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/8PD + Ff///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD/0fNa/6fo + rP+n6Kz/p+is/6forP+n6Kz/p+is/6forP+n6Kz/p+is/6forP+n6Kz/p+is/6forP+m5qv+HysgxQAA + ALkAAACzAAAAqQAAAJwAAACLAAAAdwAAAGEAAABKAAAANQAAACUAAAAYAAAAEAAAAAsAAAAKAAAADAAA + AA4AAAARAAAAFAAAABcAAAAaAAAAHAAAAB8AAAAhAAAAIgAAACQAAAAlAAAAJQAAACUAAAAlAAAAJAAA + ACIAAAAhAAAAHwAAABwAAAAaAAAAFwAAABQAAAARAAAADgAAAAsAAAAJAAAABwAAAAQAAAADAAAAAgAA + AAEAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP//AEr//wD///8A////AP///wD///8A//// + AP///wD///8A////AP///wD///8A////AP///wD/4uIJ/0dHMP8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/amoq//b2 + Av///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8APwAAAAD//wAP//8A//// + AP///wD///8A////AP///wD///8A////AP///wD///8A/7i4Gf8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/8PD + Ff///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD/0fNa/6fo + rP+n6Kz/p+is/6forP+n6Kz/p+is/6forP+n6Kz/p+is/6forP+n6Kz/p+is/6forP+n6Kz/p+is/2aN + ad0AAACzAAAAqwAAAKAAAACRAAAAfwAAAGwAAABWAAAAQgAAADAAAAAiAAAAGQAAABQAAAASAAAAEwAA + ABYAAAAaAAAAHwAAACIAAAAmAAAAKgAAAC4AAAAwAAAAMwAAADUAAAA3AAAANwAAADgAAAA4AAAANwAA + ADcAAAA1AAAAMwAAADAAAAAtAAAAKgAAACYAAAAiAAAAHwAAABoAAAAWAAAAEwAAAA8AAAALAAAACAAA + AAYAAAAEAAAAAgAAAAEAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA//8ASv//AP///wD///8A//// + AP///wD///8A////AP///wD///8A////AP///wD///8A////AP/i4gn/R0cw/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv95eSj///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AI4AAAAA//8AT/// + AP///wD///8A////AP///wD///8A////AP///wD///8A//b2Av9HRzD/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/8PD + Ff///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD/0fNa/6fo + rP+n6Kz/p+is/6forP+n6Kz/p+is/6forP+n6Kz/p+is/6forP+n6Kz/p+is/6forP+n6Kz/p+is/6fo + rP+NxJHuAAAAqQAAAKAAAACTAAAAhAAAAHMAAABgAAAATQAAADsAAAAuAAAAJAAAAB4AAAAcAAAAHAAA + ACAAAAAlAAAAKwAAADAAAAA0AAAAOgAAAD4AAABCAAAARgAAAEkAAABLAAAATQAAAE8AAABPAAAATwAA + AE8AAABNAAAASwAAAEkAAABGAAAAQgAAAD4AAAA6AAAANAAAAC8AAAArAAAAJQAAAB8AAAAaAAAAFgAA + ABEAAAANAAAACgAAAAcAAAAEAAAAAgAAAAEAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAD//wBK//8A//// + AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A/+LiCf9HRzD/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/8PDFf///wD///8A////AP///wD///8A////AP///wD///8A////AP///wDOAAAAAP// + AIv//wD///8A////AP///wD///8A////AP///wD///8A////AP/DwxX/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/8PD + Ff///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD/0vNX+afo + rP+n6Kz/p+is/6forP+n6Kz/p+is/6forP+n6Kz/p+is/6forP+n6Kz/p+is/6forP+n6Kz/p+is/6fo + rP+n6Kz/ouGn+wAAAJwAAACRAAAAhQAAAHYAAABlAAAAVQAAAEUAAAA4AAAALgAAACgAAAAnAAAAKAAA + ACsAAAAxAAAANwAAAD4AAABFAAAASwAAAFEAAABWAAAAWwAAAF8AAABiAAAAZQAAAGcAAABpAAAAagAA + AGoAAABpAAAAZwAAAGUAAABiAAAAXgAAAFsAAABVAAAAUAAAAEsAAABEAAAAPgAAADcAAAAxAAAAKgAA + ACQAAAAdAAAAFwAAABIAAAANAAAACgAAAAYAAAAEAAAAAgAAAAEAAAABAAAAAAAAAAAAAAAAAAAAAP// + AEr//wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD/4uIJ/0dH + MP8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv9aWi3///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A//// + AAv//wDH//8A////AP///wD///8A////AP///wD///8A////AP///wD/eXko/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/8PD + Ff///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD/+fkAfafo + rP+n6Kz/p+is/6forP+n6Kz/p+is/6forP+n6Kz/p+is/6forP+n6Kz/p+is/6forP+n6Kz/p+is/6fo + rP+n6Kz/p+is/6forP8AAACLAAAAgQAAAHQAAABnAAAAWQAAAEwAAABAAAAAOAAAADQAAAAyAAAANAAA + ADgAAAA/AAAARgAAAE4AAABVAAAAXQAAAGQAAABqAAAAbwAAAHQAAAB4AAAAewAAAH4AAACAAAAAgQAA + AIIAAACCAAAAgQAAAIAAAAB+AAAAewAAAHgAAAB0AAAAbwAAAGoAAABkAAAAXQAAAFUAAABOAAAARgAA + AD4AAAA2AAAALgAAACUAAAAfAAAAGAAAABIAAAANAAAACQAAAAUAAAADAAAAAQAAAAEAAAAAAAAAAAAA + AAAAAAAA//8ASv//AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A//// + AP/i4gn/R0cw/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/+LiCf///wD///8A////AP///wD///8A////AP///wD///8A//// + AP///wBH//8A////AP///wD///8A////AP///wD///8A////AP///wD///8A/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/8PD + Ff///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD//f0AewAA + AASn6Kzyp+is/6forP+n6Kz/p+is/6forP+n6Kz/p+is/6forP+n6Kz/p+is/6forP+n6Kz/p+is/6fo + rP+n6Kz/p+is/6forP+j46j6AAAAeQAAAG8AAABkAAAAWgAAAE8AAABGAAAAQAAAAD0AAAA9AAAAQAAA + AEYAAABMAAAAVQAAAF4AAABmAAAAbgAAAHYAAAB8AAAAgQAAAIYAAACKAAAAjgAAAJEAAACSAAAAlAAA + AJUAAACWAAAAlgAAAJUAAACUAAAAkgAAAJAAAACOAAAAigAAAIYAAACBAAAAfAAAAHUAAABuAAAAZgAA + AF4AAABVAAAASwAAAEEAAAA4AAAALgAAACUAAAAeAAAAFgAAABAAAAALAAAABwAAAAQAAAACAAAAAQAA + AAEAAAAAAAAAAAAAAAD//wBK//8A////AP///wD///8A////AP///wD///8A////AP///wD///8A//// + AP///wD///8A/+LiCf9aWi3/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv+trRz///8A////AP///wD///8A////AP///wD///8A//// + AP///wD///8AhP//AP///wD///8A////AP///wD///8A////AP///wD///8A/9jYDv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/8PD + Ff///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8AegAA + AAEAAAACpueryqforP+n6Kz/p+is/6forP+n6Kz/p+is/6forP+n6Kz/p+is/6forP+n6Kz/p+is/6fo + rP+n6Kz/p+is/6forP+n6Kz/l9Gb4QAAAGYAAABeAAAAVgAAAE8AAABJAAAARgAAAEUAAABHAAAATAAA + AFIAAABbAAAAYwAAAG0AAAB2AAAAfQAAAIUAAACLAAAAkQAAAJUAAACZAAAAnQAAAJ8AAAChAAAAowAA + AKUAAACmAAAApgAAAKYAAACmAAAApAAAAKMAAAChAAAAnwAAAJ0AAACZAAAAlQAAAJEAAACLAAAAhQAA + AH0AAAB1AAAAbAAAAGIAAABYAAAATQAAAEMAAAA3AAAALQAAACQAAAAbAAAAEwAAAA0AAAAJAAAABQAA + AAMAAAABAAAAAQAAAAAAAAAAAAAAAP//AEr//wD///8A////AP///wD///8A////AP///wD///8A//// + AP///wD///8A////AP///wD/9vYC/2pqKv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/eXko////AP///wD///8A////AP///wD///8A//// + AP///wD///8A////AMD//wD///8A////AP///wD///8A////AP///wD///8A////AP/Y2A7/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/8PD + Ff///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8AegAA + AAAAAAAAAAAAAabmq4Sn6Kz/p+is/6forP+n6Kz/p+is/6forP+n6Kz/p+is/6forP+n6Kz/p+is/6fo + rP+n6Kz/p+is/6forP+n6Kz/p+is/3+xg7AAAABUAAAATwAAAEwAAABKAAAASQAAAEwAAABPAAAAVgAA + AF4AAABnAAAAcAAAAHkAAACCAAAAiwAAAJEAAACYAAAAnQAAAKEAAAClAAAAqQAAAKsAAACtAAAArwAA + ALAAAACxAAAAsgAAALIAAACyAAAAsgAAALEAAACwAAAArwAAAK0AAACrAAAAqAAAAKUAAAChAAAAnQAA + AJcAAACRAAAAiwAAAIIAAAB5AAAAbwAAAGQAAABYAAAATAAAAEAAAAA0AAAAKQAAAB8AAAAXAAAAEAAA + AAoAAAAGAAAABAAAAAEAAAABAAAAAAAAAAAAAAAA//8ASv//AP///wD///8A////AP///wD///8A//// + AP///wD///8A////AP///wD///8A////AP/29gL/amoq/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/3l5KP///wD///8A////AP///wD///8A//// + AP///wD///8A////AP///wDA//8A////AP///wD///8A////AP///wD///8A////AP///wD/2NgO/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/8PD + Ff///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8AegAA + AAAAAAAAAAAAAAAAAAGi4qcjp+is+6forP+n6Kz/p+is/6forP+n6Kz/p+is/6forP+n6Kz/p+is/6fo + rP+n6Kz/p+is/6forP+n6Kz/p+is/6bnq/0/V0FgAAAARgAAAEYAAABHAAAASwAAAE8AAABWAAAAXgAA + AGgAAAByAAAAfAAAAIUAAACOAAAAlgAAAJ0AAACiAAAApwAAAKsAAACvAAAAsQAAALQAAAC1AAAAtwAA + ALgAAAC5AAAAugAAALoAAAC7AAAAuwAAALoAAAC6AAAAuQAAALgAAAC3AAAAtQAAALMAAACxAAAArwAA + AKsAAACnAAAAogAAAJ0AAACWAAAAjgAAAIUAAAB6AAAAbwAAAGIAAABVAAAASAAAADsAAAAuAAAAIwAA + ABkAAAASAAAADAAAAAcAAAAEAAAAAgAAAAEAAAAAAAAAAAAAAAD//wBK//8A////AP///wD///8A//// + AP///wD///8A////AP///wD///8A////AP///wD///8A//b2Av9qair/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv95eSj///8A////AP///wD///8A//// + AP///wD///8A////AP///wD///8AwP//AP///wD///8A////AP///wD///8A////AP///wD///8A/9jY + Dv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/8PD + Ff///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8AegAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAaforJGn6Kz/p+is/6forP+n6Kz/p+is/6forP+n6Kz/p+is/6fo + rP+n6Kz/p+is/6forP+n6Kz/p+is/6forP+RyZWtAAAAOwAAAD8AAABDAAAASgAAAFIAAABbAAAAZQAA + AHAAAAB6AAAAhQAAAI4AAACXAAAAnwAAAKUAAACqAAAArwAAALIAAAC1AAAAuAAAALkAAAC7AAAAvAAA + AL0AAAC+AAAAvgAAAL4AAAC+AAAAvgAAAL4AAAC+AAAAvgAAAL4AAAC+AAAAvQAAALwAAAC7AAAAuQAA + ALgAAAC1AAAAsgAAAK8AAACqAAAApQAAAJ8AAACXAAAAjgAAAIQAAAB4AAAAagAAAF0AAABPAAAAQAAA + ADMAAAAnAAAAHAAAABMAAAANAAAABwAAAAQAAAACAAAAAQAAAAAAAAAAAAAAAP//AEr//wD///8A//// + AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD/9vYC/2pqKv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/eXko////AP///wD///8A//// + AP///wD///8A////AP///wD///8A////AMD//wD///8A////AP///wD///8A////AP///wD///8A//// + AP/Y2A7/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/8PD + Ff///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8AegAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACY05wLp+is0aforP+n6Kz/p+is/6forP+n6Kz/p+is/6fo + rP+n6Kz/p+is/6forP+n6Kz/p+is/6forP+h4KbaHSkeOQAAADcAAAA+AAAARwAAAFIAAABeAAAAagAA + AHYAAACCAAAAjAAAAJYAAACfAAAApgAAAKwAAACxAAAAtQAAALgAAAC6AAAAuwAAAL0AAAC+AAAAvgAA + AL4AAAC/AAAAvwAAAL8AAAC/AAAAvwAAAL8AAAC/AAAAvwAAAL8AAAC/AAAAvwAAAL8AAAC+AAAAvgAA + AL4AAAC9AAAAuwAAALoAAAC4AAAAtQAAALEAAACsAAAApgAAAJ8AAACWAAAAiwAAAH8AAAByAAAAZAAA + AFUAAABFAAAANwAAACkAAAAeAAAAFAAAAA0AAAAHAAAABAAAAAIAAAABAAAAAAAAAAAAAAAA//8ASv// + AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP/29gL/amoq/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/3l5KP///wD///8A//// + AP///wD///8A////AP///wD///8A////AP///wDA//8A////AP///wD///8A////AP///wD///8A//// + AP///wD/2NgO/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/8PD + Ff///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8AegAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAKforBen6KzRp+is/6forP+n6Kz/p+is/6fo + rP+n6Kz/p+is/6forP+n6Kz/p+is/6forP+i4qfYRWBHOgAAAC4AAAA5AAAARAAAAFEAAABfAAAAbQAA + AHoAAACHAAAAkgAAAJ0AAAClAAAArAAAALEAAAC1AAAAuAAAALsAAAC8AAAAvgAAAL4AAAC+AAAAvwAA + AL8AAAC/AAAAvwAAAL8AAAC/AAAAvwAAAL8AAAC/AAAAvwAAAL8AAAC/AAAAvwAAAL8AAAC/AAAAvwAA + AL8AAAC/AAAAvgAAAL4AAAC+AAAAvAAAALsAAAC4AAAAtQAAALEAAACsAAAApQAAAJwAAACSAAAAhQAA + AHgAAABpAAAAWAAAAEkAAAA5AAAAKwAAAB8AAAAVAAAADQAAAAcAAAAEAAAAAgAAAAEAAAAAAAAAAAAA + AAD//wBK//8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A//b2 + Av9qair/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv95eSj///8A//// + AP///wD///8A////AP///wD///8A////AP///wD///8AwP//AP///wD///8A////AP///wD///8A//// + AP///wD///8A/9jYDv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/8PD + Ff///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8AegAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAp+isCqforJKn6Kz7p+is/6fo + rP+n6Kz/p+is/6forP+n6Kz/p+is/6forPud2qKaKzssJwAAACgAAAAzAAAAQAAAAE8AAABfAAAAbwAA + AH0AAACLAAAAlwAAAKEAAACpAAAAsAAAALUAAAC4AAAAuwAAAL0AAAC+AAAAvgAAAL8AAAC/AAAAvwAA + AL8AAAC/AAAAvwAAAL8AAAC/AAAAvwAAAL8AAAC/AAAAvwAAAL8AAAC/AAAAvwAAAL8AAAC/AAAAvwAA + AL8AAAC/AAAAvwAAAL8AAAC/AAAAvwAAAL4AAAC+AAAAvQAAALsAAAC4AAAAtQAAALAAAACpAAAAoQAA + AJcAAACLAAAAfAAAAG0AAABbAAAASwAAADoAAAAsAAAAHwAAABUAAAANAAAABwAAAAQAAAABAAAAAQAA + AAAAAAAAAAAAAP//AEr//wD5//8A////AP///wD///8A////AP///wD///8A////AP///wD///8A//// + AP///wD/9vYC/2pqKv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/eXko//// + AP///wD///8A////AP///wD///8A////AP///wD///8A////AMD//wD///8A////AP///wD///8A//// + AP///wD///8A////AP/Y2A7/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/8PD + Ff///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8AegAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAp+isIKfo + rIKn6KzHp+is7qforP+n6KzvpueryqDfpYZ5p3wvAAAAFwAAACIAAAAuAAAAPQAAAE4AAABeAAAAcAAA + AH8AAACOAAAAmgAAAKUAAACsAAAAswAAALcAAAC7AAAAvAAAAL4AAAC+AAAAvwAAAL8AAAC/AAAAvwAA + AL8AAAC/AAAAvwAAAL8AAAC/AAAAvwAAAL8AAAC/AAAAvwAAAL8AAAC/AAAAvwAAAL8AAAC/AAAAvwAA + AL8AAAC/AAAAvwAAAL8AAAC/AAAAvwAAAL8AAAC/AAAAvwAAAL4AAAC+AAAAvAAAALsAAAC4AAAAswAA + AKwAAAClAAAAmgAAAI4AAAB/AAAAbwAAAF4AAABMAAAAOwAAACwAAAAfAAAAFAAAAA0AAAAHAAAABAAA + AAEAAAABAAAAAAAAAAAAAAAA//8AKv//AOn//wD///8A////AP///wD///8A////AP///wD///8A//// + AP///wD///8A////AP/29gL/amoq/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/3l5 + KP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wDA//8A////AP///wD///8A//// + AP///wD///8A////AP///wD/2NgO/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/8PD + Ff///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8AegAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAABAAAAAwAAAAYAAAAMAAAAEwAAAB4AAAArAAAAOwAAAEwAAABeAAAAcAAA + AIEAAACQAAAAnQAAAKcAAACvAAAAtQAAALkAAAC7AAAAvgAAAL4AAAC/AAAAvwAAAL8AAAC/AAAAvwAA + AL8AAAC/AAAAvwAAAL8AAAC/AAAAvwAAAL8AAAC/AAAAvwAAAL8AAAC/AAAAvwAAAL8AAAC/AAAAvwAA + AL8AAAC/AAAAvwAAAL8AAAC/AAAAvwAAAL8AAAC/AAAAvwAAAL8AAAC/AAAAvwAAAL4AAAC+AAAAuwAA + ALkAAAC1AAAArwAAAKcAAACdAAAAkAAAAIEAAABwAAAAXgAAAEwAAAA6AAAAKwAAAB4AAAATAAAACwAA + AAYAAAADAAAAAQAAAAAAAAAAAAAAAAAAAAD//wAq//8A6f//AP///wD///8A////AP///wD///8A//// + AP///wD///8A////AP///wD///8A//b2Av9qair/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv95eSj///8A////AP///wD///8A////AP///wD///8A////AP///wD///8AwP//AP///wD///8A//// + AP///wD///8A////AP///wD///8A/9jYDv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/8PD + Ff///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8AegAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAABAAAAAgAAAAUAAAAKAAAAEgAAABwAAAAqAAAAOgAAAEsAAABeAAAAcAAA + AIIAAACRAAAAngAAAKkAAACxAAAAtgAAALoAAAC8AAAAvgAAAL4AAAC/AAAAvwAAAL8FBwXBKzsszE5s + UNhtl3Dkf7GD7I/HlPSd2aH6oN6l+6forP+n6Kz/oeCm/JvYoPmPx5T0gLKE7GqTbeNQb1LYKTgqygMF + A78AAAC/AAAAvwAAAL8AAAC/AAAAvwAAAL8AAAC/AAAAvwAAAL8AAAC/AAAAvwAAAL8AAAC/AAAAvgAA + AL4AAAC8AAAAugAAALYAAACxAAAAqQAAAJ4AAACRAAAAggAAAHAAAABeAAAASwAAADkAAAApAAAAHAAA + ABIAAAAKAAAABQAAAAIAAAABAAAAAAAAAAAAAAAAAAAAAP//ACr//wDp//8A////AP///wD///8A//// + AP///wD///8A////AP///wD///8A////AP///wD/9vYC/2pqKv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/eXko////AP///wD///8A////AP///wD///8A////AP///wD///8A////AMD//wD///8A//// + AP///wD///8A////AP///wD///8A////AP/Y2A7/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/8PD + Ff///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8AegAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAABAAAAAQAAAAQAAAAJAAAAEAAAABoAAAAnAAAANwAAAEkAAABcAAAAbwAA + AIEAAACRAAAAnwAAAKkAAACyAAAAtwAAALsAAAC9AAAAvgAAAL8AAAC/GCEYxlV2WNuAsoTtouGn/Kfo + rP+n6Kz/p+is/6forP+n6Kz/p+is/6forP+n6Kz/p+is/6forP+n6Kz/p+is/6forP+n6Kz/p+is/6fo + rP+i4af8gLKE7FR0VtgXIBjEAAAAvgAAAL4AAAC+AAAAvwAAAL8AAAC/AAAAvwAAAL8AAAC/AAAAvwAA + AL8AAAC/AAAAvgAAAL0AAAC7AAAAtwAAALIAAACpAAAAnwAAAJEAAACBAAAAbwAAAFsAAABJAAAANwAA + ACcAAAAZAAAAEAAAAAkAAAAEAAAAAQAAAAEAAAAAAAAAAAAAAAAAAAAA//8AKv//AOn//wD///8A//// + AP///wD///8A////AP///wD///8A////AP///wD///8A////AP/29gL/amoq/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/3l5KP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wDA//8A//// + AP///wD///8A////AP///wD///8A////AP///wD/2NgO/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/8PD + Ff///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8AegAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAQAAAAMAAAAHAAAADQAAABcAAAAjAAAAMwAAAEYAAABZAAAAbQAA + AH8AAACQAAAAngAAAKkAAACyAAAAuAAAALsAAAC9AAAAvgYIBsFJZUvXh7uL8Kbnq/6n6Kz/p+is/6fo + rP+n6Kz/p+is/6forP+n6Kz/p+is/6forP+n6Kz/p+is/6forP+n6Kz/p+is/6forP+n6Kz/p+is/6fo + rP+n6Kz/p+is/6forP+n6Kz/puer/oe7i+5JZUvUBggGvwAAAL4AAAC+AAAAvgAAAL8AAAC/AAAAvwAA + AL8AAAC/AAAAvwAAAL8AAAC+AAAAvQAAALsAAAC4AAAAsgAAAKkAAACeAAAAkAAAAH8AAABsAAAAWAAA + AEUAAAAzAAAAIwAAABYAAAANAAAABwAAAAMAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAD//wAq//8A6f// + AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A//b2Av9qair/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv95eSj///8A////AP///wD///8A////AP///wD///8A////AP///wD///8AwP// + AP///wD///8A////AP///wD///8A////AP///wD///8A/9jYDv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/8PD + Ff///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8AegAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAQAAAAIAAAAFAAAACwAAABMAAAAfAAAALgAAAEAAAABVAAAAaQAA + AHwAAACOAAAAnQAAAKkAAACyAAAAuAAAALsAAAC9DBAMwl6DYd+c2aH5p+is/6forP+n6Kz/p+is/6fo + rP+n6Kz/p+is/6forP+n6Kz/p+is/6forP+n6Kz/p+is/6forP+n6Kz/p+is/6forP+n6Kz/p+is/6fo + rP+n6Kz/p+is/6forP+n6Kz/p+is/6forP+n6Kz/p+is/53aovldgWDbDRINwAAAAL0AAAC+AAAAvgAA + AL8AAAC/AAAAvwAAAL8AAAC/AAAAvwAAAL4AAAC9AAAAuwAAALgAAACyAAAAqQAAAJ0AAACOAAAAfAAA + AGgAAABUAAAAQAAAAC4AAAAfAAAAEwAAAAsAAAAFAAAAAgAAAAEAAAAAAAAAAAAAAAAAAAAAAAAAAP// + ACr//wDp//8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD/9vYC/2pq + Kv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/eXko////AP///wD///8A////AP///wD///8A////AP///wD///8A//// + AMD//wD///8A////AP///wD///8A////AP///wD///8A////AP/Y2A7/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/8PD + Ff///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8AegAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEAAAAEAAAACQAAABAAAAAbAAAAKQAAADsAAABPAAAAZAAA + AHgAAACLAAAAmgAAAKcAAACxAAAAtwAAALsFBwW/WHpa253aovqn6Kz/p+is/6forP+n6Kz/p+is/6fo + rP+n6Kz/p+is/6forP+n6Kz/p+is/6forP+n6Kz/p+is/6forP+n6Kz/p+is/6forP+n6Kz/p+is/6fo + rP+n6Kz/p+is/6forP+n6Kz/p+is/6forP+n6Kz/p+is/6forP+n6Kz/p+is/5/dpPtYe1vZBQcFvgAA + AL4AAAC+AAAAvwAAAL8AAAC/AAAAvwAAAL8AAAC/AAAAvgAAAL0AAAC7AAAAtwAAALAAAACnAAAAmgAA + AIoAAAB3AAAAYwAAAE4AAAA6AAAAKQAAABsAAAAQAAAACAAAAAQAAAABAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAA//8AKv//AOn//wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A//// + AP/29gL/amoq/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/3l5KP///wD///8A////AP///wD///8A////AP///wD///8A//// + AP///wDA//8A////AP///wD///8A////AP///wD///8A////AP///wD/2NgO/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/8PD + Ff///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8AegAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEAAAACAAAABgAAAA0AAAAWAAAAJAAAADQAAABIAAAAXQAA + AHIAAACFAAAAlwAAAKUAAACvAAAAtgAAALsyRTPNk8yX9aforP+n6Kz/p+is/6forP+n6Kz/p+is/6fo + rP+n6Kz/p+is/6forP+n6Kz/p+is/6forP+n6Kz/p+is/6forP+n6Kz/p+is/6forP+n6Kz/p+is/6fo + rP+n6Kz/p+is/6forP+n6Kz/p+is/6forP+n6Kz/p+is/6forP+n6Kz/p+is/6forP+n6Kz/p+is/5XP + mfQ0STbMAAAAvQAAAL4AAAC+AAAAvwAAAL8AAAC/AAAAvwAAAL8AAAC+AAAAvQAAALsAAAC2AAAArwAA + AKQAAACXAAAAhQAAAHIAAABcAAAARwAAADQAAAAjAAAAFgAAAA0AAAAGAAAAAgAAAAEAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAD//wAq//8A6f//AP///wD///8A////AP///wD///8A////AP///wD///8A//// + AP///wD///8A//b2Av9qair/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv95eSj///8A////AP///wD///8A////AP///wD///8A//// + AP///wD///8AwP//AP///wD///8A////AP///wD///8A////AP///wD///8A/9jYDv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/8PD + Ff///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8AegAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABAAAABAAAAAoAAAASAAAAHgAAAC0AAABAAAAAVQAA + AGsAAAB/AAAAkgAAAKEAAACtAAAAtQcKB7xtmHHkpuer/6forP+n6Kz/p+is/6forP+n6Kz/p+is/6fo + rP+n6Kz/p+is/6forP+n6Kz/p+is/6forP+n6Kz/p+is/6forP+n6Kz/p+is/6forP+n6Kz/p+is/6fo + rP+n6Kz/p+is/6forP+n6Kz/p+is/6forP+n6Kz/p+is/6forP+n6Kz/p+is/6forP+n6Kz/p+is/6fo + rP+n6Kz/puer/2+acuMICwi+AAAAvgAAAL4AAAC/AAAAvwAAAL8AAAC/AAAAvwAAAL4AAAC9AAAAugAA + ALUAAACsAAAAoQAAAJEAAAB/AAAAagAAAFUAAABAAAAALQAAAB0AAAASAAAACgAAAAQAAAABAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAP//ACr//wDp//8A////AP///wD///8A////AP///wD///8A//// + AP///wD///8A////AP///wD/9vYC/2pqKv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/eXko////AP///wD///8A////AP///wD///8A//// + AP///wD///8A////AMD//wD///8A////AP///wD///8A////AP///wD///8A////AP/Y2A7/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8AegAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABAAAAAgAAAAcAAAANAAAAGAAAACUAAAA3AAAATAAA + AGIAAAB4AAAAiwAAAJwAAACpAAAAsyEuIsSRyZXzp+is/6forP+n6Kz/p+is/6forP+n6Kz/p+is/6fo + rP+n6Kz/p+is/6forP+n6Kz/p+is/6forP+n6Kz/p+is/6forP+n6Kz/p+is/6forP+n6Kz/p+is/6fo + rP+n6Kz/p+is/6forP+n6Kz/p+is/6forP+n6Kz/p+is/6forP+n6Kz/p+is/6forP+n6Kz/p+is/6fo + rP+n6Kz/p+is/6forP+n6Kz/kcmV8yEtIsYAAAC+AAAAvgAAAL8AAAC/AAAAvwAAAL8AAAC/AAAAvgAA + ALwAAAC5AAAAsgAAAKkAAACcAAAAiwAAAHcAAABiAAAATAAAADcAAAAlAAAAFwAAAA0AAAAHAAAAAgAA + AAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA//8AKv//AOn//wD///8A////AP///wD///8A//// + AP///wD///8A////AP///wD///8A////AP+trRz/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/3l5KP///wD///8A////AP///wD///8A//// + AP///wD///8A////AP///wDA//8A////AP///wD///8A////AP///wD///8A////AP///wD/2NgO/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8AegAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQAAAAQAAAAKAAAAEgAAAB8AAAAuAAAAQwAA + AFgAAABvAAAAhAAAAJYAAAClAAAAsDpQO8ug3qX7p+is/6forP+n6Kz/p+is/6forP+n6Kz/p+is/6fo + rP+n6Kz/p+is/6forP+n6Kz/p+is/6forP+n6Kz/p+is/6forP+n6Kz/p+is/6forP+n6Kz/p+is/6fo + rP+n6Kz/p+is/6forP+n6Kz/p+is/6forP+n6Kz/p+is/6forP+n6Kz/p+is/6forP+n6Kz/p+is/6fo + rP+n6Kz/p+is/6forP+n6Kz/p+is/6forP+f3aT7OU87zwAAAL4AAAC+AAAAvwAAAL8AAAC/AAAAvwAA + AL8AAAC+AAAAuwAAALcAAACvAAAApQAAAJYAAACDAAAAbgAAAFgAAABCAAAALgAAAB4AAAASAAAACQAA + AAQAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD//wAq//8A6f//AP///wD///8A//// + AP///wD///8A////AP///wD///8A////AP///wD/ra0c/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv95eSj///8A////AP///wD///8A//// + AP///wD///8A////AP///wD///8AwP//AP///wD///8A////AP///wD///8A////AP///wD///8A/9jY + Dv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8AegAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQAAAAIAAAAGAAAADQAAABcAAAAlAAAAOAAA + AE0AAABkAAAAegAAAI4AAACfAAAArEtoTdCm5qv+p+is/6forP+n6Kz/p+is/6forP+n6Kz/p+is/6fo + rP+n6Kz/p+is/6forP+n6Kz/p+is/6forP+n6Kz/p+is/6forP+n6Kz/p+is/6forP+n6Kz/p+is/6fo + rP+n6Kz/p+is/6forP+n6Kz/p+is/6forP+n6Kz/p+is/6forP+n6Kz/p+is/6forP+n6Kz/p+is/6fo + rP+n6Kz/p+is/6forP+n6Kz/p+is/6forP+n6Kz/p+is/6Xlqv5HY0rUAAAAvgAAAL4AAAC/AAAAvwAA + AL8AAAC/AAAAvgAAAL0AAAC7AAAAtQAAAKwAAACeAAAAjgAAAHoAAABkAAAATQAAADcAAAAlAAAAFwAA + AA0AAAAGAAAAAgAAAAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP//ACr//wDp//8A//// + AP///wD///8A////AP///wD///8A////AP///wD///8A/62tHP8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/eXko////AP///wD///8A//// + AP///wD///8A////AP///wD///8A////AMD//wD///8A////AP///wD///8A////AP///wD///8A//// + AP/Y2A7/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8AegAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEAAAADAAAACAAAABEAAAAdAAAALgAA + AEEAAABYAAAAbwAAAIUAAACXAAAAplR0VtGm56v/p+is/6forP+n6Kz/p+is/6forP+n6Kz/p+is/6fo + rP+n6Kz/p+is/6forP+n6Kz/p+is/6forP+n6Kz/p+is/6forP+n6Kz/p+is/6forP+n6Kz/p+is/6fo + rP+n6Kz/p+is/6forP+n6Kz/p+is/6forP+n6Kz/p+is/6forP+n6Kz/p+is/6forP+n6Kz/p+is/6fo + rP+n6Kz/p+is/6forP+n6Kz/p+is/6forP+n6Kz/p+is/6forP+n6Kz/puer/09tUdcAAAC+AAAAvwAA + AL8AAAC/AAAAvwAAAL8AAAC+AAAAvAAAALgAAACxAAAApgAAAJcAAACEAAAAbwAAAFgAAABBAAAALQAA + AB0AAAARAAAACAAAAAMAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA//8AKv// + AOn//wD///8A////AP///wD///8A////AP///wD///8A////AP+trRz/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/3l5KP///wD///8A//// + AP///wD///8A////AP///wD///8A////AP///wDA//8A////AP///wD///8A////AP///wD///8A//// + AP///wD/2NgO/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A//// + AAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABAAAABAAAAAsAAAAWAAAAJAAA + ADYAAABLAAAAYgAAAHkAAACOAAAAn01rUMum56v/p+is/6forP+n6Kz/p+is/6forP+n6Kz/p+is/6fo + rP+n6Kz/p+is/6forP+n6Kz/p+is/6forP+n6Kz/p+is/6forP+n6Kz/p+is/6forP+n6Kz/p+is/6fo + rP+n6Kz/p+is/6forP+n6Kz/p+is/6forP+n6Kz/p+is/6forP+n6Kz/p+is/6forP+n6Kz/p+is/6fo + rP+n6Kz/p+is/6forP+n6Kz/p+is/6forP+n6Kz/p+is/6forP+n6Kz/p+is/6forP+m56v+R2NK1QAA + AL4AAAC/AAAAvwAAAL8AAAC/AAAAvwAAAL4AAAC7AAAAtQAAAKwAAACfAAAAjgAAAHkAAABiAAAASwAA + ADUAAAAjAAAAFgAAAAsAAAAEAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAD//wCA//8A////AP///wD///8A////AP///wD///8A////AP///wD/ra0c/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv95eSj///8A//// + AP///wD///8A////AP///wD///8A////AP///wD///8AwP//AP///wD///8A////AP///wD///8A//// + AP///wD///8A/9jYDv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy////AP///wD///8A////AP///wD///8A////AP///wD///8A//// + AP///wABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABAAAAAgAAAAcAAAAPAAAAGgAA + ACoAAAA9AAAAVQAAAGwAAACCAAAAlkBYQb+m5qv+p+is/6forP+n6Kz/p+is/6forP+n6Kz/p+is/6fo + rP+n6Kz/p+is/6forP+n6Kz/p+is/6forP+n6Kz/p+is/6forP+n6Kz/p+is/6forP+n6Kz/p+is/5nU + nfeGuorte6t/5nShd913pXrXgrSG15DIlNyg3qXvp+is/6forP+n6Kz/p+is/6forP+n6Kz/p+is/6fo + rP+n6Kz/p+is/6forP+n6Kz/p+is/6forP+n6Kz/p+is/6forP+n6Kz/p+is/6forP+n6Kz/p+is/6Xl + qv41SjfPAAAAvgAAAL8AAAC/AAAAvwAAAL8AAAC+AAAAvQAAALgAAACxAAAApQAAAJUAAACCAAAAbAAA + AFQAAAA9AAAAKgAAABoAAAAPAAAABwAAAAIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAA//8AgP//AP///wD///8A////AP///wD///8A////AP///wD///8A/62tHP8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/eXko//// + AP///wD///8A////AP///wD///8A////AP///wD///8A////AMD//wD///8A////AP///wD///8A//// + AP///wD///8A////AP/Y2A7/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv///wD///8A////AP///wD///8A////AP///wD///8A//// + AP///wD///8AAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQAAAAMAAAAJAAAAEwAA + AB8AAAAxAAAARgAAAF4AAAB1AAAAiyc2KKyg36X6p+is/6forP+n6Kz/p+is/6forP+n6Kz/p+is/6fo + rP+n6Kz/p+is/6forP+n6Kz/p+is/6forP+n6Kz/p+is/6forP+n6Kz/p+is/6forP+n6Kz/p+is/6fo + rP9mjWndAAAAswAAAKsAAACgAAAAkQAAAH8AAABrAAAAVSk4Kk5zn3ZmmdWenKbmq9+n6Kz/p+is/6fo + rP+n6Kz/p+is/6forP+n6Kz/p+is/6forP+n6Kz/p+is/6forP+n6Kz/p+is/6forP+n6Kz/p+is/6fo + rP+n6Kz/ntyj+x4qH8cAAAC/AAAAvwAAAL8AAAC/AAAAvwAAAL4AAAC7AAAAtQAAAKoAAACcAAAAiwAA + AHUAAABdAAAARgAAADEAAAAfAAAAEgAAAAkAAAADAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAP//AID//wD///8A////AP///wD///8A////AP///wD///8A////AP+trRz/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/3l5 + KP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wDA//8A////AP///wD///8A//// + AP///wD///8A////AP///wD/2NgO/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL///8A////AP///wD///8A////AP///wD///8A//// + AP///wD///8A////AAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEAAAAEAAAACwAA + ABYAAAAlAAAANwAAAE4AAABmAAAAfQwRDZaVz5nwp+is/6forP+n6Kz/p+is/6forP+n6Kz/p+is/6fo + rP+n6Kz/p+is/6forP+n6Kz/p+is/6forP+n6Kz/p+is/6forP+n6Kz/p+is/6forP+n6Kz/p+is/6fo + rP+n6Kz/jsWS7wAAAKkAAACgAAAAkwAAAIMAAABxAAAAXgAAAEkAAAA1AAAAJAAAABcAAAANmdSdOqbm + q6Cn6Kz5p+is/6forP+n6Kz/p+is/6forP+n6Kz/p+is/6forP+n6Kz/p+is/6forP+n6Kz/p+is/6fo + rP+n6Kz/p+is/6forP+OxZLyBggGwAAAAL8AAAC/AAAAvwAAAL8AAAC+AAAAvAAAALgAAACvAAAAogAA + AJEAAAB9AAAAZgAAAE4AAAA3AAAAJQAAABYAAAALAAAABAAAAAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAD//wCA//8A////AP///wD///8A////AP///wD///8A////AP///wD/ra0c/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv95eSj///8A////AP///wD///8A////AP///wD///8A////AP///wD///8AwP//AP///wD///8A//// + AP///wD///8A////AP///wD///8A/9jYDv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy////AP///wD///8A////AP///wD///8A//// + AP///wD///8A////AP///wABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABAAAABgAA + AA4AAAAaAAAAKgAAAD4AAABVAAAAbgAAAIV3pnvVp+is/6forP+n6Kz/p+is/6forP+n6Kz/p+is/6fo + rP+n6Kz/p+is/6forP+n6Kz/p+is/6forP+n6Kz/p+is/6forP+n6Kz/p+is/6forP+n6Kz/p+is/6fo + rP+n6Kz/p+is/6PjqPsAAACcAAAAkQAAAIMAAABzAAAAYQAAAE8AAAA8AAAAKwAAABwAAAARAAAACgAA + AAQAAAABouGnIKforJ+n6Kz9p+is/6forP+n6Kz/p+is/6forP+n6Kz/p+is/6forP+n6Kz/p+is/6fo + rP+n6Kz/p+is/6forP+n6Kz/p+is/2uUbuMAAAC/AAAAvwAAAL8AAAC/AAAAvwAAAL4AAAC6AAAAsgAA + AKcAAACXAAAAhQAAAG0AAABVAAAAPgAAACoAAAAaAAAADgAAAAYAAAABAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAA//8AgP//AP///wD///8A////AP///wD///8A////AP///wD///8A/62t + HP8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/eXko////AP///wD///8A////AP///wD///8A////AP///wD///8A////AMD//wD///8A//// + AP///wD///8A////AP///wD///8A////AP/Y2A7/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv///wD///8A////AP///wD///8A//// + AP///wD///8A////AP///wD///8AAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAgAA + AAgAAAARAAAAHwAAAC8AAABEAAAAXQAAAHVAWUKppuer/6forP+n6Kz/p+is/6forP+n6Kz/p+is/6fo + rP+n6Kz/p+is/6forP+n6Kz/p+is/6forP+n6Kz/p+is/6forP+n6Kz/p+is/6forP+n6Kz/p+is/6fo + rP+n6Kz/p+is/6forP+n6Kz/AQIBiwAAAH8AAABxAAAAYQAAAFEAAABAAAAALwAAACEAAAAWAAAADQAA + AAcAAAAEAAAAAQAAAAEAAAABpOSpPaforNqn6Kz/p+is/6forP+n6Kz/p+is/6forP+n6Kz/p+is/6fo + rP+n6Kz/p+is/6forP+n6Kz/p+is/6forP+m56v+L0IxzgAAAL8AAAC/AAAAvwAAAL8AAAC+AAAAuwAA + ALUAAACrAAAAnQAAAIsAAAB1AAAAXQAAAEQAAAAvAAAAHgAAABEAAAAIAAAAAgAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAP//AID//wD///8A////AP///wD///8A////AP///wD///8A//// + AP+trRz/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/3l5KP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wDA//8A//// + AP///wD///8A////AP///wD///8A////AP///wD/2NgO/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL///8A////AP///wD///8A//// + AP///wD///8A////AP///wD///8A////AAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQAA + AAQAAAAKAAAAFAAAACIAAAA0AAAASwAAAGQJDQmAmNOc76forP+n6Kz/p+is/6forP+n6Kz/p+is/6fo + rP+n6Kz/p+is/6forP+n6Kz/p+is/6forP+n6Kz/p+is/6forP+n6Kz/p+is/6forP+n6Kz/p+is/6fo + rP+n6Kz/p+is/6forP+n6Kz/pOOp+wAAAHYAAABrAAAAXQAAAE8AAABAAAAAMQAAACUAAAAZAAAAEgAA + AAwAAAAIAAAABgAAAAQAAAAEAAAAAwAAAAKc2aEPpuersKforP+n6Kz/p+is/6forP+n6Kz/p+is/6fo + rP+n6Kz/p+is/6forP+n6Kz/p+is/6forP+n6Kz/p+is/5HJlfQFBgXAAAAAvwAAAL8AAAC/AAAAvgAA + AL0AAAC4AAAArwAAAKEAAACQAAAAfAAAAGMAAABKAAAANAAAACIAAAAUAAAACgAAAAQAAAABAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD//wCA//8A////AP///wD///8A////AP///wD///8A//// + AP///wD/ra0c/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv95eSj///8A////AP///wD///8A////AP///wD///8A////AP///wD///8AwP// + AP///wD///8A////AP///wD///8A////AP///wD///8A/9jYDv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy////AP///wD///8A//// + AP///wD///8A////AP///wD///8A////AP///wABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAEAAAAEAAAADAAAABcAAAAmAAAAOgAAAFAAAABqaZJtu6forP+n6Kz/p+is/6forP+n6Kz/p+is/6fo + rP+n6Kz/p+is/6forP+n6Kz/p+is/6forP+n6Kz/p+is/6forP+n6Kz/p+is/6forP+n6Kz/p+is/6fo + rP+n6Kz/p+is/6forP+n6Kz/p+is/5fRm+EAAABhAAAAVQAAAEkAAAA9AAAAMQAAACYAAAAdAAAAFgAA + ABIAAAAPAAAADQAAAAsAAAAKAAAACQAAAAcAAAAFAAAABDhNOQOm5quAp+is/6forP+n6Kz/p+is/6fo + rP+n6Kz/p+is/6forP+n6Kz/p+is/6forP+n6Kz/p+is/6forP+n6Kz/VHRW2gAAAL8AAAC/AAAAvwAA + AL8AAAC+AAAAuQAAALEAAAClAAAAlQAAAIEAAABqAAAAUAAAADkAAAAmAAAAFwAAAAwAAAAEAAAAAQAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA//8AgP//AP///wD///8A////AP///wD///8A//// + AP///wD///8A/62tHP8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/eXko////AP///wD///8A////AP///wD///8A////AP///wD///8A//// + AMD//wD///8A////AP///wD///8A////AP///wD///8A////AP/Y2A7/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv///wD///8A//// + AP///wD///8A////AP///wD///8A////AP///wD///8AAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAABAAAABQAAAA0AAAAaAAAAKgAAAD4AAABVFh8XeKHgpven6Kz/p+is/6forP+n6Kz/p+is/6fo + rP+n6Kz/p+is/6forP+n6Kz/p+is/6forP+n6Kz/p+is/6forP+n6Kz/p+is/6forP+n6Kz/p+is/6fo + rP+n6Kz/p+is/6forP+n6Kz/p+is/6forP+CtIatAAAASQAAAEAAAAA2AAAALQAAACUAAAAfAAAAGgAA + ABcAAAAWAAAAFgAAABYAAAAVAAAAEwAAABEAAAAOAAAACgAAAAcAAAAEAAAAA6bmq3un6Kz/p+is/6fo + rP+n6Kz/p+is/6forP+n6Kz/p+is/6forP+n6Kz/p+is/6forP+n6Kz/p+is/5zZofkJDQnCAAAAvwAA + AL8AAAC/AAAAvgAAALsAAACzAAAAqAAAAJkAAACFAAAAbwAAAFUAAAA9AAAAKgAAABkAAAANAAAABQAA + AAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP//AID//wD///8A////AP///wD///8A//// + AP///wD///8A////AP+trRz/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/3l5KP///wD///8A////AP///wD///8A////AP///wD///8A//// + AP///wDA//8A////AP///wD///8A////AP///wD///8A////AP///wD/2NgO/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL///8A//// + AP///wD///8A////AP///wD///8A////AP///wD///8A////AAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAQAAAAcAAAAQAAAAHAAAAC0AAABCAAAAW2+bc7en6Kz/p+is/6forP+n6Kz/p+is/6fo + rP+n6Kz/p+is/6forP+n6Kz/p+is/6forP+n6Kz/p+is/6forP+n6Kz/p+is/6forP+n6Kz/p+is/6fo + rP+n6Kz/p+is/6forP+n6Kz/p+is/6forP+m56v9RWBHVwAAADUAAAAuAAAAKAAAACIAAAAfAAAAHAAA + ABwAAAAeAAAAIAAAACIAAAAjAAAAIgAAACAAAAAcAAAAFwAAABIAAAANAAAACAAAAAQAAAADpuargqfo + rP+n6Kz/p+is/6forP+n6Kz/p+is/6forP+n6Kz/p+is/6forP+n6Kz/p+is/6forP+n6Kz/XH9e3QAA + AL8AAAC/AAAAvwAAAL4AAAC8AAAAtQAAAKsAAACcAAAAigAAAHMAAABaAAAAQgAAAC0AAAAcAAAAEAAA + AAcAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD//wCA//8A////AP///wD///8A//// + AP///wD///8A////AP///wD/ra0c/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv95eSj///8A////AP///wD///8A////AP///wD///8A//// + AP///wD///8AwP//AP///wD///8A////AP///wD///8A////AP///wD///8A/9jYDv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy//// + AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wABAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAIAAAAHAAAAEQAAAB8AAAAwAAAARgwQDGKh4Kb0p+is/6forP+n6Kz/p+is/6fo + rP+n6Kz/p+is/6forP+n6Kz/p+is/6forP+n6Kz/p+is/6forP+n6Kz/p+is/6forP+n6Kz/p+is/6fo + rP+n6Kz/p+is/6forP+n6Kz/p+is/6forP+n6Kz/lM6YqQAAACkAAAAlAAAAIQAAAB4AAAAdAAAAHQAA + ACAAAAAkAAAAKQAAAC4AAAAyAAAANAAAADQAAAAxAAAAKwAAACQAAAAcAAAAFAAAAA0AAAAIAAAABCo6 + KwSm56u0p+is/6forP+n6Kz/p+is/6forP+n6Kz/p+is/6forP+n6Kz/p+is/6forP+n6Kz/p+is/5vX + n/kFBgXAAAAAvwAAAL8AAAC/AAAAvQAAALcAAACsAAAAnwAAAI0AAAB3AAAAXgAAAEUAAAAwAAAAHwAA + ABEAAAAHAAAAAgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA//8AgP//AP///wD///8A//// + AP///wD///8A////AP///wD///8A/62tHP8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/eXko////AP///wD///8A////AP///wD///8A//// + AP///wD///8A////AMD//wD///8A////AP///wD///8A////AP///wD///8A////AP/Y2A7/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8AAQAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAACAAAACQAAABMAAAAhAAAAMwAAAEljiWaap+is/6forP+n6Kz/p+is/6fo + rP+n6Kz/p+is/6forP+n6Kz/p+is/6forP+n6Kz/p+is/6PjqP2n6Kz/p+is/6forP+n6Kz/p+is/6fo + rP+n6Kz/p+is/6forP+n6Kz/p+is/6forP+n6Kz/o+Oo1zJGNCgAAAAbAAAAGQAAABkAAAAaAAAAHQAA + ACIAAAAoAAAAMQAAADoAAABBAAAARwAAAEoAAABJAAAARQAAAD0AAAA0AAAAKAAAAB4AAAAUAAAADQAA + AAcAAAAEi8KQEqbnq96n6Kz/p+is/6forP+n6Kz/p+is/6forP+n6Kz/p+is/6forP+n6Kz/p+is/6fo + rP+n6Kz/Q15F1QAAAL8AAAC/AAAAvwAAAL4AAAC4AAAArwAAAKEAAACQAAAAewAAAGIAAABIAAAAMgAA + ACAAAAATAAAACAAAAAIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP//AID//wD///8A//// + AP///wD///8A////AP///wD///8A////AP+trRz/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/3l5KP///wD///8A////AP///wD///8A//// + AP///wD///8A////AP///wDA//8A////AP///wD///8A////AP///wD///8A////AP///wD/2NgO/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AAEAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAwAAAAoAAAAUAAAAIgAAADUAAABLlM6Y2aforP+n6Kz/p+is/6fo + rP+n6Kz/p+is/6forP+n6Kz/p+is/6forP+n6Kz/p+is/6forP9BW0PLj8aT7aforP+n6Kz/p+is/6fo + rP+n6Kz/p+is/6forP+n6Kz/p+is/6forP+n6Kz/pOSp1WaNaSkAAAASAAAAEgAAABMAAAAWAAAAGwAA + ACIAAAArAAAANwAAAEIAAABNAAAAVwAAAF4AAABhAAAAYQAAAFsAAABSAAAARgAAADgAAAAqAAAAHQAA + ABMAAAALAAAABgAAAASd2qJFp+is/qforP+n6Kz/p+is/6forP+n6Kz/p+is/6forP+n6Kz/p+is/6fo + rP+n6Kz/p+is/4S3iO4AAAC/AAAAvwAAAL8AAAC+AAAAuQAAALAAAACjAAAAkgAAAH0AAABlAAAASwAA + ADQAAAAiAAAAEwAAAAkAAAADAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD//wCA//8A//// + AP///wD///8A////AP///wD///8A////AP///wD/ra0c/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv95eSj///8A////AP///wD///8A//// + AP///wD///8A////AP///wD///8AwP//AP///wD///8A////AP///wD///8A////AP///wD///8A/9jY + Dv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wABAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAMAAAAKAAAAFQAAACQAAAA3LkAvX6bnq/6n6Kz/p+is/6fo + rP+n6Kz/p+is/6forP+n6Kz/p+is/6forP+n6Kz/p+is/6forP94pnvnAAAAsggLCKlvm3PQpeWq/afo + rP+n6Kz/p+is/6forP+n6Kz/p+is/6forP+n6Kz7ouKnmFx/XhQAAAAKAAAACgAAAA0AAAARAAAAGAAA + ACEAAAAtAAAAOgAAAEcAAABVAAAAYwAAAG0AAAB2AAAAeQAAAHcAAABxAAAAZwAAAFgAAABIAAAANwAA + ACgAAAAbAAAAEAAAAAkAAAAFAAAABqLip6qn6Kz/p+is/6forP+n6Kz/p+is/6forP+n6Kz/p+is/6fo + rP+n6Kz/p+is/6forP+m5qv+FBwVxQAAAL8AAAC/AAAAvgAAALkAAACxAAAApAAAAJQAAAB/AAAAZwAA + AEwAAAA2AAAAIwAAABUAAAAKAAAAAwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA//8AgP// + AP///wD///8A////AP///wD///8A////AP///wD///8A/62tHP8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/eXko////AP///wD///8A//// + AP///wD///8A////AP///wD///8A////AMD//wD///8A////AP///wD///8A////AP///wD///8A//// + AP/Y2A7/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8AAQAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADAAAACgAAABYAAAAlAAAAN3akeZqn6Kz/p+is/6fo + rP+n6Kz/p+is/6forP+n6Kz/p+is/6forP+n6Kz/p+is/6forP+k5Kn9GiMawgAAALIAAAClAAAAlRok + G4xvmnKrmdWe1qTkqfGn6Kz/puar8KTkqcij46iEmdWeJQAAAAIAAAADAAAABAAAAAcAAAAMAAAAEwAA + AB0AAAArAAAAOgAAAEkAAABaAAAAagAAAHcAAACCAAAAigAAAI0AAACLAAAAhQAAAHkAAABqAAAAWAAA + AEYAAAA0AAAAJQAAABgAAAAOAAAABwAAAAeCtIYtp+is+qforP+n6Kz/p+is/6forP+n6Kz/p+is/6fo + rP+n6Kz/p+is/6forP+n6Kz/p+is/1FxVNoAAAC/AAAAvwAAAL4AAAC6AAAAsgAAAKUAAACVAAAAgQAA + AGgAAABOAAAANwAAACQAAAAWAAAACgAAAAMAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP// + AID//wD///8A////AP///wD///8A////AP///wD///8A////AP+trRz/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/3l5KP///wD///8A//// + AP///wD///8A////AP///wD///8A////AP///wDA//8A////AP///wD///8A////AP///wD///8A//// + AP///wD/2NgO/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A//// + AAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABAAAAAoAAAAWAAAAJQAAADiUzpjLp+is/6fo + rP+n6Kz/p+is/6forP+n6Kz/p+is/6forP+n6Kz/p+is/6forP+n6Kz/c5925gAAALkAAACxAAAApAAA + AJQAAAB/AAAAZwAAAE0AAAA3AAAAJAAAABUAAAAKAAAAAwAAAAAAAAAAAAAAAQAAAAMAAAAHAAAADgAA + ABgAAAAlAAAANQAAAEcAAABaAAAAawAAAHwAAACKAAAAlQAAAJwAAACeAAAAnAAAAJUAAACKAAAAewAA + AGkAAABVAAAAQgAAADAAAAAgAAAAFAAAAAwAAAAJAAAADZ/dpKmn6Kz/p+is/6forP+n6Kz/p+is/6fo + rP+n6Kz/p+is/6forP+n6Kz/p+is/6forP9+r4LrAAAAvwAAAL8AAAC+AAAAugAAALIAAACmAAAAlQAA + AIEAAABpAAAATwAAADcAAAAlAAAAFgAAAAoAAAADAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAD//wCA//8A////AP///wD///8A////AP///wD///8A////AP///wD/ra0c/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv95eSj///8A//// + AP///wD///8A////AP///wD///8A////AP///wD///8AwP//AP///wD///8A////AP///wD///8A//// + AP///wD///8A/9jYDv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy////AP///wD///8A////AP///wD///8A////AP///wD///8A//// + AP///wABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQAAAAKAAAAFgAAACULDws7pOSp96fo + rP+n6Kz/p+is/6forP+n6Kz/p+is/6forP+n6Kz/p+is/6forP+n6Kz/p+is/ys7LMsAAAC5AAAAsQAA + AKQAAACUAAAAfwAAAGcAAABNAAAANwAAACQAAAAVAAAACgAAAAMAAAAAAAAAAAAAAAEAAAAEAAAACQAA + ABIAAAAdAAAALAAAAD8AAABTAAAAZwAAAHoAAACLAAAAmQAAAKMAAACpAAAArAAAAKkAAACjAAAAmQAA + AIsAAAB5AAAAZQAAAFAAAAA9AAAAKwAAABwAAAARAAAADQAAAA98rYBHp+is/6forP+n6Kz/p+is/6fo + rP+n6Kz/p+is/6forP+n6Kz/p+is/6forP+n6Kz/oN6l+wMEA8AAAAC/AAAAvgAAALoAAACyAAAApgAA + AJUAAACBAAAAaQAAAE8AAAA3AAAAJQAAABYAAAAKAAAAAwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAA//8AgP//AP///wD///8A////AP///wD///8A////AP///wD///8A/62tHP8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/eXko//// + AP///wD///8A////AP///wD///8A////AP///wD///8A////AMD//wD///8A////AP///wD///8A//// + AP///wD///8A////AP/Y2A7/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv///wD///8A////AP///wD///8A////AP///wD///8A//// + AP///wD///8AAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADAAAACgAAABYAAAAlWXxcXqfo + rP+n6Kz/p+is/6forP+n6Kz/p+is/6forP+n6Kz/p+is/6forP+n6Kz/p+is/5PMl/UAAAC+AAAAugAA + ALIAAAClAAAAlQAAAIEAAABpAAAATwAAADgAAAAlAAAAFgAAAAoAAAAEAAAAAAAAAAAAAAABAAAABAAA + AAoAAAAUAAAAIQAAADEAAABGAAAAXAAAAHIAAACFAAAAlgAAAKMAAACuAAAAswAAALUAAACzAAAArgAA + AKUAAACXAAAAhwAAAHMAAABfAAAASgAAADcAAAAmAAAAGQAAABIAAAATAAAAGaPjqOCn6Kz/p+is/6fo + rP+n6Kz/p+is/6forP+n6Kz/p+is/6forP+n6Kz/p+is/6forP8nNyjLAAAAvwAAAL4AAAC6AAAAsgAA + AKUAAACUAAAAgQAAAGgAAABOAAAANwAAACQAAAAWAAAACgAAAAMAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAP//AID//wD///8A////AP///wD///8A////AP///wD///8A////AP+trRz/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/3l5 + KP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wDA//8A////AP///wD///8A//// + AP///wD///8A////AP///wD/2NgO/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL///8A////AP///wD///8A////AP///wD///8A//// + AP///wD///8A////AAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAwAAAAoAAAAVAAAAJH6v + goan6Kz/p+is/6forP+n6Kz/p+is/6forP+n6Kz/p+is/6forP+n6Kz/p+is/6forP9ki2fhAAAAvgAA + ALoAAACyAAAApgAAAJcAAACDAAAAawAAAFEAAAA6AAAAJwAAABcAAAAMAAAABAAAAAEAAAAAAAAAAQAA + AAQAAAALAAAAFQAAACMAAAA0AAAASgAAAGEAAAB4AAAAiwAAAJ0AAACqAAAAswAAALgAAAC7AAAAuQAA + ALUAAACtAAAAogAAAJQAAACCAAAAbQAAAFgAAABDAAAAMQAAACIAAAAZAAAAGAAAAB2TzJecp+is/6fo + rP+n6Kz/p+is/6forP+n6Kz/p+is/6forP+n6Kz/p+is/6forP+n6Kz/S2hN1wAAAL8AAAC+AAAAuQAA + ALEAAACkAAAAlAAAAH8AAABnAAAATAAAADYAAAAjAAAAFQAAAAoAAAADAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAD//wCA//8A////AP///wD///8A////AP///wD///8A////AP///wD/ra0c/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv95eSj///8A////AP///wD///8A////AP///wD///8A////AP///wD///8AwP//AP///wD///8A//// + AP///wD///8A////AP///wD///8A/9jYDv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy////AP///wD///8A////AP///wD///8A//// + AP///wD///8A////AP///wABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAMAAAAKAAAAFAAA + ACKQyJSnp+is/6forP+n6Kz/p+is/6forP+n6Kz/p+is/6forP+n6Kz/p+is/6forP+n6Kz/Nks30AAA + AL4AAAC7AAAAswAAAKgAAACZAAAAhgAAAG8AAABVAAAAPQAAACoAAAAZAAAADQAAAAUAAAABAAAAAAAA + AAEAAAAEAAAACgAAABUAAAAiAAAANAAAAEoAAABhAAAAeQAAAI0AAACeAAAArAAAALUAAAC7AAAAvAAA + ALwAAAC5AAAAswAAAKoAAACeAAAAjgAAAHwAAABnAAAAUgAAAD0AAAAtAAAAIgAAAB8AAAAjcZ11Z6fo + rP+n6Kz/p+is/6forP+n6Kz/p+is/6forP+n6Kz/p+is/6forP+n6Kz/p+is/2mSbOMAAAC/AAAAvgAA + ALkAAACwAAAAowAAAJIAAAB9AAAAZAAAAEsAAAA0AAAAIgAAABMAAAAJAAAAAwAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAA//8AgP//AP///wD///8A////AP///wD///8A////AP///wD///8A/62t + HP8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/eXko////AP///wD///8A////AP///wD///8A////AP///wD///8A////AMD//wD///8A//// + AP///wD///8A////AP///wD///8A////AP/Y2A7/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv///wD///8A////AP///wD///8A//// + AP///wD///8A////AP///wD///8AAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACAAAACQAA + ABMAAAAhmtafxKforP+n6Kz/p+is/6forP+n6Kz/p+is/6forP+n6Kz/p+is/6forP+n6Kz/puer/goP + C8IAAAC+AAAAuwAAALUAAACqAAAAnAAAAIoAAABzAAAAWgAAAEMAAAAuAAAAHQAAABAAAAAHAAAAAgAA + AAEAAAABAAAABAAAAAoAAAATAAAAIAAAADEAAABGAAAAXgAAAHUAAACJAAAAmwAAAKkAAACzAAAAugAA + AL0AAAC9AAAAuwAAALgAAACxAAAApgAAAJkAAACIAAAAdQAAAGAAAABMAAAAOgAAAC4AAAApAAAALCY1 + J0Kn6Kz/p+is/6forP+n6Kz/p+is/6forP+n6Kz/p+is/6forP+n6Kz/p+is/6forP98rYDrAAAAvwAA + AL4AAAC4AAAArwAAAKEAAACQAAAAewAAAGIAAABIAAAAMgAAACAAAAATAAAACAAAAAIAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAP//AID//wD///8A////AP///wD///8A////AP///wD///8A//// + AP+trRz/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/3l5KP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wDA//8A//// + AP///wD///8A////AP///wD///8A////AP///wD/2NgO/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL///8A////AP///wD///8A//// + AP///wD///8A////AP///wD///8A////AAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAgAA + AAcAAAARAAAAH6Hgptqn6Kz/p+is/6forP+n6Kz/p+is/6forP+n6Kz/p+is/6forP+n6Kz/p+is/5bQ + mvcAAAC/AAAAvwAAALwAAAC3AAAArQAAAKAAAACOAAAAeQAAAGEAAABJAAAAMwAAACIAAAATAAAACgAA + AAQAAAABAAAAAQAAAAMAAAAIAAAAEAAAABwAAAAsAAAAQAAAAFYAAABtAAAAggAAAJQAAACkAAAArwAA + ALcAAAC7AAAAvQAAAL0AAAC7AAAAtQAAAK4AAACjAAAAlAAAAIIAAABvAAAAWwAAAEkAAAA8AAAANgAA + ADcAAABAoN6l6qforP+n6Kz/p+is/6forP+n6Kz/p+is/6forP+n6Kz/p+is/6forP+n6Kz/jMOQ8gAA + AL8AAAC9AAAAtwAAAKwAAACfAAAAjQAAAHcAAABeAAAARQAAADAAAAAfAAAAEQAAAAcAAAACAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD//wCA//8A////AP///wD///8A////AP///wD///8A//// + AP///wD/ra0c/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv95eSj///8A////AP///wD///8A////AP///wD///8A////AP///wD///8AwP// + AP///wD///8A////AP///wD///8A////AP///wD///8A/9jYDv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy////AP///wD///8A//// + AP///wD///8A////AP///wD///8A////AP///wABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAEAAAAHAAAAEAAAAByk5Knsp+is/6forP+n6Kz/p+is/6forP+n6Kz/p+is/6forP+n6Kz/p+is/6fo + rP+FuYnvAAAAvwAAAL8AAAC9AAAAuAAAALAAAACkAAAAlAAAAIAAAABoAAAAUAAAADoAAAAoAAAAGAAA + AA0AAAAGAAAAAgAAAAEAAAACAAAABwAAAA0AAAAXAAAAJQAAADcAAABMAAAAYgAAAHcAAACLAAAAnAAA + AKkAAACyAAAAuAAAALwAAAC9AAAAvAAAALkAAAC0AAAAqwAAAJ8AAACPAAAAfQAAAGoAAABYAAAATAAA + AEQAAABEAAAATJbQmtan6Kz/p+is/6forP+n6Kz/p+is/6forP+n6Kz/p+is/6forP+n6Kz/p+is/5jT + nPgAAAC+AAAAvAAAALUAAACrAAAAnAAAAIoAAABzAAAAWgAAAEIAAAAtAAAAHAAAABAAAAAHAAAAAQAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA//8AgP//AP///wD///8A////AP///wD///8A//// + AP///wD///8A/62tHP8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/eXko////AP///wD///8A////AP///wD///8A////AP///wD///8A//// + AMD//wD///8A////AP///wD///8A////AP///wD///8A////AP/Y2A7/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv///wD///8A//// + AP///wD///8A////AP///wD///8A////AP///wD///8AAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAABAAAABQAAAA0AAAAapuar8qforP+n6Kz/p+is/6forP+n6Kz/p+is/6forP+n6Kz/p+is/6fo + rP+n6Kz/fK2A6wAAAL8AAAC/AAAAvgAAALoAAACzAAAAqAAAAJoAAACHAAAAcQAAAFkAAABDAAAALwAA + AB8AAAASAAAACQAAAAQAAAABAAAAAgAAAAQAAAAKAAAAEgAAAB4AAAAuAAAAQAAAAFVghmOgir+O2QMF + A5IAAAChAAAArAAAALUAAAC6AAAAvQAAAL0AAAC7AAAAuAAAALEAAACnAAAAmgAAAIsAAAB5AAAAaQAA + AFwAAABVAAAAVAAAAFqKwI7Lp+is/6forP+n6Kz/p+is/6forP+n6Kz/p+is/6forP+n6Kz/p+is/6fo + rP+g3qX7AAAAvgAAALsAAACzAAAAqAAAAJkAAACFAAAAbwAAAFUAAAA9AAAAKgAAABkAAAANAAAABQAA + AAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP//AID//wD///8A////AP///wD///8A//// + AP///wD///8A////AP+trRz/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/3l5KP///wD///8A////AP///wD///8A////AP///wD///8A//// + AP///wDA//8A////AP///wD///8A////AP///wD///8A////AP///wD/2NgO/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL///8A//// + AP///wD///8A////AP///wD///8A////AP///wD///8A////AAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAQAAAAQAAAAMAAAAF6forP6n6Kz/p+is/6forP+n6Kz/p+is/6forP+n6Kz/p+is/6fo + rP+n6Kz/p+is/3Shd+cAAAC/AAAAvwAAAL4AAAC7AAAAtQAAAKwAAACgAAAAjwAAAHoAAABkAAAATQAA + ADgAAAAmAAAAGAAAAA0AAAAHAAAAAwAAAAIAAAADAAAABwAAAA0AAAAWAAAAJDRJNkaTzZjEp+is/6fo + rP9qk22/AAAAlwAAAKUAAACvAAAAtwAAALsAAAC9AAAAvQAAALsAAAC2AAAArwAAAKQAAACXAAAAiAAA + AHkAAABuAAAAZwAAAGUAAABqhLeIzKforP+n6Kz/p+is/6forP+n6Kz/p+is/6forP+n6Kz/p+is/6fo + rP+n6Kz/o+Oo/QAAAL4AAAC5AAAAsQAAAKUAAACVAAAAgQAAAGoAAABQAAAAOQAAACYAAAAXAAAADAAA + AAQAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD//wCA//8A////AP///wD///8A//// + AP///wD///8A////AP///wD/ra0c/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv95eSj///8A////AP///wD///8A////AP///wD///8A//// + AP///wD///8AwP//AP///wD///8A////AP///wD///8A////AP///wD///8A/9jYDv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy//// + AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wABAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAEAAAAEAAAACgAAABSn6Kz8p+is/6forP+n6Kz/p+is/6forP+n6Kz/p+is/6fo + rP+n6Kz/p+is/6forP9xnXXmAAAAvwAAAL8AAAC+AAAAvQAAALgAAACxAAAApgAAAJcAAACEAAAAbwAA + AFgAAABDAAAAMAAAACAAAAATAAAACwAAAAYAAAADAAAAAwAAAAQAAAAJAAAAEIm+jWSk5Kntp+is/6fo + rP+n6Kz/peWq/DFEM6AAAACcAAAAqQAAALIAAAC4AAAAuwAAAL0AAAC8AAAAuQAAALQAAACsAAAAoQAA + AJUAAACJAAAAfwAAAHkAAAB2AAAAeoK0htKn6Kz/p+is/6forP+n6Kz/p+is/6forP+n6Kz/p+is/6fo + rP+n6Kz/p+is/6PjqP0AAAC9AAAAuAAAAK8AAAChAAAAkAAAAHsAAABjAAAASgAAADQAAAAiAAAAFAAA + AAoAAAAEAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA//8AgP//AP///wD///8A//// + AP///wD///8A////AP///wD///8A/62tHP8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/eXko////AP///wD///8A////AP///wD///8A//// + AP///wD///8A////AMD//wD///8A////AP///wD///8A////AP///wD///8A////AP/Y2A7/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8AAQAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAgAAAAgAAAARpuar8qforP+n6Kz/p+is/6forP+n6Kz/p+is/6fo + rP+n6Kz/p+is/6forP+n6Kz/eKZ76QAAAL8AAAC/AAAAvwAAAL4AAAC6AAAAtQAAAKsAAACfAAAAjgAA + AHsAAABlAAAAUAAAADwAAAArAAAAHAAAABEAAAAKAAAABQAAAAQAAAAEe6t/F6PjqKen6Kz/p+is/6fo + rP+n6Kz/p+is/6forP+X0pzpCAsIlAAAAKAAAACsAAAAtAAAALkAAAC8AAAAvQAAALsAAAC4AAAAsgAA + AKkAAACgAAAAlwAAAJAAAACKAAAAiAAAAIuGuorep+is/6forP+n6Kz/p+is/6forP+n6Kz/p+is/6fo + rP+n6Kz/p+is/6forP+g3qX7AAAAuwAAALUAAACrAAAAnQAAAIsAAAB1AAAAXAAAAEQAAAAvAAAAHgAA + ABEAAAAIAAAAAgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP//AID//wD///8A//// + AP///wD///8A////AP///wD///8A////AP+trRz/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/3l5KP///wD///8A////AP///wD///8A//// + AP///wD///8A////AP///wDA//8A////AP///wD///8A////AP///wD///8A////AP///wD/2NgO/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AAEAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEAAAAGAAAADqbmq+mn6Kz/p+is/6forP+n6Kz/p+is/6fo + rP+n6Kz/p+is/6forP+n6Kz/p+is/4W5ie8AAAC/AAAAvwAAAL8AAAC+AAAAvAAAALgAAACwAAAApgAA + AJgAAACHAAAAcwAAAF4AAABKAAAANwAAACgAAAAaAAAAEAAAAAoAAAAGAAAABKbnq8Kn6Kz/p+is/6fo + rP+n6Kz/p+is/6forP+n6Kz/p+is/3WieMcAAACWAAAApAAAAK8AAAC2AAAAuwAAAL0AAAC9AAAAuwAA + ALcAAACxAAAAqgAAAKMAAACdAAAAmgAAAJcAAACajMOQ6KforP+n6Kz/p+is/6forP+n6Kz/p+is/6fo + rP+n6Kz/p+is/6forP+n6Kz/mNOc+AAAALoAAACyAAAApwAAAJcAAACFAAAAbQAAAFUAAAA+AAAAKgAA + ABoAAAAOAAAABgAAAAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD//wCA//8A//// + AP///wD///8A////AP///wD///8A////AP///wD/ra0c/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv95eSj///8A////AP///wD///8A//// + AP///wD///8A////AP///wD///8AwP//AP///wD///8A////AP///wD///8A////AP///wD///8A/9jY + Dv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wABAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABAAAABAAAAAyk46nTp+is/6forP+n6Kz/p+is/6fo + rP+n6Kz/p+is/6forP+n6Kz/p+is/6forP+W0Jr2AAAAvwAAAL8AAAC/AAAAvgAAAL0AAAC6AAAAtQAA + AKwAAAChAAAAkgAAAIEAAABtAAAAWgAAAEYAAAA1AAAAJgAAABoAAAARAAAACwAAAAec2aE7p+is/Kfo + rP+n6Kz/p+is/6forP+n6Kz/p+is/6forP+m56v+PlZApgAAAJoAAACnAAAAsQAAALgAAAC7AAAAvQAA + AL0AAAC6AAAAtgAAALIAAACtAAAAqQAAAKYAAACkAAAApprWn/Wn6Kz/p+is/6forP+n6Kz/p+is/6fo + rP+n6Kz/p+is/6forP+n6Kz/p+is/43EkfEAAAC4AAAArwAAAKIAAACRAAAAfQAAAGYAAABOAAAANwAA + ACUAAAAWAAAACwAAAAQAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA//8AgP// + AP///wD///8A////AP///wD///8A////AP///wD///8A/62tHP8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/eXko////AP///wD///8A//// + AP///wD///8A////AP///wD///8A////AMD//wD///8A////AP///wD///8A////AP///wD///8A//// + AP/Y2A7/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8AAQAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQAAAAMAAAAJouGnuaforP+n6Kz/p+is/6fo + rP+n6Kz/p+is/6forP+n6Kz/p+is/6forP+n6Kz/puer/gsPC8IAAAC/AAAAvwAAAL8AAAC+AAAAvAAA + ALgAAACyAAAAqQAAAJ0AAACOAAAAfQAAAGoAAABYAAAARgAAADUAAAAoAAAAHAAAABMAAAANAAAACqPj + qIan6Kz/p+is/6forP+n6Kz/p+is/6forP+n6Kz/p+is/5zZoe8OFA+VAAAAnwAAAKsAAAC0AAAAuQAA + ALwAAAC9AAAAvAAAALoAAAC3AAAAtQAAALIAAACvAAAArw4TDrSm56v/p+is/6forP+n6Kz/p+is/6fo + rP+n6Kz/p+is/6forP+n6Kz/p+is/6forP9+sILqAAAAtQAAAKoAAACdAAAAiwAAAHUAAABeAAAARgAA + ADEAAAAfAAAAEgAAAAkAAAADAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP// + AID//wD///8A////AP///wD///8A////AP///wD///8A////AP+trRz/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/3l5KP///wD///8A//// + AP///wD///8A////AP///wD///8A////AP///wDA//8A////AP///wD///8A////AP///wD///8A//// + AP///wD/2NgO/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A//// + AAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEAAAACAAAAB6DfpZmn6Kz/p+is/6fo + rP+n6Kz/p+is/6forP+n6Kz/p+is/6forP+n6Kz/p+is/6forP81SjfQAAAAvwAAAL8AAAC/AAAAvgAA + AL4AAAC7AAAAtwAAALAAAACmAAAAmgAAAIsAAAB7AAAAaQAAAFgAAABGAAAANwAAACsAAAAgAAAAGAAA + ABIuQTASpuarz6forP+n6Kz/p+is/6forP+n6Kz/p+is/6forP+n6Kz/fq+C0AAAAJcAAAClAAAArwAA + ALcAAAC7AAAAvgAAAL4AAAC8AAAAuwAAALkAAAC4AAAAtwAAALY6UDvKp+is/6forP+n6Kz/p+is/6fo + rP+n6Kz/p+is/6forP+n6Kz/p+is/6forP+n6Kz/aJFr3gAAALEAAAClAAAAlgAAAIIAAABsAAAAVAAA + AD0AAAAqAAAAGgAAAA8AAAAHAAAAAgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAD//wCA//8A////AP///wD///8A////AP///wD///8A////AP///wD/ra0c/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv95eSj///8A//// + AP///wD///8A////AP///wD///8A////AP///wD///8AwP//AP///wD///8A////AP///wD///8A//// + AP///wD///8A/9jYDv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy////AP///wD///8A////AP///wD///8A////AP///wD///8A//// + AP///wABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQAAAASc2aFqp+is/6fo + rP+n6Kz/p+is/6forP+n6Kz/p+is/6forP+n6Kz/p+is/6forP+n6Kz/Y4lm4AAAAL8AAAC/AAAAvwAA + AL8AAAC+AAAAvQAAALoAAAC1AAAArwAAAKUAAACZAAAAiwAAAHsAAABqAAAAWgAAAEoAAAA8AAAAMAAA + ACYAAAAeAAAAGXWjeTym56v4p+is/6forP+n6Kz/p+is/6forP+n6Kz/p+is/6forP9KZ0yyAAAAoAAA + AKwAAAC1AAAAugAAAL0AAAC+AAAAvgAAAL0AAAC8AAAAvAAAALsAAAC7Z49q4KforP+n6Kz/p+is/6fo + rP+n6Kz/p+is/6forP+n6Kz/p+is/6forP+n6Kz/p+is/09tUdEAAACsAAAAnwAAAI4AAAB5AAAAYgAA + AEsAAAA1AAAAIwAAABYAAAALAAAABAAAAAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAA//8AgP//AP///wD///8A////AP///wD///8A////AP///wD///8A/62tHP8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/eXko//// + AP///wD///8A////AP///wD///8A////AP///wD///8A////AMD//wD///8A////AP///wD///8A//// + AP///wD///8A////AP/Y2A7/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv///wD///8A////AP///wD///8A////AP///wD///8A//// + AP///wD///8AAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEAAAADltCaOqfo + rP+n6Kz/p+is/6forP+n6Kz/p+is/6forP+n6Kz/p+is/6forP+n6Kz/p+is/5bQmvYBAQG/AAAAvwAA + AL8AAAC/AAAAvwAAAL4AAAC8AAAAuQAAALUAAACuAAAApAAAAJkAAACLAAAAfQAAAG0AAABeAAAATwAA + AEMAAAA3AAAALgAAACcAAAAikcqWgqforP+n6Kz/p+is/6forP+n6Kz/p+is/6forP+n6Kz/ntuj9RYf + F6QAAACpAAAAsgAAALgAAAC9AAAAvgAAAL4AAAC+AAAAvgAAAL4AAAC+AAAAvpTOmPan6Kz/p+is/6fo + rP+n6Kz/p+is/6forP+n6Kz/p+is/6forP+n6Kz/p+is/6forP8nNyi/AAAApgAAAJcAAACFAAAAbwAA + AFgAAABBAAAALgAAAB0AAAARAAAACAAAAAMAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAP//AID//wD///8A////AP///wD///8A////AP///wD///8A////AP+trRz/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/3l5 + KP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wDA//8A////AP///wD///8A//// + AP///wD///8A////AP///wD/2NgO/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL///8A////AP///wD///8A////AP///wD///8A//// + AP///wD///8A////AAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABAAAAAkxq + Tgum56v0p+is/6forP+n6Kz/p+is/6forP+n6Kz/p+is/6forP+n6Kz/p+is/6forP+n6Kz/Nkw4zwAA + AL8AAAC/AAAAvwAAAL8AAAC+AAAAvgAAALwAAAC5AAAAtQAAAK4AAAClAAAAmgAAAI4AAACBAAAAcwAA + AGUAAABYAAAATAAAAEIAAAA6AAAAMwMFAy+e26PJp+is/6forP+n6Kz/p+is/6forP+n6Kz/p+is/6fo + rP+DtoffAAAApgAAALEAAAC4AAAAvAAAAL4AAAC/AAAAvwAAAL8AAAC/AAAAvy0/L8yn6Kz/p+is/6fo + rP+n6Kz/p+is/6forP+n6Kz/p+is/6forP+n6Kz/p+is/6forP+h4Kb7AwQDrQAAAJ8AAACOAAAAegAA + AGQAAABNAAAANwAAACUAAAAXAAAADQAAAAYAAAACAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAD//wCA//8A////AP///wD///8A////AP///wD///8A////AP///wD/ra0c/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv95eSj///8A////AP///wD///8A////AP///wD///8A////AP///wD///8AwP//AP///wD///8A//// + AP///wD///8A////AP///wD///8A/9jYDv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy////AP///wD///8A////AP///wD///8A//// + AP///wD///8A////AP///wABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAEAAAAEpOSpt6forP+n6Kz/p+is/6forP+n6Kz/p+is/6forP+n6Kz/p+is/6forP+n6Kz/p+is/3em + e+gAAAC/AAAAvwAAAL8AAAC/AAAAvwAAAL4AAAC+AAAAvAAAALkAAAC1AAAArwAAAKYAAACdAAAAkgAA + AIYAAAB6AAAAbgAAAGMAAABYAAAATwAAAEgAAABDPFQ+VqTkqfSn6Kz/p+is/6forP+n6Kz/p+is/6fo + rP+n6Kz/p+is/1FxVMgAAACwAAAAtwAAALsAAAC+AAAAvwAAAL8AAAC/AAAAvwAAAL91onjnp+is/6fo + rP+n6Kz/p+is/6forP+n6Kz/p+is/6forP+n6Kz/p+is/6forP+n6Kz/gLGE5wAAAKUAAACWAAAAgwAA + AG4AAABYAAAAQgAAAC4AAAAeAAAAEgAAAAkAAAAEAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAA//8AgP//AP///wD///8A////AP///wD///8A////AP///wD///8A/62t + HP8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/eXko////AP///wD///8A////AP///wD///8A////AP///wD///8A////AMD//wD///8A//// + AP///wD///8A////AP///wD///8A////AP/Y2A7/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv///wD///8A////AP///wD///8A//// + AP///wD///8A////AP///wD///8AAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAABAAAAAqHgpnKn6Kz/p+is/6forP+n6Kz/p+is/6forP+n6Kz/p+is/6forP+n6Kz/p+is/6fo + rP+k5Kn9GiQbxgAAAL8AAAC/AAAAvwAAAL8AAAC/AAAAvgAAAL4AAAC8AAAAuQAAALUAAACwAAAAqQAA + AKEAAACXAAAAjgAAAIQAAAB5AAAAcAAAAGcAAABgAAAAWgAAAFVslm+Tp+is/6forP+n6Kz/p+is/6fo + rP+n6Kz/p+is/6forP+h4Kb6HSgeuwAAALgAAAC7AAAAvgAAAL8AAAC/AAAAvwAAAL8bJRzHpOSp/qfo + rP+n6Kz/p+is/6forP+n6Kz/p+is/6forP+n6Kz/p+is/6forP+n6Kz/p+is/1Z3WMwAAACcAAAAiwAA + AHgAAABiAAAATAAAADcAAAAlAAAAGAAAAA0AAAAHAAAAAgAAAAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAP//AID//wD///8A////AP///wD///8A////AP///wD///8A//// + AP+trRz/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/3l5KP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wDA//8A//// + AP///wD///8A////AP///wD///8A////AP///wD/2NgO/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL///8A////AP///wD///8A//// + AP///wD///8A////AP///wD///8A////AAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAGRyZUep+is/aforP+n6Kz/p+is/6forP+n6Kz/p+is/6forP+n6Kz/p+is/6fo + rP+n6Kz/p+is/3Shd+YAAAC+AAAAvwAAAL8AAAC/AAAAvwAAAL8AAAC+AAAAvgAAALwAAAC6AAAAtwAA + ALIAAACsAAAApgAAAJ4AAACXAAAAjgAAAIYAAAB/AAAAeQAAAHMAAABvAAAAbIvCkM+n6Kz/p+is/6fo + rP+n6Kz/p+is/6forP+n6Kz/p+is/4e7i+wCAwK5AAAAvAAAAL4AAAC/AAAAvwAAAL8AAAC/eah96qfo + rP+n6Kz/p+is/6forP+n6Kz/p+is/6forP+n6Kz/p+is/6forP+n6Kz/p+is/6bmq/4YIRiqAAAAkQAA + AH8AAABqAAAAVQAAAEAAAAAtAAAAHQAAABIAAAAKAAAABAAAAAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD//wCA//8A////AP///wD///8A////AP///wD///8A//// + AP///wD/ra0c/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv95eSj///8A////AP///wD///8A////AP///wD///8A////AP///wD///8AwP// + AP///wD///8A////AP///wD///8A////AP///wD///8A/9jYDv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy////AP///wD///8A//// + AP///wD///8A////AP///wD///8A////AP///wABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAABAAAAAqXlqsGn6Kz/p+is/6forP+n6Kz/p+is/6forP+n6Kz/p+is/6fo + rP+n6Kz/p+is/6forP+m56v/MkUzzQAAAL4AAAC/AAAAvwAAAL8AAAC/AAAAvwAAAL4AAAC+AAAAvQAA + ALsAAAC4AAAAtQAAALAAAACrAAAApQAAAJ8AAACZAAAAlAAAAI4AAACJAAAAhQAAAIMZIxqMntyj86fo + rP+n6Kz/p+is/6forP+n6Kz/p+is/6forP+n6Kz/WHtb2QAAAL0AAAC+AAAAvwAAAL8AAAC/NUo30Kfo + rP+n6Kz/p+is/6forP+n6Kz/p+is/6forP+n6Kz/p+is/6forP+n6Kz/p+is/6forP+IvYznAAAAlwAA + AIUAAAByAAAAXQAAAEgAAAA0AAAAIwAAABYAAAANAAAABgAAAAIAAAABAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA//8AgP//AP///wD///8A////AP///wD///8A//// + AP///wD///8A/62tHP8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/eXko////AP///wD///8A////AP///wD///8A////AP///wD///8A//// + AMD//wD///8A////AP///wD///8A////AP///wD///8A////AP/Y2A7/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv///wD///8A//// + AP///wD///8A////AP///wD///8A////AP///wD///8AAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAGi4adhp+is/6forP+n6Kz/p+is/6forP+n6Kz/p+is/6fo + rP+n6Kz/p+is/6forP+n6Kz/p+is/5XPmfUNEg3BAAAAvgAAAL8AAAC/AAAAvwAAAL8AAAC/AAAAvwAA + AL4AAAC+AAAAvAAAALoAAAC4AAAAtAAAALAAAACsAAAAqAAAAKMAAACgAAAAnAAAAJkAAACXAAAAlUdi + Sban6Kz/p+is/6forP+n6Kz/p+is/6forP+n6Kz/p+is/6PjqP0lMybJAAAAvgAAAL8AAAC/DRINw5XP + mvan6Kz/p+is/6forP+n6Kz/p+is/6forP+n6Kz/p+is/6forP+n6Kz/p+is/6forP+n6Kz/TWtQvgAA + AIsAAAB4AAAAZAAAAE8AAAA7AAAAKQAAABsAAAAQAAAACQAAAAQAAAABAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP//AID//wD///8A////AP///wD///8A//// + AP///wD///8A////AP+trRz/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/3l5KP///wD///8A////AP///wD///8A////AP///wD///8A//// + AP///wDA//8A////AP///wD///8A////AP///wD///8A////AP///wD/2NgO/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL///8A//// + AP///wD///8A////AP///wD///8A////AP///wD///8A////AAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABfa6BCKforOan6Kz/p+is/6forP+n6Kz/p+is/6fo + rP+n6Kz/p+is/6forP+n6Kz/p+is/6forP+n6Kz/fKx/6QEBAb0AAAC+AAAAvwAAAL8AAAC/AAAAvwAA + AL8AAAC/AAAAvgAAAL4AAAC9AAAAvAAAALoAAAC4AAAAtQAAALIAAACvAAAArQAAAKoAAACoAAAApgAA + AKUAAACldqR53KforP+n6Kz/p+is/6forP+n6Kz/p+is/6forP+n6Kz/jcWS8wUHBcAAAAC/AQEBv3ys + f+un6Kz/p+is/6forP+n6Kz/p+is/6forP+n6Kz/p+is/6forP+n6Kz/p+is/6forP+n6Kz/ndmh9gcJ + B5QAAAB/AAAAagAAAFUAAABBAAAALwAAAB8AAAATAAAACwAAAAUAAAACAAAAAQAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD//wCA//8A////AP///wD///8A//// + AP///wD///8A////AP///wD/ra0c/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv95eSj///8A////AP///wD///8A////AP///wD///8A//// + AP///wD///8AwP//AP///wD///8A////AP///wD///8A////AP///wD///8A/9jYDv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy//// + AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wABAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAGk5Kl9p+is/6forP+n6Kz/p+is/6fo + rP+n6Kz/p+is/6forP+n6Kz/p+is/6forP+n6Kz/p+is/6forP9fhGLcAAAAvQAAAL4AAAC/AAAAvwAA + AL8AAAC/AAAAvwAAAL8AAAC/AAAAvgAAAL4AAAC+AAAAvAAAALsAAAC6AAAAuAAAALYAAAC1AAAAswAA + ALIAAACyAAAAsQwQDLaX0Zv1p+is/6forP+n6Kz/p+is/6forP+n6Kz/p+is/6forP9jiWbgAAAAv16D + Yd+n6Kz/p+is/6forP+n6Kz/p+is/6forP+n6Kz/p+is/6forP+n6Kz/p+is/6forP+n6Kz/p+is/2SK + Z8gAAACHAAAAcwAAAF4AAABJAAAANQAAACUAAAAXAAAADQAAAAcAAAADAAAAAQAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA//8AgP//AP///wD///8A//// + AP///wD///8A////AP///wD///8A/62tHP8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/eXko////AP///wD///8A////AP///wD///8A//// + AP///wD///8A////AMD//wD///8A////AP///wD///8A////AP///wD///8A////AP/Y2A7/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8AAQAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABnNmhD6forOun6Kz/p+is/6fo + rP+n6Kz/p+is/6forP+n6Kz/p+is/6forP+n6Kz/p+is/6forP+n6Kz/p+is/1p+XdoAAAC9AAAAvgAA + AL8AAAC/AAAAvwAAAL8AAAC/AAAAvwAAAL8AAAC/AAAAvwAAAL4AAAC+AAAAvgAAAL0AAAC8AAAAuwAA + ALsAAAC6AAAAugAAALoAAAC6MkY0y6bmq/6n6Kz/p+is/6forP+n6Kz/p+is/6forP+n6Kz/puar/m6Z + ceWn6Kz/p+is/6forP+n6Kz/p+is/6forP+n6Kz/p+is/6forP+n6Kz/p+is/6forP+n6Kz/p+is/5/d + pPgQFhCXAAAAfQAAAGgAAABSAAAAPQAAACsAAAAcAAAAEAAAAAkAAAAEAAAAAQAAAAEAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP//AID//wD///8A//// + AP///wD///8A////AP///wD///8A////AP+trRz/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/3l5KP///wD///8A////AP///wD///8A//// + AP///wD///8A////AP///wDA//8A////AP///wD///8A////AP///wD///8A////AP///wD/2NgO/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AAEAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAGm5qtzp+is/6fo + rP+n6Kz/p+is/6forP+n6Kz/p+is/6forP+n6Kz/p+is/6forP+n6Kz/p+is/6forP+n6Kz/XoJg2wEB + AbwAAAC+AAAAvgAAAL8AAAC/AAAAvwAAAL8AAAC/AAAAvwAAAL8AAAC/AAAAvwAAAL8AAAC/AAAAvwAA + AL4AAAC+AAAAvgAAAL4AAAC+AAAAvgAAAL5mjWnhp+is/6forP+n6Kz/p+is/6forP+n6Kz/p+is/6fo + rP+n6Kz/p+is/6forP+n6Kz/p+is/6forP+n6Kz/p+is/6forP+n6Kz/p+is/6forP+n6Kz/p+is/6fo + rP9egmDIAAAAiwAAAHYAAABgAAAASQAAADUAAAAkAAAAFgAAAAwAAAAGAAAAAgAAAAEAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD//wCA//8A//// + AP///wD///8A////AP///wD///8A////AP///wD/ra0c/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv95eSj///8A////AP///wD///8A//// + AP///wD///8A////AP///wD///8AwP//AP///wD///8A////AP///wD///8A////AP///wD///8A/9jY + Dv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wABAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAksuWCKfo + rNan6Kz/p+is/6forP+n6Kz/p+is/6forP+n6Kz/p+is/6forP+n6Kz/p+is/6forP+n6Kz/p+is/6fo + rP97q3/oDBENvwAAAL4AAAC+AAAAvwAAAL8AAAC/AAAAvwAAAL8AAAC/AAAAvwAAAL8AAAC/AAAAvwAA + AL8AAAC/AAAAvwAAAL8AAAC/AAAAvwAAAL8AAAC/BggGwY/HlPOn6Kz/p+is/6forP+n6Kz/p+is/6fo + rP+n6Kz/p+is/6forP+n6Kz/p+is/6forP+n6Kz/p+is/6forP+n6Kz/p+is/6forP+n6Kz/p+is/6fo + rP+W0JryBwkHnAAAAIgAAAByAAAAWwAAAEUAAAAxAAAAHwAAABMAAAAKAAAABAAAAAEAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA//8AgP// + AP///wD///8A////AP///wD///8A////AP///wD///8A/62tHP8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/eXko////AP///wD///8A//// + AP///wD///8A////AP///wD///8A////AMD//wD///8A////AP///wD///8A////AP///wD///8A//// + AP/Y2A7/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8AAQAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAGk5Kk+p+is/qforP+n6Kz/p+is/6forP+n6Kz/p+is/6forP+n6Kz/p+is/6forP+n6Kz/p+is/6fo + rP+n6Kz/p+is/5PNmPQwQjHKAAAAvAAAAL4AAAC+AAAAvwAAAL8AAAC/AAAAvwAAAL8AAAC/AAAAvwAA + AL8AAAC/AAAAvwAAAL8AAAC/AAAAvwAAAL8AAAC/AAAAvwAAAL8mNSfLpOSp/aforP+n6Kz/p+is/6fo + rP+n6Kz/p+is/6forP+n6Kz/p+is/6forP+n6Kz/p+is/6forP+n6Kz/p+is/6forP+n6Kz/p+is/6fo + rP+m56v/Nkw4vgAAAJoAAACIAAAAcwAAAFsAAABFAAAAMQAAAB8AAAATAAAACgAAAAQAAAABAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP// + AID//wD///8A////AP///wD///8A////AP///wD///8A////AP+trRz/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/3l5KP///wD///8A//// + AP///wD///8A////AP///wD///8A////AP///wDA//8A////AP///wD///8A////AP///wD///8A//// + AP///wD/2NgO/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A//// + AAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAaforJWn6Kz/p+is/6forP+n6Kz/p+is/6forP+n6Kz/p+is/6forP+n6Kz/p+is/6fo + rP+n6Kz/p+is/6forP+n6Kz/puer/nOgd+QYIhnCAAAAvQAAAL4AAAC+AAAAvwAAAL8AAAC/AAAAvwAA + AL8AAAC/AAAAvwAAAL8AAAC/AAAAvwAAAL8AAAC/AAAAvwAAAL8AAAC/AAAAv1l8XN2n6Kz/p+is/6fo + rP+n6Kz/p+is/6forP+n6Kz/p+is/6forP+n6Kz/p+is/6forP+n6Kz/p+is/6forP+n6Kz/p+is/6fo + rP+n6Kz/bplx4AAAAKoAAACdAAAAiwAAAHYAAABfAAAASQAAADQAAAAjAAAAFQAAAAsAAAAFAAAAAgAA + AAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAD//wCA//8A////AP///wD///8A////AP///wD///8A////AP///wD/ra0c/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv95eSj///8A//// + AP///wD///8A////AP///wD///8A////AP///wD///8AwP//AP///wD///8A////AP///wD///8A//// + AP///wD///8A/9jYDv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy////AP///wD///8A////AP///wD///8A////AP///wD///8A//// + AP///wABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAACX0ZsKp+is0qforP+n6Kz/p+is/6forP+n6Kz/p+is/6forP+n6Kz/p+is/6fo + rP+n6Kz/p+is/6forP+n6Kz/p+is/6forP+n6Kz/pOSp/XOgd+QrOyzJAAAAvAAAAL4AAAC+AAAAvgAA + AL8AAAC/AAAAvwAAAL8AAAC/AAAAvwAAAL8AAAC/AAAAvwAAAL8AAAC/AAAAvys7LMx0oXfnpuer/6fo + rP+n6Kz/p+is/6forP+n6Kz/p+is/6forP+n6Kz/p+is/6forP+n6Kz/p+is/6forP+n6Kz/p+is/6fo + rP+n6Kz/kMiU8wcKB7cAAACtAAAAoAAAAJEAAAB9AAAAZwAAAFEAAAA8AAAAKQAAABsAAAAQAAAACAAA + AAQAAAABAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAA//8AgP//AP///wD///8A////AP///wD///8A////AP///wD///8A/62tHP8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/eXko//// + AP///wD///8A////AP///wD///8A////AP///wD///8A////AMD//wD///8A////AP///wD///8A//// + AP///wD///8A////AP/Y2A7/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv///wD///8A////AP///wD///8A////AP///wD///8A//// + AP///wD///8AAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAKPjqCmn6Kzwp+is/6forP+n6Kz/p+is/6forP+n6Kz/p+is/6fo + rP+n6Kz/p+is/6forP+n6Kz/p+is/6forP+n6Kz/p+is/6forP+n6Kz/p+is/5XPmvVokWvgOE05zRAW + EMIAAAC+AAAAvgAAAL4AAAC/AAAAvwAAAL8AAAC/AAAAvwoPC8I2SzfQZIpn4ZPMl/Wn6Kz/p+is/6fo + rP+n6Kz/p+is/6forP+n6Kz/p+is/6forP+n6Kz/p+is/6forP+n6Kz/p+is/6forP+n6Kz/p+is/6fo + rP+n6Kz/oN6l+x8sIMYAAAC4AAAAsAAAAKYAAACXAAAAhQAAAHEAAABbAAAARgAAADMAAAAiAAAAFgAA + AA0AAAAHAAAAAwAAAAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAP//AID//wD///8A////AP///wD///8A////AP///wD///8A////AP+trRz/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/3l5 + KP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wDA//8A////AP///wD///8A//// + AP///wD///8A////AP///wD/2NgO/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL///8A////AP///wD///8A////AP///wD///8A//// + AP///wD///8A////AAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAApOSpR6forPyn6Kz/p+is/6forP+n6Kz/p+is/6fo + rP+n6Kz/p+is/6forP+n6Kz/p+is/6forP+n6Kz/p+is/6forP+n6Kz/p+is/6forP+n6Kz/p+is/6fo + rP+n6Kz/mdWe94a6iu58rYDqc6B35m+bc+V5p3zphrqK7pXPmvam56v/p+is/6forP+n6Kz/p+is/6fo + rP+n6Kz/p+is/6forP+n6Kz/p+is/6forP+n6Kz/p+is/6forP+n6Kz/p+is/6forP+n6Kz/p+is/6fo + rP+n6Kz/peWq/jhNOdAAAAC9AAAAugAAALQAAACsAAAAoAAAAJAAAAB9AAAAaAAAAFMAAAA/AAAALQAA + AB4AAAATAAAACgAAAAUAAAACAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAD//wCA//8A////AP///wD///8A////AP///wD///8A////AP///wD/ra0c/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv95eSj///8A////AP///wD///8A////AP///wD///8A////AP///wD///8AwP//AP///wD///8A//// + AP///wD///8A////AP///wD///8A/9jYDv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy////AP///wD///8A////AP///wD///8A//// + AP///wD///8A////AP///wABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACl5apgp+is/qforP+n6Kz/p+is/6fo + rP+n6Kz/p+is/6forP+n6Kz/p+is/6forP+n6Kz/p+is/6forP+n6Kz/p+is/6forP+n6Kz/p+is/6fo + rP+n6Kz/p+is/6forP+n6Kz/p+is/6forP+n6Kz/p+is/6forP+n6Kz/p+is/6forP+n6Kz/p+is/6fo + rP+n6Kz/p+is/6forP+n6Kz/p+is/6forP+n6Kz/p+is/6forP+n6Kz/p+is/6forP+n6Kz/p+is/6fo + rP+n6Kz/puer/0hkStMAAAC9AAAAvQAAALsAAAC4AAAAsQAAAKcAAACaAAAAiQAAAHYAAABhAAAATAAA + ADkAAAAoAAAAGgAAABAAAAAIAAAABAAAAAEAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAA//8AgP//AP///wD///8A////AP///wD///8A////AP///wD///8A/62t + HP8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/eXko////AP///wD///8A////AP///wD///8A////AP///wD///8A////AMD//wD///8A//// + AP///wD///8A////AP///wD///8A////AP/Y2A7/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv///wD///8A////AP///wD///8A//// + AP///wD///8A////AP///wD///8AAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAKbmq2un6Kz+p+is/6fo + rP+n6Kz/p+is/6forP+n6Kz/p+is/6forP+n6Kz/p+is/6forP+n6Kz/p+is/6forP+n6Kz/p+is/6fo + rP+n6Kz/p+is/6forP+n6Kz/p+is/6forP+n6Kz/p+is/6forP+n6Kz/p+is/6forP+n6Kz/p+is/6fo + rP+n6Kz/p+is/6forP+n6Kz/p+is/6forP+n6Kz/p+is/6forP+n6Kz/p+is/6forP+n6Kz/p+is/6fo + rP+n6Kz/puer/lFwU9EAAAC4AAAAuwAAAL0AAAC9AAAAuwAAALYAAACvAAAAowAAAJUAAACEAAAAcAAA + AFsAAABGAAAANAAAACMAAAAWAAAADQAAAAcAAAADAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAP//AID//wD///8A////AP///wD///8A////AP///wD///8A//// + AP+trRz/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/3l5KP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wDA//8A//// + AP///wD///8A////AP///wD///8A////AP///wD/2NgO/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL///8A////AP///wD///8A//// + AP///wD///8A////AP///wD///8A////AAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAApeWqYKfo + rPyn6Kz/p+is/6forP+n6Kz/p+is/6forP+n6Kz/p+is/6forP+n6Kz/p+is/6forP+n6Kz/p+is/6fo + rP+n6Kz/p+is/6forP+n6Kz/p+is/6forP+n6Kz/p+is/6forP+n6Kz/p+is/6forP+n6Kz/p+is/6fo + rP+n6Kz/p+is/6forP+n6Kz/p+is/6forP+n6Kz/p+is/6forP+n6Kz/p+is/6forP+n6Kz/p+is/6fo + rP+n6Kz/puar/k1rUMQAAACsAAAAswAAALgAAAC8AAAAvQAAALwAAAC5AAAAtAAAAKwAAACgAAAAkAAA + AH4AAABqAAAAVQAAAEAAAAAuAAAAHwAAABMAAAALAAAABQAAAAIAAAABAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD//wCA//8A////AP///wD///8A////AP///wD///8A//// + AP///wD/ra0c/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv95eSj///8A////AP///wD///8A////AP///wD///8A////AP///wD///8AwP// + AP///wD///8A////AP///wD///8A////AP///wD///8A/9jYDv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy////AP///wD///8A//// + AP///wD///8A////AP///wD///8A////AP///wABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AACl5apKp+is8KforP+n6Kz/p+is/6forP+n6Kz/p+is/6forP+n6Kz/p+is/6forP+n6Kz/p+is/6fo + rP+n6Kz/p+is/6forP+n6Kz/p+is/6forP+n6Kz/p+is/6forP+n6Kz/p+is/6forP+n6Kz/p+is/6fo + rP+n6Kz/p+is/6forP+n6Kz/p+is/6forP+n6Kz/p+is/6forP+n6Kz/p+is/6forP+n6Kz/p+is/6fo + rP+n6Kz/p+is/5jTnO0FBgWaAAAAowAAAK0AAAC1AAAAugAAAL0AAAC9AAAAuwAAALgAAACyAAAAqAAA + AJsAAACLAAAAeAAAAGQAAABPAAAAOwAAACkAAAAbAAAAEAAAAAkAAAAEAAAAAQAAAAEAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA//8AgP//AP///wD///8A////AP///wD///8A//// + AP///wD///8A/62tHP8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/eXko////AP///wD///8A////AP///wD///8A////AP///wD///8A//// + AMD//wD///8A////AP///wD///8A////AP///wD///8A////AP/Y2A7/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv///wD///8A//// + AP///wD///8A////AP///wD///8A////AP///wD///8AAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAKforCmn6KzVp+is/6forP+n6Kz/p+is/6forP+n6Kz/p+is/6forP+n6Kz/p+is/6fo + rP+n6Kz/p+is/6forP+n6Kz/p+is/6forP+n6Kz/p+is/6forP+n6Kz/p+is/6forP+n6Kz/p+is/6fo + rP+n6Kz/p+is/6forP+n6Kz/p+is/6forP+n6Kz/p+is/6forP+n6Kz/p+is/6forP+n6Kz/p+is/6fo + rP+n6Kz/p+is/6forP+n6Kz/bZdwxQAAAJkAAACmAAAArwAAALYAAAC7AAAAvQAAAL0AAAC7AAAAtgAA + AK8AAAClAAAAlwAAAIUAAAByAAAAXQAAAEkAAAA1AAAAJQAAABcAAAANAAAABwAAAAMAAAABAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP//AID//wD///8A////AP///wD///8A//// + AP///wD///8A////AP+trRz/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/3l5KP///wD///8A////AP///wD///8A////AP///wD///8A//// + AP///wDA//8A////AP///wD///8A////AP///wD///8A////AP///wD/2NgO/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL///8A//// + AP///wD///8A////AP///wD///8A////AP///wD///8A////AAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAp+isCqforJmn6Kz+p+is/6forP+n6Kz/p+is/6forP+n6Kz/p+is/6fo + rP+n6Kz/p+is/6forP+n6Kz/p+is/6forP+n6Kz/p+is/6forP+n6Kz/p+is/6forP+n6Kz/p+is/6fo + rP+n6Kz/p+is/6forP+n6Kz/p+is/6forP+n6Kz/p+is/6forP+n6Kz/p+is/6forP+n6Kz/p+is/6fo + rP+n6Kz/p+is/6forP+n6Kz/p+is/6bmq/02SzelAAAAnAAAAKkAAACyAAAAuAAAALsAAAC9AAAAvQAA + ALoAAAC1AAAArAAAAKEAAACSAAAAgAAAAGwAAABXAAAAQgAAADAAAAAgAAAAFAAAAAsAAAAGAAAAAgAA + AAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD//wCA//8A////AP///wD///8A//// + AP///wD///8A////AP///wD/ra0c/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv95eSj///8A////AP///wD///8A////AP///wD///8A//// + AP///wD///8AwP//AP///wD///8A////AP///wD///8A////AP///wD///8A/9jYDv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy//// + AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wABAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAp+isQ6forNqn6Kz/p+is/6forP+n6Kz/p+is/6fo + rP+n6Kz/p+is/6forP+n6Kz/p+is/6forP+n6Kz/p+is/6forP+n6Kz/p+is/6forP+n6Kz/p+is/6fo + rP+n6Kz/p+is/6forP+n6Kz/p+is/6forP+n6Kz/p+is/6forP+n6Kz/p+is/6forP+n6Kz/p+is/6fo + rP+n6Kz/p+is/6forP+n6Kz/p+is/6forP+n6Kz/mdWe6woOCpUAAACgAAAArAAAALQAAAC5AAAAvAAA + AL0AAAC8AAAAuAAAALIAAACpAAAAnQAAAI0AAAB5AAAAZQAAAFAAAAA8AAAAKwAAABwAAAAQAAAACQAA + AAQAAAABAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA//8AgP//AP///wD///8A//// + AP///wD///8A////AP///wD///8A/62tHP8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/eXko////AP///wD///8A////AP///wD///8A//// + AP///wD///8A////AMD//wD///8A////AP///wD///8A////AP///wD///8A////AP/Y2A7/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8AAQAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACn6KwGp+isc6forO+n6Kz/p+is/6fo + rP+n6Kz/p+is/6forP+n6Kz/p+is/6forP+n6Kz/p+is/6forP+n6Kz/p+is/6forP+n6Kz/p+is/6fo + rP+n6Kz/p+is/6forP+n6Kz/p+is/6forP+n6Kz/p+is/6forP+n6Kz/p+is/6forP+n6Kz/p+is/6bm + q+6m5qvpp+is/6forP+n6Kz/p+is/6forP+n6Kz/p+is/6forP95p3zKAAAAlQAAAKMAAACvAAAAtgAA + ALsAAAC9AAAAvQAAALsAAAC3AAAAsAAAAKYAAACYAAAAhwAAAHMAAABeAAAASQAAADYAAAAlAAAAGAAA + AA4AAAAHAAAABAAAAAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP//AID//wD///8A//// + AP///wD///8A////AP///wD///8A////AP+trRz/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/3l5KP///wD///8A////AP///wD///8A//// + AP///wD///8A////AP///wDA//8A////AP///wD///8A////AP///wD///8A////AP///wD/2NgO/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AAEAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACn6KwPp+isc6fo + rOCn6Kz/p+is/6forP+n6Kz/p+is/6forP+n6Kz/p+is/6forP+n6Kz/p+is/6forP+n6Kz/p+is/6fo + rP+n6Kz/p+is/6forP+n6Kz/p+is/6forP+n6Kz/p+is/6forP+n6Kz/p+is/6forP+n6Kz/puar6ZzZ + oYZNa1Aai8KQPKforPqn6Kz/p+is/6forP+n6Kz/p+is/6forP+n6Kz/p+is/kNeRagAAACaAAAApwAA + ALEAAAC4AAAAuwAAAL0AAAC9AAAAugAAALUAAACtAAAAogAAAJMAAACBAAAAbQAAAFgAAABDAAAAMQAA + ACEAAAAUAAAACwAAAAYAAAACAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD//wCA//8A//// + AP///wD///8A////AP///wD///8A////AP///wD/ra0c/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv95eSj///8A////AP///wD///8A//// + AP///wD///8A////AP///wD///8AwP//AP///wD///8A////AP///wD///8A////AP///wD///8A/9jY + Dv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wABAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AACn6KwEp+isVaforMCn6Kz8p+is/6forP+n6Kz/p+is/6forP+n6Kz/p+is/6forP+n6Kz/p+is/6fo + rP+n6Kz/p+is/6forP+n6Kz/p+is/6forP+n6Kz/p+is/6forP+n6Kz/p+is/6forP2k5KnDmtafZT9X + QRAAAAAIAAAABwAAAAWj46h/p+is/6forP+n6Kz/p+is/6forP+n6Kz/p+is/6forP+d2qLxExoUlgAA + AJ4AAACrAAAAswAAALkAAAC8AAAAvgAAALwAAAC5AAAAswAAAKoAAACdAAAAjgAAAHsAAABmAAAAUQAA + AD0AAAArAAAAHAAAABEAAAAKAAAABAAAAAIAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA//8AgP// + AP///wD///8A////AP///wD///8A////AP///wD///8A/62tHP8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/eXko////AP///wD///8A//// + AP///wD///8A////AP///wD///8A////AMD//wD///8A////AP///wD///8A////AP///wD///8A//// + AP/Y2A7/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8AAQAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAp+isFaforGCn6Kyup+is9KforP+n6Kz/p+is/6forP+n6Kz/p+is/6fo + rP+n6Kz/p+is/6forP+n6Kz/p+is/6forP+n6Kz/p+is/6forP+n6KzzpOSpuaHgpnOJvo0hAAAABQAA + AAQAAAAEAAAAAgAAAAEAAAABfa6BBKbnq8mn6Kz/p+is/6forP+n6Kz/p+is/6forP+n6Kz/p+is/4K1 + htIAAACUAAAAowAAAK4AAAC1AAAAuwAAAL0AAAC9AAAAuwAAALgAAACwAAAApgAAAJkAAACIAAAAdAAA + AF8AAABKAAAANwAAACYAAAAZAAAADgAAAAcAAAAEAAAAAQAAAAEAAAAAAAAAAAAAAAAAAAAAAAAAAP// + AID//wD///8A////AP///wD///8A////AP///wD///8A////AP+trRz/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/3l5KP///wD///8A//// + AP///wD///8A////AP///wD///8A////AP///wDA//8A////AP///wD///8A////AP///wD///8A//// + AP///wD/2NgO/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A//// + AAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAKforASn6Kwsp+isWaforIen6Ky0p+is0qfo + rOen6Kz1p+is/6forP+n6Kzyp+is6qbnq9Sm56u1peWqlqTjqWeh4KY3b5tzCQAAAAIAAAACAAAAAQAA + AAEAAAABAAAAAQAAAAAAAAAAAAAAAAAAAAGi4qcmp+is9KforP+n6Kz/p+is/6forP+n6Kz/p+is/6fo + rP+n6Kz/UXBTsAAAAJkAAACmAAAAsQAAALgAAAC7AAAAvQAAAL0AAAC7AAAAtQAAAK4AAACjAAAAlAAA + AIIAAABtAAAAWAAAAEQAAAAxAAAAIQAAABUAAAAMAAAABgAAAAMAAAABAAAAAAAAAAAAAAAAAAAAAAAA + AAD//wCA//8A////AP///wD///8A////AP///wD///8A////AP///wD/ra0c/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv95eSj///8A//// + AP///wD///8A////AP///wD///8A////AP///wD///8AwP//AP///wD///8A////AP///wD///8A//// + AP///wD///8A/9jYDv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy////AP///wD///8A////AP///wD///8A////AP///wD///8A//// + AP///wABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAabmq2un6Kz/p+is/6forP+n6Kz/p+is/6fo + rP+n6Kz/p+is/6HgpvYcJhyZAAAAnQAAAKoAAACzAAAAuQAAALwAAAC+AAAAvAAAALkAAACzAAAAqgAA + AJ4AAACOAAAAfAAAAGcAAABSAAAAPQAAACwAAAAdAAAAEgAAAAoAAAAEAAAAAgAAAAEAAAAAAAAAAAAA + AAAAAAAA//8AgP//AP///wD///8A////AP///wD///8A////AP///wD///8A/62tHP8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/eXko//// + AP///wD///8A////AP///wD///8A////AP///wD///8A////AMD//wD///8A////AP///wD///8A//// + AP///wD///8A////AP/Y2A7/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv///wD///8A////AP///wD///8A////AP///wD///8A//// + AP///wD///8AAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABUdFYCpueruaforP+n6Kz/p+is/6fo + rP+n6Kz/p+is/6forP+n6Kz/i8GP2wECAZMAAACiAAAArQAAALUAAAC7AAAAvQAAAL0AAAC7AAAAuAAA + ALEAAACnAAAAmgAAAIgAAAB1AAAAYQAAAEwAAAA4AAAAJwAAABkAAAAPAAAACAAAAAQAAAABAAAAAQAA + AAAAAAAAAAAAAP//AID//wD///8A////AP///wD///8A////AP///wD///8A////AP+trRz/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/3l5 + KP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wDA//8A////AP///wD///8A//// + AP///wD///8A////AP///wD/2NgO/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL///8A////AP///wD///8A////AP///wD///8A//// + AP///wD///8A////AAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAKHgphun6Kztp+is/6fo + rP+n6Kz/p+is/6forP+n6Kz/p+is/6forP9eg2G3AAAAmAAAAKYAAACwAAAAtwAAALsAAAC9AAAAvQAA + ALsAAAC1AAAArgAAAKMAAACUAAAAgwAAAG8AAABaAAAARQAAADIAAAAiAAAAFgAAAA0AAAAHAAAAAwAA + AAEAAAAAAAAAAAAAAAD//wCA//8A////AP///wD///8A////AP///wD///8A////AP///wD/ra0c/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv95eSj///8A////AP///wD///8A////AP///wD///8A////AP///wD///8AwP//AP///wD///8A//// + AP///wD///8A////AP///wD///8A/9jYDv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy////AP///wD///8A////AP///wD///8A//// + AP///wD///8A////AP///wABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABpeWqWKfo + rP+n6Kz/p+is/6forP+n6Kz/p+is/6forP+n6Kz/pOOp+SY1J50AAACdAAAAqQAAALIAAAC4AAAAvAAA + AL0AAAC8AAAAuQAAALQAAACrAAAAnwAAAI8AAAB9AAAAaAAAAFMAAABAAAAALgAAAB8AAAATAAAACgAA + AAUAAAACAAAAAQAAAAAAAAAA//8AgP//AP///wD///8A////AP///wD///8A////AP///wD///8A/62t + HP8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/eXko////AP///wD///8A////AP///wD///8A////AP///wD///8A////AMD//wD///8A//// + AP///wD///8A////AP///wD///8A////AP/Y2A7/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv///wD///8A////AP///wD///8A//// + AP///wD///8A////AP///wD///8AAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAGm5quop+is/6forP+n6Kz/p+is/6forP+n6Kz/p+is/6forP+RypbjAwUDkwAAAKEAAACsAAAAtQAA + ALoAAAC9AAAAvQAAALsAAAC4AAAAsQAAAKgAAACaAAAAigAAAHYAAABiAAAATQAAADoAAAAoAAAAGgAA + ABAAAAAJAAAABAAAAAEAAAABAAAAAP//AID//wD///8A////AP///wD///8A////AP///wD///8A//// + AP+trRz/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/3l5KP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wDA//8A//// + AP///wD///8A////AP///wD///8A////AP///wD/2NgO/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL///8A////AP///wD///8A//// + AP///wD///8A////AP///wD///8A////AAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAntujEqforOSn6Kz/p+is/6forP+n6Kz/p+is/6forP+n6Kz/p+is/2qTbcAAAACXAAAApQAA + AK8AAAC3AAAAuwAAAL0AAAC9AAAAuwAAALYAAACvAAAApAAAAJYAAACFAAAAcAAAAFwAAABHAAAANAAA + ACQAAAAXAAAADQAAAAcAAAADAAAAAQAAAAD//wCA//8A////AP///wD///8A////AP///wD///8A//// + AP///wD/ra0c/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv95eSj///8A////AP///wD///8A////AP///wD///8A////AP///wD///8AwP// + AP///wD///8A////AP///wD///8A////AP///wD///8A/9jYDv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy////AP///wD///8A//// + AP///wD///8A////AP///wD///8A////AP///wABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAGk5KlHp+is/qforP+n6Kz/p+is/6forP+n6Kz/p+is/6forP+l5ar8M0c1oQAA + AJwAAACpAAAAsgAAALgAAAC7AAAAvQAAALwAAAC6AAAAtAAAAKwAAACgAAAAkQAAAH8AAABqAAAAVQAA + AEEAAAAvAAAAHwAAABMAAAALAAAABgAAAAIAAAAB//8AgP//AP///wD///8A////AP///wD///8A//// + AP///wD///8A/62tHP8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/eXko////AP///wD///8A////AP///wD///8A////AP///wD///8A//// + AMD//wD///8A////AP///wD///8A////AP///wD///8A////AP/Y2A7/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv///wD///8A//// + AP///wD///8A////AP///wD///8A////AP///wD///8AAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAabmq5Wn6Kz/p+is/6forP+n6Kz/p+is/6forP+n6Kz/p+is/5fS + nOkJDQmUAAAAoAAAAKwAAAC0AAAAuQAAALwAAAC9AAAAvAAAALgAAACyAAAAqQAAAJwAAACLAAAAeQAA + AGQAAABPAAAAOwAAACoAAAAcAAAAEAAAAAkAAAAEAAAAAf//AID//wD///8A////AP///wD///8A//// + AP///wD///8A////AP+trRz/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/3l5KP///wD///8A////AP///wD///8A////AP///wD///8A//// + AP///wDA//8A////AP///wD///8A////AP///wD///8A////AP///wD/2NgO/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL///8A//// + AP///wD///8A////AP///wD///8A////AP///wD///8A////AAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACY05wLp+is2aforP+n6Kz/p+is/6forP+n6Kz/p+is/6fo + rP+n6Kz/daN5yAAAAJUAAACjAAAArwAAALYAAAC7AAAAvQAAAL0AAAC7AAAAtwAAAK8AAAClAAAAlwAA + AIYAAABzAAAAXgAAAEkAAAA2AAAAJQAAABgAAAAOAAAABwAAAAP//wCA//8A////AP///wD///8A//// + AP///wD///8A////AP///wD/ra0c/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv95eSj///8A////AP///wD///8A////AP///wD///8A//// + AP///wD///8AwP//AP///wD///8A////AP///wD///8A////AP///wD///8A/9jYDv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy//// + AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wABAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAaTjqTin6Kz7p+is/6forP+n6Kz/p+is/6fo + rP+n6Kz/p+is/6bnq/5AWUKnAAAAmgAAAKcAAACxAAAAuAAAALsAAAC9AAAAvQAAALoAAAC1AAAArQAA + AKEAAACSAAAAgAAAAGwAAABXAAAAQwAAADAAAAAgAAAAFAAAAAsAAAAG/f0Agf//AP///wD///8A//// + AP///wD///8A////AP///wD///8A/62tHP8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/eXko////AP///wD///8A////AP///wD///8A//// + AP///wD///8A////AMD//wD///8A////AP///wD///8A////AP///wD///8A////AP/Y2A7/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8AAQAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABpuarg6forP+n6Kz/p+is/6fo + rP+n6Kz/p+is/6forP+n6Kz/nNmh7xAWEJUAAACfAAAAqwAAALMAAAC5AAAAvAAAAL0AAAC8AAAAuQAA + ALMAAACpAAAAnQAAAI0AAAB6AAAAZgAAAFAAAAA9AAAAKwAAABwAAAARAAAACvv7AIL//wD///8A//// + AP///wD///8A////AP///wD///8A////AP+trRz/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/3l5KP///wD///8A////AP///wD///8A//// + AP///wD///8A////AP///wDA//8A////AP///wD///8A////AP///wD///8A////AP///wD/2NgO/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AAEAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAIvCkAam56vMp+is/6fo + rP+n6Kz/p+is/6forP+n6Kz/p+is/6forP+AsYTPAAAAlAAAAKMAAACuAAAAtQAAALsAAAC9AAAAvQAA + ALsAAAC3AAAAsAAAAKYAAACYAAAAiAAAAHQAAABfAAAASgAAADcAAAAlAAAAGAAAAA75+QCD//8A//// + AP///wD///8A////AP///wD///8A////AP///wD/ra0c/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv95eSj///8A////AP///wD///8A//// + AP///wD///8A////AP///wD///8AwP//AP///wD///8A////AP///wD///8A////AP///wD///8A/9jY + Dv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wABAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABo+OoK6fo + rPan6Kz/p+is/6forP+n6Kz/p+is/6forP+n6Kz/p+is/01rUK0AAACZAAAApgAAALEAAAC4AAAAuwAA + AL0AAAC9AAAAuwAAALUAAACtAAAAogAAAJQAAACCAAAAbQAAAFgAAABDAAAAMQAAACEAAAAV9PQAhv// + AP///wD///8A////AP///wD///8A////AP///wD///8A/62tHP8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/eXko////AP///wD///8A//// + AP///wD///8A////AP///wD///8A////AMD//wD///8A////AP///wD///8A////AP///wD///8A//// + AP/Y2A7/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8AAQAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAGm5qtxp+is/6forP+n6Kz/p+is/6forP+n6Kz/p+is/6forP+g3qX0GiMamAAAAJ4AAACqAAAAswAA + ALkAAAC8AAAAvgAAALwAAAC5AAAAswAAAKoAAACeAAAAjgAAAHsAAABnAAAAUgAAAD0AAAArAAAAHe7u + AIn//wD///8A////AP///wD///8A////AP///wD///8A////AP+trRz/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/3l5KP///wD///8A//// + AP///wD///8A////AP///wD///8A////AP///wDA//8A////AP///wD///8A////AP///wD///8A//// + AP///wD/2NgO/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A//// + AAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAVHRWAqbnq76n6Kz/p+is/6forP+n6Kz/p+is/6forP+n6Kz/p+is/4i9jNgAAACUAAAAogAA + AK0AAAC1AAAAuwAAAL0AAAC9AAAAuwAAALgAAACxAAAApgAAAJkAAACIAAAAdQAAAGAAAABLAAAANwAA + ACfp6QCM//8A////AP///wD///8A////AP///wD///8A////AP///wD/ra0c/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv95eSj///8A//// + AP///wD///8A////AP///wD///8A////AP///wD///8AwP//AP///wD///8A////AP///wD///8A//// + AP///wD///8A/9jYDv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy////AP///wD///8A////AP///wD///8A////AP///wD///8A//// + AP///wABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAACi4acfp+is76forP+n6Kz/p+is/6forP+n6Kz/p+is/6forP+n6Kz/Wn1ctgAA + AJgAAACmAAAAsAAAALcAAAC7AAAAvQAAAL0AAAC7AAAAtQAAAK4AAACjAAAAlAAAAIIAAABuAAAAWQAA + AEUAAAAy4eEAkf//AP///wD///8A////AP///wD///8A////AP///wD///8A/62tHP8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/eXko//// + AP///wD///8A////AP///wD///8A////AP///wD///8A////AMD//wD///8A////AP///wD///8A//// + AP///wD///8A////AP/Y2A7/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv///wD///8A////AP///wD///8A////AP///wD///8A//// + AP///wD///8AAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAaXlql+n6Kz/p+is/6forP+n6Kz/p+is/6forP+n6Kz/p+is/6Pj + qPgjMSScAAAAnQAAAKkAAACzAAAAuQAAALwAAAC9AAAAvAAAALkAAACzAAAAqwAAAJ8AAACPAAAAfAAA + AGgAAABTAAAAP9raAJb//wD///8A////AP///wD///8A////AP///wD///8A////AP+trRz/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/3l5 + KP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wDA//8A////AP///wD///8A//// + AP///wD///8A////AP///wD/2NgO/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL///8A////AP///wD///8A////AP///wD///8A//// + AP///wD///8A////AAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABpuerraforP+n6Kz/p+is/6forP+n6Kz/p+is/6fo + rP+n6Kz/kMiU4AMFA5MAAAChAAAArQAAALUAAAC6AAAAvQAAAL0AAAC7AAAAuAAAALEAAACnAAAAmgAA + AIoAAAB2AAAAYQAAAE3Q0ACd//8A////AP///wD///8A////AP///wD///8A////AP///wD/ra0c/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv95eSj///8A////AP///wD///8A////AP///wD///8A////AP///wD///8AwP//AP///wD///8A//// + AP///wD///8A////AP///wD///8A/9jYDv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy////AP///wD///8A////AP///wD///8A//// + AP///wD///8A////AP///wABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAJ7coxSn6Kznp+is/6forP+n6Kz/p+is/6fo + rP+n6Kz/p+is/6forP9nj2q9AAAAlwAAAKUAAACvAAAAtwAAALsAAAC9AAAAvQAAALsAAAC2AAAArwAA + AKMAAACVAAAAhAAAAHAAAABbyMgAo///AP///wD///8A////AP///wD///8A////AP///wD///8A/62t + HP8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/eXko////AP///wD///8A////AP///wD///8A////AP///wD///8A////AMD//wD///8A//// + AP///wD///8A////AP///wD///8A////AP/Y2A7/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv///wD///8A////AP///wD///8A//// + AP///wD///8A////AP///wD///8AAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABpeWqTKforP6n6Kz/p+is/6fo + rP+n6Kz/p+is/6forP+n6Kz/peWq+y9CMZ8AAACcAAAAqQAAALIAAAC4AAAAvAAAAL0AAAC8AAAAuQAA + ALQAAACsAAAAoAAAAJEAAAB/AAAAasDAAKr//wD///8A////AP///wD///8A////AP///wD///8A//// + AP+trRz/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/3l5KP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wDA//8A//// + AP///wD///8A////AP///wD///8A////AP///wD/2NgO/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL///8A////AP///wD///8A//// + AP///wD///8A////AP///wD///8A////AAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAGm5qubp+is/6fo + rP+n6Kz/p+is/6forP+n6Kz/p+is/6forP+X0ZvnBwkHlAAAAKAAAACsAAAAtAAAALoAAAC8AAAAvQAA + ALsAAAC4AAAAsgAAAKkAAACcAAAAiwAAAHm3twCy//8A////AP///wD///8A////AP///wD///8A//// + AP///wD/ra0c/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv95eSj///8A////AP///wD///8A////AP///wD///8A////AP///wD///8AwP// + AP///wD///8A////AP///wD///8A////AP///wD///8A/9jYDv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy////AP///wD///8A//// + AP///wD///8A////AP///wD///8A////AP///wABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAmtafDafo + rNyn6Kz/p+is/6forP+n6Kz/p+is/6forP+n6Kz/p+is/3KedcYAAACWAAAApAAAAK8AAAC2AAAAuwAA + AL0AAAC9AAAAuwAAALcAAACvAAAApQAAAJcAAACFsLAAuf//AP///wD///8A////AP///wD///8A//// + AP///wD///8A/62tHP8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/eXko////AP///wD///8A////AP///wD///8A////AP///wD///8A//// + AMD//wD///8A////AP///wD///8A////AP///wD///8A////AP/Y2A7/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv///wD///8A//// + AP///wD///8A////AP///wD///8A////AP///wD///8AAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAGk5Kk8p+is/KforP+n6Kz/p+is/6forP+n6Kz/p+is/6forP+m56v9PFM9pQAAAJoAAACoAAAAsQAA + ALgAAAC7AAAAvQAAAL0AAAC6AAAAtQAAAKwAAAChAAAAkaurAL///wD///8A////AP///wD///8A//// + AP///wD///8A////AP+trRz/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/3l5KP///wD///8A////AP///wD///8A////AP///wD///8A//// + AP///wDA//8A////AP///wD///8A////AP///wD///8A////AP///wD/2NgO/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL///8A//// + AP///wD///8A////AP///wD///8A////AP///wD///8A////AAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAabmq4in6Kz/p+is/6forP+n6Kz/p+is/6forP+n6Kz/p+is/5vYoO0OEw6UAAAAnwAA + AKsAAAC0AAAAuQAAALwAAAC9AAAAvAAAALgAAACyAAAAqQAAAJympgDF//8A////AP///wD///8A//// + AP///wD///8A////AP///wD/ra0c/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv95eSj///8A////AP///wD///8A////AP///wD///8A//// + AP///wD///8AwP//AP///wD///8A////AP///wD///8A////AP///wD///8A/9jYDv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy//// + AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wABAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAACPx5QHpuer0aforP+n6Kz/p+is/6forP+n6Kz/p+is/6forP+n6Kz/fa6BzgAA + AJQAAACjAAAArgAAALUAAAC7AAAAvQAAAL0AAAC7AAAAtwAAAK8AAACkoqIAyv//AP///wD///8A//// + AP///wD///8A////AP///wD///8A/62tHP8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/eXko////AP///wD///8A////AP///wD///8A//// + AP///wD///8A////AMD//wD///8A////AP///wD///8A////AP///wD///8A////AP/Y2A7/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8AAQAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAaPjqC6n6Kz4p+is/6forP+n6Kz/p+is/6forP+n6Kz/p+is/6fo + rP5JZkyrAAAAmgAAAKcAAACxAAAAuAAAALsAAAC9AAAAvQAAALoAAACzAAAAqZ+fAM3//wD///8A//// + AP///wD///8A////AP///wD///8A////AP+trRz/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/3l5KP///wD///8A////AP///wD///8A//// + AP///wD///8A////AP///wDA//8A////AP///wD///8A////AP///wD///8A////AP///wD/2NgO/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AAEAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABpuardaforP+n6Kz/p+is/6forP+n6Kz/p+is/6fo + rP+n6Kz/ntyj8xUdFpYAAACeAAAAqgAAALMAAAC5AAAAvAAAALwAAAC7AAAAtQAAAKyengDP//8A//// + AP///wD///8A////AP///wD///8A////AP///wD/ra0c/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv95eSj///8A////AP///wD///8A//// + AP///wD///8A////AP///wD///8AwP//AP///wD///8A////AP///wD///8A////AP///wD///8A/9jY + Dv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wABAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAH2ugQSm56vCp+is/6forP+n6Kz/p+is/6fo + rP+n6Kz/p+is/6forP+Gu4rWAAAAlAAAAKMAAACtAAAAtQAAALkAAAC7AAAAuAAAALMAAACqnp4Azv// + AP///wD///8A////AP///wD///8A////AP///wD///8A/62tHP8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/eXko////AP///wD///8A//// + AP///wD///8A////AP///wD///8A////AMD//wD///8A////AP///wD///8A////AP///wD///8A//// + AP/Y2A7/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8AAQAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABouKnIqforPKn6Kz/p+is/6fo + rP+n6Kz/p+is/6forP+n6Kz/p+is/1Z4WbMAAACXAAAApQAAAK4AAACzAAAAtQAAALMAAACuAAAAo6Gh + AMv//wD///8A////AP///wD///8A////AP///wD///8A////AP+trRz/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/3l5KP///wD///8A//// + AP///wD///8A////AP///wD///8A////AP///wDA//8A////AP///wD///8A////AP///wD///8A//// + AP///wD/2NgO/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A//// + AAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAGl5apjp+is/6fo + rP+n6Kz/p+is/6forP+n6Kz/p+is/6forP+i4af3IC0hmAAAAJkAAACjAAAAqQAAAKwAAACpAAAAowAA + AJmmpgDF//8A////AP///wD///8A////AP///wD///8A////AP///wD/ra0c/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv95eSj///8A//// + AP///wD///8A////AP///wD///8A////AP///wD///8AwP//AP///wD///8A////AP///wD///8A//// + AP///wD///8A/9jYDv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy////AP///wD///8A////AP///wD///8A////AP///wD///8A//// + AP///wABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAabn + q7Kn6Kz/p+is/6forP+n6Kz/p+is/6forP+n6Kz/p+is/4/Gk90BAgGLAAAAlQAAAJwAAACeAAAAnAAA + AJUAAACKrKwAvv//AP///wD///8A////AP///wD///8A////AP///wD///8A/62tHP8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/eXko//// + AP///wD///8A////AP///wD///8A////AP///wD///8A////AMD//wD///8A////AP///wD///8A//// + AP///wD///8A////AP/Y2A7/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv///wD///8A////AP///wD///8A////AP///wD///8A//// + AP///wD///8AAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AACg3qUYp+is6qforP+n6Kz/p+is/6forP+n6Kz/p+is/6forP+n6Kz/Z5BrswAAAIUAAACLAAAAjQAA + AIoAAACDAAAAd7S0ALX//wD///8A////AP///wD///8A////AP///wD///8A////AP+trRz/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/3l5 + KP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wDA//8A////AP///wD///8A//// + AP///wD///8A////AP///wD/2NgO/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL///8A////AP///wD///8A////AP///wD///8A//// + AP///wD///8A////AAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAaXlqlGn6Kz/p+is/6forP+n6Kz/p+is/6forP+n6Kz/p+is/6TkqfoyRjSIAAAAdwAA + AHkAAAB2AAAAbgAAAGO0tACg//8A////AP///wD///8A////AP///wD///8A////AP///wD/uLgZ/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv95eSj///8A////AP///wD///8A////AP///wD///8A////AP///wD///8AwP//AP///wD///8A//// + AP///wD///8A////AP///wD///8A////AP8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/eXko////AP///wD///8A////AP///wD///8A//// + AP///wD///8A////AMQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAABpuaroKforP+n6Kz/p+is/6forP+n6Kz/p+is/6forP+n6Kz/mdSd3gkM + CWQAAABiAAAAXgAAAFgAAABNgIAAaP//AP///wD///8A////AP///wD///8A////AP///wD///8A/+Li + Cf8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/ra0c////AP///wD///8A////AP///wD///8A////AP///wD///8A////AIT//wDH//8A//// + AP///wD///8A////AP///wD///8A////AP///wD/h4cl/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/7i4Gf///wD///8A////AP///wD///8A//// + AP///wD///8A////AP///wCHAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAJzZoQ+n6Kzgp+is/6forP+n6Kz/p+is/6forP+n6Kz/p+is/6fo + rP+CtYalAAAASgAAAEcAAABAAAAAOAAAAC7+/gD4//8A////AP///wD///8A////AP///wD///8A//// + AP///wD/R0cw/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/+LiCf///wD///8A////AP///wD///8A////AP///wD///8A////AP///wBH//8Ai/// + AP///wD///8A////AP///wD///8A////AP///wD///8A/8PDFf8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/0dHMP/29gL///8A////AP///wD///8A//// + AP///wD///8A////AP///wD///8ASwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABpOSpQaforP2n6Kz/p+is/6forP+n6Kz/p+is/6fo + rP+n6Kz/puer/F+EYl8AAAAyAAAALQAAACYAAAAf9/cAwf//AP///wD///8A////AP///wD///8A//// + AP///wD///8A/6GhH/8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/1paLf///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8AC/// + AE///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD/Wlot/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv+trRz///8A////AP///wD///8A//// + AP///wD///8A////AP///wD///8A////AA8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAGm5quOp+is/6forP+n6Kz/p+is/6fo + rP+n6Kz/p+is/6forP+g36XIAAAAIQAAAB0AAAAYAAAAE/LyAIb//wD///8A////AP///wD///8A//// + AP///wD///8A////AP/29gL/R0cw/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv/DwxX///8A////AP///wD///8A////AP///wD///8A////AP///wD///8AzgAA + AAD//wAP//8A////AP///wD///8A////AP///wD///8A////AP///wD///8A/9jYDv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv9qair/9vYC////AP///wD///8A//// + AP///wD///8A////AP///wD///8A////AM4AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAlc+ZCaforNSn6Kz/p+is/6fo + rP+n6Kz/p+is/6forP+g36WuT25SJgAAABMAAAAQAAAADQAAAArs7ABE//8A////AP///wD///8A//// + AP///wD///8A////AP///wD///8A/7i4Gf8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv95eSj///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A//// + AI4AAAAAAAAAAP//AL7//wD///8A////AP///wD///8A////AP///wD///8A////AP///wD/oaEf/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv9HRzD/4uIJ////AP///wD///8A//// + AP///wD///8A////AP///wD///8A////AP///wB/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAGk46kyp+is+afo + rP+n6Kz/p+is/6bnq+yb159cAAAACwAAAAoAAAAKAAAACAAAAAcAAAAEAAAAA///AP7//wD///8A//// + AP///wD///8A////AP///wD///8A////AP///wD/lZUi/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv9HRzD/9vYC////AP///wD///8A////AP///wD///8A////AP///wD///8A//// + AP///wA/AAAAAAAAAAD//wBv//8A////AP///wD///8A////AP///wD///8A////AP///wD///8A//// + AP+VlSL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv9HRzD/4uIJ////AP///wD///8A//// + AP///wD///8A////AP///wD///8A////AP///wD///8AHwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAKbm + q3yn6Kz/p+is/6bnq66NxZIaAAAABAAAAAQAAAAEAAAABAAAAAMAAAACAAAAAQAAAAH//wCe//8A//// + AP///wD///8A////AP///wD///8A////AP///wD///8A////AP+VlSL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv9aWi3/4uIJ////AP///wD///8A////AP///wD///8A////AP///wD///8A//// + AP///wDuAAAAAAAAAAAAAAAA//8ABf//AO7//wD///8A////AP///wD///8A////AP///wD///8A//// + AP///wD///8A/8PDFf9HRzD/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv95eSj/9vYC////AP///wD///8A//// + AP///wD///8A////AP///wD///8A////AP///wD///8AlAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AACn6KwDp+istqXlql0AAAABAAAAAQAAAAEAAAABAAAAAQAAAAEAAAABAAAAAQAAAAAAAAAA//8ANP// + AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A/62tHP8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv+HhyX/9vYC////AP///wD///8A////AP///wD///8A////AP///wD///8A//// + AP///wD///8AhAAAAAAAAAAAAAAAAAAAAAD//wCE//8A////AP///wD///8A////AP///wD///8A//// + AP///wD///8A////AP///wD/7OwF/5WVIv9HRzD/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/3l5KP/Y2A7///8A////AP///wD///8A//// + AP///wD///8A////AP///wD///8A////AP///wD///8A////ACQAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAD//wCU//8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD/7OwF/5WV + Iv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy + Mv8yMjL/MjIy/3l5KP/Y2A7///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A//// + AP///wD///8A1///AAUAAAAAAAAAAAAAAAAAAAAAAAAAAP//AL///wD///8A////AP///wD///8A//// + AP///wD///8A////AP///wD///8A////AP///wD/9vYC/87OEv+trRz/ra0c/62tHP+trRz/ra0c/62t + HP+trRz/ra0c/62tHP+trRz/ra0c/62tHP+trRz/ra0c/62tHP+trRz/ra0c/62tHP+trRz/ra0c/62t + HP+trRz/ra0c/62tHP+trRz/ra0c/62tHP+trRz/w8MV/+zsBf///wD///8A////AP///wD///8A//// + AP///wD///8A////AP///wD///8A////AP///wD///8A////AIcAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAA//8AFf//AOf//wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A//// + AP///wD/9vYC/87OEv+trRz/ra0c/62tHP+trRz/ra0c/62tHP+trRz/ra0c/62tHP+trRz/ra0c/62t + HP+trRz/ra0c/62tHP+trRz/ra0c/62tHP+trRz/ra0c/62tHP+trRz/ra0c/62tHP+trRz/ra0c/62t + HP+trRz/w8MV/+zsBf///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A//// + AP///wD///8A////AGQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD//wA0//8A////AP///wD///8A//// + AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A//// + AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A//// + AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A//// + AP///wD///8A////AP///wD///8A////AP///wD///8A////AMEAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAD//wBQ//8A////AP///wD///8A////AP///wD///8A////AP///wD///8A//// + AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A//// + AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A//// + AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A//// + AP///wD///8A////AJ8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP//AG///wD///8A//// + AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A//// + AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A//// + AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A//// + AP///wD///8A////AP///wD///8A////AP///wD///8A////AOn//wAqAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAP//AIr//wD///8A////AP///wD///8A////AP///wD///8A//// + AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A//// + AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A//// + AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A//// + AP///wD///8A////ANn//wAIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA//8Aqf// + AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A//// + AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A//// + AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A//// + AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wBKAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA//8Auf//AP///wD///8A////AP///wD///8A//// + AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A//// + AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A//// + AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A//// + AP///wD///8A////AP///wA4AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAD//wC5//8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A//// + AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A//// + AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A//// + AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wBKAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD//wC5//8A////AP///wD///8A//// + AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A//// + AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A//// + AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A//// + AP///wD///8A////APn//wBKAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAP//AH///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A//// + AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A//// + AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A//// + AP///wD///8A////AP///wD///8A////AP///wD///8A////ANn//wA4AAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP//AJn//wD///8A//// + AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A//// + AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A//// + AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A//// + AP///wD///8A////AMn//wAqAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAA//8ARP//ANf//wD///8A////AP///wD///8A////AP///wD///8A//// + AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A//// + AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A//// + AP///wD///8A////AP///wD///8A////AP///wD///8A////AJ///wAIAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA//8AX/// + APb//wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A//// + AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A//// + AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A//// + AP///wD///8A////AI8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD//wAF//8Al///AP///wD///8A////AP///wD///8A//// + AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A//// + AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A//// + AP///wD///8A////AP///wD///8A////AP///wD///8Azv//AGQAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAD//wAk//8ApP//AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A//// + AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A//// + AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A//// + AP///wD///8Avv//AFQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD//wBE//8Arv//AP///wD///8A//// + AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A//// + AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A//// + AP///wD///8A////AP///wD///8A////AP///wDO//8AZAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAD//wBE//8Arv//AP///wD///8A////AP///wD///8A////AP///wD///8A//// + AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A//// + AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A//// + AP///wDO//8AZAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD//wAf//8AX/// + AJv//wDX//8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A//// + AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A//// + AP///wD///8A////AP///wDn//8Aq///AG///wAvAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD//wAf//8AX///AJv//wDX//8A////AP///wD///8A//// + AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A//// + AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wDn//8Aq/// + AG///wAvAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAP//ABX//wBR//8AgP//AID//wCA//8AgP//AID//wCA//8AgP//AID//wCA//8AgP// + AID//wCA//8AgP//AID//wCA//8AgP//AID//wCA//8AgP//AID//wCA//8AgP//AID//wCA//8AgP// + AID//wCA//8AgP//AGH//wAlAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP//ABX//wBR//8AgP// + AID//wCA//8AgP//AID//wCA//8AgP//AID//wCA//8AgP//AID//wCA//8AgP//AID//wCA//8AgP// + AID//wCA//8AgP//AID//wCA//8AgP//AID//wCA//8AgP//AID//wCA//8AgP//AGH//wAlAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAA///////////////////AAAAH/////////////////////////////////////4AAAAP///// + ////////////////////////////////AAAAAf////////////////////////////////////4AAAAA + /////////////////////////////////////AAAAAB////////////////////////////////////4 + AAAAAD////////////////////////////////////AAAAAAH/////////////////////////////// + ////4AAAAAAP///////////////////////////////////AAAAAAAf///////////////////////// + /////////4AAAAAAA///////////////////////////////////AAAAAAAB//////////////////// + //////////////4AAAAAAAD//////////////////////////////////AAAAAAAAH////////////// + ///////////////////4AAAAAAAAP/////////////////////////////////AAAAAAAAAf//////// + ////////////////////////4AAAAAAAAA/////////////////////////////////AAAAAAAAAB/// + /////////////////////////////4AAAAAAAAAD////////////////////////////////AAAAAAAA + AAH///////////////////////////////4AAAAAAAAAAP///////////////////////////////AAA + AAAAAAAAf//////////////////////////////4AAAAAAAAAAA///////////////////////////// + //AAAAAAAAAAAB//////////////////////////////4AAAAAAAAAAAD/////////////////////// + ///////AAAAAAAAAAAAH/////////////////////////////4AAAAAAAAAAAAP///////////////// + ////////////AAAAAAAAAAAAAf////////////////////////////4AAAAAAAAAAAAA//////////// + /////////////////AAAAAAAAAAAAAB////////////////////////////4AAAAAAAAAAAAAD////// + //////////////////////AAAAAAAAAAAAAAH///////////////////////////4AAAAAAAAAAAAAAP + ///////////////////////////AAAAAAAAAAAAAAAf//////////////////////////4AAAAAAAAAA + AAAAA///////////////////////////AAAAAAAAAAAAAAAB//////////////////////////4AAAAA + AAAAAAAAAAD//////////////////////////AAAAAAAAAAAAAAAAH/////////////////////////4 + AAAAAAAAAAAAAAAAP/////////////////////////AAAAAAAAAAAAAAAAAf//////////////////// + ////4AAAAAAAAAAAAAAAAA/////////////////////////AAAAAAAAAAAAAAAAAB/////////////// + /////////4AAAAAAAAAAAAAAAAAD////////////////////////AAAAAAAAAAAAAAAAAAH///////// + //////////////4AAAAAAAAAAAAAAAAAAP///////////////////////AAAAAAAAAAAAAAAAAAAf/// + ///////////////////4AAAAAAAAAAAAAAAAAAA///////////////////////AAAAAAAAAAAAAAAAAA + AB//////////////////////4AAAAAAAAAAAAAAAAAAAD//////////////////////AAAAAAAAAAAAA + AAAAAAAH/////////////////////4AAAAAAAAAAAAAAAAAAAAP/////////////////////AAAAAAAA + AAAAAAAAAAAAAf////////////////////4AAAAAAAAAAAAAAAAAAAAA/////////////////////AAA + AAAAAAAAAAAAAAAAAAB////////////////////4AAAAAAAAAAAAAAAAAAAAAD////////////////// + //AAAAAAAAAAAAAAAAAAAAAAH///////////////////4AAAAAAAAAAAAAAAAAAAAAAP//////////// + ///////AAAAAAAAAAAAAAAAAAAAAAAf//////////////////4AAAAAAAAAAAAAAAAAAAAAAA/////// + ////////////AAAAAAAAAAAAAAAAAAAAAAAB//////////////////4AAAAAAAAAAAAAAAAAAAAAAAD/ + /////////////////AAAAAAAAAAAAAAAAAAAAAAAAH/////////////////4AAAAAAAAAAAAAAAAAAAA + AAAAP/////////////////AAAAAAAAAAAAAAAAAAAAAAAAAf////////////////4AAAAAAAAAAAAAAA + AAAAAAAAAA/////////////////AAAAAAAAAAAAAAAAAAAAAAAAAB////////////////4AAAAAAAAAA + AAAAAAAAAAAAAAAD////////////////AAAAAAAAAAAAAAAAAAAAAAAAAAH///////////////4AAAAA + AAAAAAAAAAAAAAAAAAAAAP///////////////AAAAAAAAAAAAAAAAAAAAAAAAAAAf//////////////4 + AAAAAAAAAAAAAAAAAAAAAAAAAAA///////////////AAAAAAAAAAAAAAAAAAAAAAAAAAAB////////// + ////4AAAAAAAAAAAAAAAAAAAAAAAAAAAD//////////////AAAAAAAAAAAAAAAAAAAAAAAAAAAAH//// + /////////4AAAAAAAAAAAAAAAAAAAAAAAAAAAAP/////////////AAAAAAAAAAAAAAAAAAAAAAAAAAAA + Af////////////4AAAAAAAAAAAAAAAAAAAAAAAAAAAAAf////////////AAAAAAAAAAAAAAAAAAAAAAA + AAAAAAA////////////4AAAAAAAAAAAAAAAAAAAAAAAAAAAAAB////////////AAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAD///////////4AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAH///////////AAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAP//////////4AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAf//////////AAAAAAAA + AAAAAAABAAAAAAAAAAAAAAAA//////////4AAAAAAAAAAAAAAAOAAAAAAAAAAAAAAAB//////////AAA + AAAAAAAAAAAAB8AAAAAAAAAAAAAAAD/////////4AAAAAAAAAAAAAAAP4AAAAAAAAAAAAAAAH/////// + //AAAAAAAAAAAAAAAB/wAAAAAAAAAAAAAAAP////////4AAAAAAAAAAAAAAAP/gAAAAAAAAAAAAAAAf/ + ///////AAAAAAAAAAAAAAAB//AAAAAAAAAAAAAAAA////////4AAAAAAAAAAAAAAAP/+AAAAAAAAAAAA + AAAB////////AAAAAAAAAAAAAAAB//8AAAAAAAAAAAAAAAD///////wAAAAAAAAAAAAAAAP//4AAAAAA + AAAAAAAAAH//////+AAAAAAAAAAAAAAAB///wAAAAAAAAAAAAAAAP//////wAAAAAAAAAAAAAAAP///g + AAAAAAAAAAAAAAAf/////+AAAAAAAAAAAAAAAB////AAAAAAAAAAAAAAAA//////wAAAAAAAAAAAAAAA + H///+AAAAAAAAAAAAAAAB/////+AAAAAAAAAAAAAAAAH///8AAAAAAAAAAAAAAAD/////wAAAAAAAAAA + AAAAAAP///4AAAAAAAAAAAAAAAH////+AAAAAAAAAAAAAAAAAf///wAAAAAAAAAAAAAAAP////wAAAAA + AAAAAAAAAAAB////gAAAAAAAAAAAAAAAf///+AAAAAAAAAAAAAAAAAD////AAAAAAAAAAAAAAAA////w + AAAAAAAAAAAAAAAAAP///+AAAAAAAAAAAAAAAB///+AAAAAAAAAAAAAAAAAAf///8AAAAAAAAAAAAAAA + D///wAAAAAAAAAAAAAAAAAB////4AAAAAAAAAAAAAAAH//+AAAAAAAAAAAAAAAAAAD////wAAAAAAAAA + AAAAAAP//wAAAAAAAAAAAAAAAAAAP////gAAAAAAAAAAAAAAAf/+AAAAAAAAAAAAAAAAAAA/////AAAA + AAAAAAAAAAAA//wAAAAAAAAAAAAAAAAAAD////+AAAAAAAAAAAAAAAB/+AAAAAAAAAAAAAAAAAAAP/// + /8AAAAAAAAAAAAAAAD/wAAAAAAAAAAAAAAAAAAA/////4AAAAAAAAAAAAAAAH/AAAAAAAAAAAAAAAAAA + AD/////wAAAAAAAAAAAAAAAP4AAAAAAAAAAAAAAAAAAAP/////gAAAAAAAAAAAAAAA/AAAAAAAAAAAAA + AAAAAAA//////AAAAAAAAAAAAAAAB8AAAAAAAAAAAAAAAAAAADgAAH/+AAAAAAAAAAAAAAADgAAAAAAA + AAAAAAAAAAAAAAAAA/8AAAAAAAAAAAAAAAOAAAAAAAAAAAAAAAAAAAAAAAAAf4AAAAAAAAAAAAAAA4AA + AAAAAAAAAAAAAAAAAAAAAAAfwAAAAAAAAAAAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAfgAAAAAAAAAAAA + AAEAAAAAAAAAAAAAAAAAAAAAAAAAAfAAAAAAAAAAAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAeAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA4A + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABwAAAAAAAAAAAAAAAAAAAAAAAAAAAAMAAAAAAAAA + AAADgAAAAAAAAAAAAAAAAAAAAAAAAAAABwAAAAAAAAAAAAHAAAAAAAAAAAAAAAAAAAAAAAAAAAAPgAAA + AAAAAAAAAOAAAAAAAAAAAAAAAAAAAAAAAAAAAB/AAAAAAAAAAAAAcAAAAAAAAAAAAAAAAAAAAAAAAAAA + P+AAAAAAAAAAAAA4AAAAAAAAAAAAAAAAAAAAAAAAAAB/8AAAAAAAAAAAABwAAAAAAAAAAAAAAAAAAAAA + AAAAAP/8AAAAAAAAAAAADgAAAAAAAAAAAAAAAAAAAAAAAAAB///AAAAAAAAAAAAPAAAAAAAAAAAAAAAA + AAAAAAAAAAP//4AAAAAAAAAAAAeAAAAAAAAAAAAAAAAAAAAAAAAAB///AAAAAAAAAAAAA8AAAAAAAAAA + AAAAAAAAAAAAAAAP//8AAAAAAAAAAAAD4AAAAAAAAAAAAAAAAAAAAAAAAB///gAAAAAAAAAAAAHwAAAA + AAAAAAAAAAAAAAAAAAAAP//+AAAAAAAAAAAAAfgAAAAAAAAAAAAAAAAAAAAAAAB///wAAAAAAAAAAAAA + /AAAAAAAAAAAAAAAAAAAAAAAAP///AAAAAAAAAAAAAD+AAAAAAAAAAAAAAAAAAAAAAAB///4AAAAAAAA + AAAAAH8AAAAAAAAAAAAAAAAAAAAAAAP///gAAAAAAAAAAAAAf4AAAAAAAAAAAAAAAAAAAAAAB///8AAA + AAAAAAAAAAA/wAAAAAAAAAAAAAAAAAAAAAAP///wAAAAAAAAAAAAAD/gAAAAAAAAAAAAAAAAAAAAAA// + //AAAAAAAAAAAAAAP/AAAAAAAAAAAAAAAAAAAAAAD///4AAAAAAAAAAAAAA/8AAAAAAAAAAAAAAAAAAA + AAAP///gAAAAAAAAAAAAAB/wAAAAAAAAAAAAAAAAAAAAAA///+AAAAAAAAAAAAAAH/AAAAAAAAAAAAAA + AAAAAAAAD///4AAAAAAAAAAAAAAf8AAAAAAAAAAAAAAAAAAAAAAP///gAAAAAAAAAAAAAB/wAAAAAAAA + AAAAAAAAAAAAAA///8AAAAAAAAAAAAAAD/AAAAAAAAAAAAAAAAAAAAAAD///wAAAAAAAAAAAAAAP8AAA + AAAAAAAAAAAAAAAAAAAP///AAAAAAAAAAAAAAA/wAAAAAAAAAAAAAAAAAAAAAA///8AAAAAAAAAAAAAA + D/AAAAAAAAAAAAAAAAAAAAAAD///wAAAAAAAAAAAAAAP8AAAAAAAAAAAAAAAAAAAAAAP///AAAAAAAAA + AAAAAA/wAAAAAAAAAAAAAAAAAAAAAA///8AAAAAAAAAAAAAAD/AAAAAAAAAAAAAAAAAAAAAAD///wAAA + AAAAAAAAAAAP8AAAAAAAAAAAAAAAAAAAAAAP///AAAAAAAAAAAAAAA/wAAAAAAAAAAAAAAAAAAAAAA// + /8AAAABgAAAAAAAAD/AAAAAAAAAAAAAAAAAAAAAAD///wAAAAGAAAAAAAAAP8AAAAAAAAAAAAAAAAAAA + AAAP///AAAAAYAAAAAAAAA/wAAAAAAAAAAAAAAAAAAAAAA///8AAAAAgAAAAAAAAD/AAAAAAAAAAAAAA + AAAAAAAAD///wAAAACAAAAAAAAAP8AAAAAAAAAAAAAAAAAAAAAAP///AAAAAAAAAAAAAAA/wAAAAAAAA + AAAAAAAAAAAAAA///8AAAAAAAAAAAAAAD/AAAAAAAAAAAAAAAAAAAAAAD///wAAAAAAAAAAAAAAP8AAA + AAAAAAAAAAAAAAAAAAAP///AAAAAAAAAAAAAAA/wAAAAAAAAAAAAAAAAAAAAAA///8AAAAAAAAAAAAAA + D/AAAAAAAAAAAAAAAAAAAAAAD///wAAAAAAAAAAAAAAP8AAAAAAAAAAAAAAAAAAAAAAP///gAAAAAAAA + AAAAAB/wAAAAAAAAAAAAAAAAAAAAAA///+AAAAAAAAAAAAAAH/AAAAAAAAAAAAAAAAAAAAAAD///4AAA + AAAAAAAAAAAf8AAAAAAAAAAAAAAAAAAAAAAP///gAAAAAAAAAAAAAB/wAAAAAAAAAAAAAAAAAAAAAA// + /+AAAAAAAAAAAAAAP/AAAAAAAAAAAAAAAAAAAAAAD///8AAAAAAAAAAAAAA/8AAAAAAAAAAAAAAAAAAA + AAAP///wAAAAAAAAAAAAAD/wAAAAAAAAAAAAAAAAAAAAAA////AAAAAAAAAAAAAAP/AAAAAAAAAAAAAA + AAAAAAAAD///+AAAAAAAAAAAAAB/8AAAAAAAAAAAAAAAAAAAAAAP///4AAAAAAAAAAAAAH/wAAAAAAAA + AAAAAAAAAAAAAA////wAAAAAAAAAAAAA//AAAAAAAAAAAAAAAAAAAAAAD////AAAAAAAAAAAAAD/8AAA + AAAAAAAAAAAAAAAAAAAP///+AAAAAAAAAAAAAf/wAAAAAAAAAAAAAAAAAAAAAA////4AAAAAAAAAAAAB + //AAAAAAAAAAAAAAAAAAAAAAD////wAAAAAAAAAAAAP/8AAAAAAAAAAAAAAAAAAAAAAP////AAAAAAAA + AAAAA//wAAAAAAAAAAAAAAAAAAAAAA////+AAAAAAAAAAAAH//AAAAAAAAAAAAAAAAAAAAAAD////8AA + AAAAAAAAAA//8AAAAAAAAAAAAAAAAAAAAAAP////wAAAAAAAAAAAD//wAAAAAAAAAAAAAAAAAAAAAA// + ///gAAAAAAAAAAAH//AAAAAAAAAAAAAAAAAAAAAAD/////AAAAAAAAAAAAP/8AAAAAAAAAAAAAAAAAAA + AAAP////+AAAAAAAAAAAA//wAAAAAAAAAAAAAAAAAAAAAA/////8AAAAAAAAAAAB//AAAAAAAAAAAAAA + AAAAAAAAD/////4AAAAAAAAAAAD/8AAAAAAAAAAAAAAAAAAAAAAP/////wAAAAAAAAAAAP/wAAAAAAAA + AAAAAAAAAAAAAA//////gAAAAAAAAAAAf/AAAAAAAAAAAAAAAAAAAAAAD//////AAAAAAAAAAAA/8AAA + AAAAAAAAAAAAAAAAAAAP/////+AAAAAAAAAAAD/wAAAAAAAAAAAAAAAAAAAAAA//////8AAAAAAAAAAA + H/AAAAAAAAAAAAAAAAAAAAAAD//////8AAAAAAAAAAAP8AAAAAAAAAAAAAAAAAAAAAAP//////4AAAAA + AAAAAA/wAAAAAAAAAAAAAAAAAAAAAA///////4AAAAAAAAAAB/AAAAAAAAAAAAAAAAAAAAAAD/////// + 4AAAAAAAAAAD8AAAAAAAAAAAAAAAAAAAAAAP///////8AAAAAAAAAAHwAAAAAAAAAAAAAAAAAAAAAA// + //////+AAABwAAAAAfAAAAAAAAAAAAAAAAAAAAAAD/////////////gAAAAA8AAAAAAAAAAAAAAAAAAA + AAAP/////////////AAAAABwAAAAAAAAAAAAAAAAAAAAAA/////////////+AAAAAHAAAAAAAAAAAAAA + AAAAAAAAD/////////////4AAAAAMAAAAAAAAAAAAAAAAAAAAAAP/////////////wAAAAAQAAAAAAAA + AAAAAAAAAAAAAA//////////////gAAAABAAAAAAAAAAAAAAAAAAAAAAD/////////////+AAAAAAAAA + AAAAAAAAAAAAAAAAAAAP/////////////8AAAAAAAAAAAAAAAAAAAAAAAAAAAA//////////////4AAA + AAAAAAAAAAAAAAAAAAAAAAAAD//////////////gAAAAAAAAAAAAAAAAAAAAAAAAAAAP//////////// + //AAAAAAAAAAAAAAAAAAAAAAAAAAAA//////////////+AAAAAAAAAAAAAAAAAAAAAAAAAAAD/////// + ///////4AAAAAAAAAAAAAAAAAAAAAAAAAAAP//////////////wAAAAAAAAAAAAAAAAAAAAAAAAAAA// + /////////////gAAAAAAAAAAAAAAAAAAAAAAAAAAD///////////////AAAAAAAAAAAAAAAAAAAAAAAA + AAAP//////////////8AAAAAAAAAAAAAAAAAAAAAAAAAAA///////////////4AAAAAAAAAAAAAAAAAA + AAAAAAAAD///////////////wAAAAAAAAAAAAAAAAAAAAAAAAAAP///////////////AAAAAAAAAAAAA + AAAAAAAAAAAAAA///////////////+AAAAAAAAAAAAAAAAAAAAAAAAAAD///////////////8AAAAAAA + AAAAAAAAAAAAAAAAAAAP///////////////wAAAAAAAAAAAAAAAAAAAAAAAAAA////////////////gA + AAAAAAAAAAAAAAAAAAAAAAAAD////////////////AAAAAAAAAAAAAAAAAAAAAAAAAAP//////////// + ///8AAAAAAAAAAAAAAAAAAAAAAAAAA////////////////4AAAAAAAAAAAAAAAAAAAAAAAAAD/////// + /////////wAAAAAAAAAAAAAAAAAAAAAAAAAP////////////////AAAAAAAAAAAAAAAAAAAAAAAAAA// + //////////////+AAAAAAAAAAAAAAAAAAAAAAAAAD////////////////8AAAAAAAAAAAAAAAAAAAAAA + AAAP////////////////4AAAAAAAAAAAAAAAAAAAAAAAAA/////////////////gAAAAAAAAAAAAAAAA + AAAAAAAAH/////////////////AAAAAAAAAAAAAAAAAAAAAAAAAf////////////////+AAAAAAAAAAA + AAAAAAAAAAAAAB/////////////////4AAAAAAAAAAAAAAAAAAAAAAAAH/////////////////wAAAAA + AAAAAAABAAAAAAAAAAA//////////////////gAAAAAAAAAAAAGAAAAAAAAAAD/////////////////+ + AAAAAAAAAAAAAYAAAAAAAAAAP/////////////////+AAAAAAAAAAAADgAAAAAAAAAB///////////// + /////4AMAAAAAAAAAAPAAAAAAAAAAH////////////////////4AAAAAAAAAA+AAAAAAAAAA//////// + /////////////gAAAAAAAAAH4AAAAAAAAAH/////////////////////AAAAAAAAAA/wAAAAAAAAAf// + //////////////////+AAAAAAAAAD/gAAAAAAAAD/////////////////////8AAAAAAAAAf/AAAAAAA + AAf/////////////////////4AAAAAAAAD/+AAAAAAAAD//////////////////////wAAAAAAAAf/8A + AAAAAAAf//////////////////////gAAAAAAAH//4AAAAAAAH///////////////////////AAAAAAA + A///4AAAAAAB////////////////////////AAAAAAAP///4AAAAAAf////////////////////////A + AAAAAD////+AAAAAf/////////////////////////wAAAAD//8= + + + \ No newline at end of file From 38e4ab665f38cc228c6ce7eb49e27675c7dd9aa0 Mon Sep 17 00:00:00 2001 From: Dominic Nguyen Date: Wed, 13 Dec 2023 18:43:42 -0800 Subject: [PATCH 31/76] outside of vertical --- AuroraLabelItemsPlugin.cs | 186 +++++++++++++++++++------------------- 1 file changed, 92 insertions(+), 94 deletions(-) diff --git a/AuroraLabelItemsPlugin.cs b/AuroraLabelItemsPlugin.cs index 67c695d..d697012 100644 --- a/AuroraLabelItemsPlugin.cs +++ b/AuroraLabelItemsPlugin.cs @@ -60,10 +60,11 @@ public class AuroraLabelItemsPlugin : ILabelPlugin readonly ConcurrentDictionary mntflagtoggle = new ConcurrentDictionary(); readonly ConcurrentDictionary downlink = new ConcurrentDictionary(); // key: callsign, value: acknowledged status - readonly ConcurrentDictionary> advisoryConflict = new ConcurrentDictionary>(); - readonly ConcurrentDictionary> imminentConflict = new ConcurrentDictionary>(); - //readonly ConcurrentDictionary advisoryConflict = new ConcurrentDictionary(); - //readonly ConcurrentDictionary imminentConflict = new ConcurrentDictionary(); + readonly ConcurrentDictionary> advisoryConflict = new ConcurrentDictionary>(); + readonly ConcurrentDictionary> imminentConflict = new ConcurrentDictionary>(); + //readonly ConcurrentDictionary> advisoryConflict = new ConcurrentDictionary>(); + //readonly ConcurrentDictionary> imminentConflict = new ConcurrentDictionary>(); + public AuroraLabelItemsPlugin() { @@ -130,7 +131,7 @@ public void OnFDRUpdate(FDP2.FDR updated) { ConflictProbe(updated, 100); } - + if (FDP2.GetFDRIndex(updated.Callsign) == -1) { eastboundCallsigns.TryRemove(updated.Callsign, out _); @@ -347,20 +348,20 @@ public void ConflictProbe(FDP2.FDR fdr, int value) bool cpdlc = (Regex.IsMatch(fdr2.AircraftEquip, @"J5") || Regex.IsMatch(fdr2.AircraftEquip, @"J7")); bool adsc = Regex.IsMatch(fdr2.AircraftSurvEquip, @"D1"); bool jet = fdr2.PerformanceData?.IsJet ?? false; - + var newValue = value; if (rnp4 && adsc && cpdlc) { - newValue = Math.Max(newValue, 23); + newValue = Math.Max(newValue, 23); } - - + + else if (rnp10 && adsc && cpdlc) { newValue = Math.Max(newValue, 50); } - + else { newValue = Math.Max(newValue, 100); @@ -374,20 +375,20 @@ public void ConflictProbe(FDP2.FDR fdr, int value) var firstConflictTime = segments1.FirstOrDefault(); var firstConflictTime2 = segments2.FirstOrDefault(); - var isConflictPair = segments1.Count > 0; + var isConflictPair = segments1.Count > 0; if (firstConflictTime == null || firstConflictTime2 == null) continue; - - var timeLongSame = sameDir && isConflictPair && firstConflictTime.endTime > DateTime.UtcNow + + var timeLongSame = sameDir && isConflictPair && firstConflictTime.endTime > DateTime.UtcNow && (firstConflictTime2.startTime - firstConflictTime.startTime).Duration() < (jet ? (new TimeSpan(0, 0, 10, 0)) : (new TimeSpan(0, 0, 15, 0)));//check time based longitudinal for same direction - var timeLongCross = crossing && isConflictPair && firstConflictTime.endTime > DateTime.UtcNow + var timeLongCross = crossing && isConflictPair && firstConflictTime.endTime > DateTime.UtcNow && (firstConflictTime2.startTime - firstConflictTime.startTime).Duration() < (new TimeSpan(0, 0, 15, 0)); var distLongSame = sameDir && isConflictPair && firstConflictTime.endTime > DateTime.UtcNow && Conversions.CalculateDistance(firstConflictTime.startLatlong, firstConflictTime2.startLatlong) < (jet && rnp4 && cpdlc && adsc ? 30 : (rnp4 || rnp10) ? 50 : 50); var timeLongOpposite = false; - TimeOfPassing top = null; + TimeOfPassing top = null; if (isConflictPair && oppoDir) { @@ -395,15 +396,15 @@ public void ConflictProbe(FDP2.FDR fdr, int value) { top = new TimeOfPassing(fdr, fdr2); } - + catch (Exception e) { return; } timeLongOpposite = top.Time > DateTime.UtcNow - && (top.Time.Add(new TimeSpan(0, 0, 10, 0)) > DateTime.UtcNow) && (top.Time.Subtract(new TimeSpan(0, 0, 10, 0)) < DateTime.UtcNow); + && (top.Time.Add(new TimeSpan(0, 0, 10, 0)) > DateTime.UtcNow) && (top.Time.Subtract(new TimeSpan(0, 0, 10, 0)) < DateTime.UtcNow); } - + @@ -412,82 +413,67 @@ public void ConflictProbe(FDP2.FDR fdr, int value) // < (jet && rnp4 && cpdlc && adsc ? 30 : (rnp4 || rnp10) ? 50 : 50); - var lossOfSep = (delta < verticalSep) && timeLongSame || timeLongCross || distLongSame || timeLongOpposite; // || distLongOpposite + var lossOfSep = timeLongSame || timeLongCross || distLongSame || timeLongOpposite; // || distLongOpposite var earliestLOS = (isConflictPair && oppoDir ? top.Time.Subtract(new TimeSpan(0, 0, 10, 0)) : (DateTime.Compare(firstConflictTime.startTime, firstConflictTime2.startTime) < 0 ? firstConflictTime.startTime : firstConflictTime2.startTime)); var imminentConflicts = (isConflictPair && oppoDir && (delta < verticalSep)) ? (new TimeSpan(0, 0, 30, 0, 0) >= earliestLOS.Subtract(DateTime.UtcNow).Duration()) : (lossOfSep && new TimeSpan(0, 0, 30, 0, 0) >= earliestLOS.Subtract(DateTime.UtcNow).Duration()); //check if timediff < 30 mins - var advisoryConflicts = (isConflictPair && oppoDir && (delta < verticalSep)) ? (new TimeSpan(0, 2, 0, 0, 0) > earliestLOS.Subtract(DateTime.UtcNow).Duration()) + var advisoryConflicts = (isConflictPair && oppoDir && (delta < verticalSep)) ? (new TimeSpan(0, 2, 0, 0, 0) > earliestLOS.Subtract(DateTime.UtcNow).Duration()) && (earliestLOS.Subtract(DateTime.UtcNow).Duration() >= new TimeSpan(0, 0, 30, 0, 0)) - : (lossOfSep && new TimeSpan(0, 2, 0, 0, 0) > earliestLOS.Subtract(DateTime.UtcNow).Duration()) + : (lossOfSep && new TimeSpan(0, 2, 0, 0, 0) > earliestLOS.Subtract(DateTime.UtcNow).Duration()) && (earliestLOS.Subtract(DateTime.UtcNow).Duration() >= new TimeSpan(0, 0, 30, 0, 0)); //check if timediff < 2 hours - - if (imminentConflicts) - { - imminentConflict.AddOrUpdate(fdr.Callsign, new List(new string[] { fdr2.Callsign }), - (k, v) => v.Append(fdr2.Callsign).ToList()); - imminentConflict.AddOrUpdate(fdr2.Callsign, new List(new string[] { fdr.Callsign }), - (k, v) => v.Append(fdr.Callsign).ToList()); - - //imminentConflict.AddOrUpdate(fdr.Callsign, imminentConflicts, (k, v) => imminentConflicts); + if (imminentConflicts) + { + imminentConflict.AddOrUpdate(fdr.Callsign, new HashSet(new string[] { fdr2.Callsign }), + (k, v) => { v.Add(fdr2.Callsign); return v; }); - //imminentConflict.AddOrUpdate(cs1, imminentConflicts, (k, v) => imminentConflict); - //imminentConflict.AddOrUpdate(cs2, imminentConflicts, (k, v) => imminentConflict); - } + } else { - //imminentConflict.AddOrUpdate(fdr2.Callsign, new List(), - // (k, v) => v.Where(e => e != fdr.Callsign).ToList()); - //imminentConflict.AddOrUpdate(fdr.Callsign, new List(), - // (k, v) => v.Where(e => e != fdr2.Callsign).ToList()); + HashSet maybeSet; + bool exists = imminentConflict.TryGetValue(fdr.Callsign, out maybeSet); + if (exists) + { + maybeSet.Remove(fdr2.Callsign); + } - imminentConflict.TryRemove(fdr.Callsign, out _); - imminentConflict.TryRemove(fdr2.Callsign, out _); - } - if (advisoryConflicts) + if (advisoryConflicts) { - advisoryConflict.AddOrUpdate(fdr2.Callsign, new List(new string[] { fdr.Callsign }), - (k, v) => v.Append(fdr.Callsign).ToList()); - advisoryConflict.AddOrUpdate(fdr.Callsign, new List(new string[] { fdr2.Callsign }), - (k, v) => v.Append(fdr2.Callsign).ToList()); + advisoryConflict.AddOrUpdate(fdr.Callsign, new HashSet(new string[] { fdr2.Callsign }), + (k, v) => { v.Add(fdr2.Callsign); return v; }); + } else - { - advisoryConflict.AddOrUpdate(fdr.Callsign, new List(), - (k, v) => v.Where(e => e != fdr2.Callsign).ToList()); - advisoryConflict.AddOrUpdate(fdr2.Callsign, new List(), - (k, v) => v.Where(e => e != fdr.Callsign).ToList()); - - - advisoryConflict.TryRemove(fdr.Callsign, out _); - advisoryConflict.TryRemove(fdr2.Callsign, out _); + { + HashSet admaybeSet; + bool adexists = advisoryConflict.TryGetValue(fdr.Callsign, out admaybeSet); + if (adexists) + { + admaybeSet.Remove(fdr2.Callsign); + } + } } - var emptyAdvisoryConflicts = advisoryConflict.Where(pair => pair.Value.Count == 0) - .Select(pair => pair.Key) - .ToList(); - foreach (var callsign in emptyAdvisoryConflicts) - { - advisoryConflict.TryRemove(callsign, out _); } - var emptyImminentConflicts = imminentConflict.Where(pair => pair.Value.Count == 0) - .Select(pair => pair.Key) - .ToList(); - foreach (var callsign in emptyImminentConflicts) + else + { + HashSet maybeSet; // defines an uninitialized variable for the result of the below method to get placed in + bool exists = imminentConflict.TryGetValue(fdr.Callsign, out maybeSet); // tries to get the set of conflicts corresponding to a callsign, places it in the `maybeSet` variable if it exists. The bool `exists` represents whether there was a set of conflicts for that callsign + if (exists) { - imminentConflict.TryRemove(callsign, out _); + maybeSet.Remove(fdr2.Callsign); // remove the fdr2 (which is the one we are currently evaluating for conflicts against fdr) from the set of conflicts } } - } } + } @@ -552,38 +538,38 @@ public CustomLabelItem GetCustomLabelItem(string itemType, Track track, FDP2.FDR int cfl = flightDataRecord.CFLUpper / 100; int rfl = flightDataRecord.RFL / 100; int alt = flightDataRecord.CFLUpper == -1 ? rfl : cfl; - var exConflict = (isAdvisory || isImminent && (track.State == MMI.HMIStates.Jurisdiction) ? GetDirectionColour(flightDataRecord.Callsign) : default); - var colour = (isNonRVSM ? NonRVSM : exConflict); + var excludeColor = SelectASDTrackColour(track) == GetConflictColour(flightDataRecord.Callsign) ? null : SelectASDTrackColour(track); + var colour = (isNonRVSM ? NonRVSM : excludeColor); var notProbe = flightDataRecord.State == (FDR.FDRStates.STATE_PREACTIVE | FDR.FDRStates.STATE_COORDINATED) ? BorderFlags.All : BorderFlags.None; switch (itemType) { - //case LABEL_ITEM_SELECT_HORI: - // - // if (selectedCallsign) - // { - // return new CustomLabelItem() - // - // { - // Text = "", - // Border = BorderFlags.Top - // }; - // } - // - // return null; - // - //case LABEL_ITEM_SELECT_VERT: - // - // if (selectedCallsign) - // { - // return new CustomLabelItem() - // { - // Text = "", - // Border = BorderFlags.Left - // }; - // } - // - // return null; + case LABEL_ITEM_SELECT_HORI: + + if (selectedCallsign) + { + return new CustomLabelItem() + + { + Text = "", + Border = BorderFlags.Top + }; + } + + return null; + + case LABEL_ITEM_SELECT_VERT: + + if (selectedCallsign) + { + return new CustomLabelItem() + { + Text = "", + Border = BorderFlags.Left + }; + } + + return null; case LABEL_ITEM_COMM_ICON: @@ -594,6 +580,7 @@ public CustomLabelItem GetCustomLabelItem(string itemType, Track track, FDP2.FDR Text = "▽", //▼ BackColourIdentity = Colours.Identities.Jurisdiction, //Border = BorderFlags.All + CustomForeColour = excludeColor }; } else @@ -601,6 +588,7 @@ public CustomLabelItem GetCustomLabelItem(string itemType, Track track, FDP2.FDR return new CustomLabelItem() { Text = "⬜", + CustomForeColour = excludeColor }; } case LABEL_ITEM_ADSB_CPDLC: @@ -670,6 +658,7 @@ public CustomLabelItem GetCustomLabelItem(string itemType, Track track, FDP2.FDR return new CustomLabelItem() { Text = "◦", + CustomForeColour = excludeColor }; } @@ -678,6 +667,7 @@ public CustomLabelItem GetCustomLabelItem(string itemType, Track track, FDP2.FDR return new CustomLabelItem() { Text = "&", + CustomForeColour = excludeColor }; } @@ -689,6 +679,7 @@ public CustomLabelItem GetCustomLabelItem(string itemType, Track track, FDP2.FDR return new CustomLabelItem() { Text = "x", + CustomForeColour = excludeColor }; return null; @@ -775,6 +766,7 @@ public CustomLabelItem GetCustomLabelItem(string itemType, Track track, FDP2.FDR { Text = "★", OnMouseClick = HandleRadarFlagClick, + CustomForeColour = excludeColor }; } @@ -784,6 +776,7 @@ public CustomLabelItem GetCustomLabelItem(string itemType, Track track, FDP2.FDR { Text = "◦", OnMouseClick = HandleRadarFlagClick, + CustomForeColour = excludeColor }; } @@ -795,6 +788,7 @@ public CustomLabelItem GetCustomLabelItem(string itemType, Track track, FDP2.FDR return new CustomLabelItem() { Text = "^", + CustomForeColour = excludeColor }; } @@ -813,6 +807,7 @@ public CustomLabelItem GetCustomLabelItem(string itemType, Track track, FDP2.FDR { Text = "M" + Convert.ToDecimal(mach).ToString("F2").Replace(".", ""), //Text = "N" + flightDataRecord.TAS + CustomForeColour = excludeColor }; case LABEL_ITEM_3DIGIT_GROUNDSPEED: @@ -823,6 +818,7 @@ public CustomLabelItem GetCustomLabelItem(string itemType, Track track, FDP2.FDR return new CustomLabelItem() { Text = "N" + gs.ToString("000"),//format as 3 digits (with leading zeros) + CustomForeColour = excludeColor }; default: @@ -886,6 +882,8 @@ private CustomColour GetConflictColour(string callsign) { return Advisory; } + else + return null; } } From bae28f7794c3e53de3996ea6027dd6298ca82592 Mon Sep 17 00:00:00 2001 From: Dominic Nguyen Date: Sun, 17 Dec 2023 16:57:53 -0800 Subject: [PATCH 32/76] ExcludeConflictColor and Cleared Route Strip --- AuroraLabelItemsPlugin.cs | 139 ++++++++++++++++++++++++-------------- AuroraStripItemPlugin.cs | 54 ++++++++++++++- 2 files changed, 141 insertions(+), 52 deletions(-) diff --git a/AuroraLabelItemsPlugin.cs b/AuroraLabelItemsPlugin.cs index d697012..dea458a 100644 --- a/AuroraLabelItemsPlugin.cs +++ b/AuroraLabelItemsPlugin.cs @@ -15,7 +15,6 @@ - //Note the reference to vatsys (set Copy Local to false) -----> namespace AuroraLabelItemsPlugin @@ -59,11 +58,9 @@ public class AuroraLabelItemsPlugin : ILabelPlugin readonly ConcurrentDictionary radartoggle = new ConcurrentDictionary(); readonly ConcurrentDictionary mntflagtoggle = new ConcurrentDictionary(); readonly ConcurrentDictionary downlink = new ConcurrentDictionary(); - // key: callsign, value: acknowledged status readonly ConcurrentDictionary> advisoryConflict = new ConcurrentDictionary>(); readonly ConcurrentDictionary> imminentConflict = new ConcurrentDictionary>(); - //readonly ConcurrentDictionary> advisoryConflict = new ConcurrentDictionary>(); - //readonly ConcurrentDictionary> imminentConflict = new ConcurrentDictionary>(); + public AuroraLabelItemsPlugin() @@ -117,20 +114,6 @@ public void OnFDRUpdate(FDP2.FDR updated) int rfl = updated.RFL; int alt = cfl == -1 ? rfl : cfl; - TransferOfControl(updated); - - if (jet & rnp4 & cpdlc & adsc) ///Using CalculateAreaofConflict method - { - ConflictProbe(updated, 23); - } - else if (rnp4 || rnp10) - { - ConflictProbe(updated, 50); - } - else - { - ConflictProbe(updated, 100); - } if (FDP2.GetFDRIndex(updated.Callsign) == -1) { @@ -236,6 +219,25 @@ public void OnFDRUpdate(FDP2.FDR updated) bool east = trk >= 0 && trk < 180; eastboundCallsigns.AddOrUpdate(updated.Callsign, east, (c, e) => east); } + + TransferOfControl(updated); + + if (jet & rnp4 & cpdlc & adsc) ///Using CalculateAreaofConflict method + { + ConflictProbe(updated, 23); + } + else if (rnp4 || rnp10) + { + ConflictProbe(updated, 50); + } + else if (rnp10) + { + ConflictProbe(updated, 75); + } + else + { + ConflictProbe(updated, 100); + } } } @@ -282,7 +284,6 @@ private static void TransferOfControl(FDP2.FDR fdr) { toc.HandoffNextSector(); MMI.HandoffJurisdiction(fdr, whichFIR); - //FDP2.AcceptJurisdiction(fdr, whichFIR); MMI.Inhibit(fdr); Thread.Sleep(300000); RDP.DeCouple(rt); @@ -438,7 +439,16 @@ public void ConflictProbe(FDP2.FDR fdr, int value) bool exists = imminentConflict.TryGetValue(fdr.Callsign, out maybeSet); if (exists) { - maybeSet.Remove(fdr2.Callsign); + maybeSet.Clear(); + } + + + var emptyImminentConflicts = imminentConflict.Where(pair => pair.Value.Count == 0) + .Select(pair => pair.Key) + .ToList(); + foreach (var callsign in emptyImminentConflicts) + { + imminentConflict.TryRemove(callsign, out _); } @@ -448,8 +458,6 @@ public void ConflictProbe(FDP2.FDR fdr, int value) advisoryConflict.AddOrUpdate(fdr.Callsign, new HashSet(new string[] { fdr2.Callsign }), (k, v) => { v.Add(fdr2.Callsign); return v; }); - - } else { @@ -457,8 +465,17 @@ public void ConflictProbe(FDP2.FDR fdr, int value) bool adexists = advisoryConflict.TryGetValue(fdr.Callsign, out admaybeSet); if (adexists) { - admaybeSet.Remove(fdr2.Callsign); + admaybeSet.Clear(); + } + + var emptyAdvisoryConflicts = advisoryConflict.Where(pair => pair.Value.Count == 0) + .Select(pair => pair.Key) + .ToList(); + foreach (var callsign in emptyAdvisoryConflicts) + { + advisoryConflict.TryRemove(callsign, out _); } + } } @@ -466,11 +483,32 @@ public void ConflictProbe(FDP2.FDR fdr, int value) else { HashSet maybeSet; // defines an uninitialized variable for the result of the below method to get placed in + HashSet admaybeSet; + bool adexists = advisoryConflict.TryGetValue(fdr.Callsign, out admaybeSet); bool exists = imminentConflict.TryGetValue(fdr.Callsign, out maybeSet); // tries to get the set of conflicts corresponding to a callsign, places it in the `maybeSet` variable if it exists. The bool `exists` represents whether there was a set of conflicts for that callsign if (exists) { maybeSet.Remove(fdr2.Callsign); // remove the fdr2 (which is the one we are currently evaluating for conflicts against fdr) from the set of conflicts } + if (adexists) + { + admaybeSet.Remove(fdr2.Callsign); // remove the fdr2 (which is the one we are currently evaluating for conflicts against fdr) from the set of conflicts + } + + var emptyAdvisoryConflicts = advisoryConflict.Where(pair => pair.Value.Count == 0) + .Select(pair => pair.Key) + .ToList(); + foreach (var callsign in emptyAdvisoryConflicts) + { + advisoryConflict.TryRemove(callsign, out _); + } + var emptyImminentConflicts = imminentConflict.Where(pair => pair.Value.Count == 0) + .Select(pair => pair.Key) + .ToList(); + foreach (var callsign in emptyImminentConflicts) + { + imminentConflict.TryRemove(callsign, out _); + } } } } @@ -503,7 +541,6 @@ private void HandleRadarFlagClick(CustomLabelItemMouseClickEventArgs e) } - /// vatSys calls this function when it encounters a custom label item (defined in Labels.xml) during the label rendering. /// itemType is the value of the Type attribute in Labels.xml /// If it's not our item being called (another plugins, for example), return null. @@ -527,9 +564,6 @@ public CustomLabelItem GetCustomLabelItem(string itemType, Track track, FDP2.FDR bool radarToggled = radartoggle.TryGetValue(flightDataRecord.Callsign, out _); bool mntflagToggled = mntflagtoggle.TryGetValue(flightDataRecord.Callsign, out _); bool downLink = downlink.TryGetValue(flightDataRecord.Callsign, out _); - bool selectedCallsign = MMI.SelectedTrack?.GetFDR()?.Callsign == track.GetFDR().Callsign; - bool isAdvisory = advisoryConflict.TryGetValue(flightDataRecord.Callsign, out _); - bool isImminent = imminentConflict.TryGetValue(flightDataRecord.Callsign, out _); bool isNonRVSM = !flightDataRecord.RVSM; var pbn = Regex.Match(flightDataRecord.Remarks, @"PBN\/\w+\s"); bool rnp10 = pbn.Value.Contains("A1"); @@ -538,21 +572,22 @@ public CustomLabelItem GetCustomLabelItem(string itemType, Track track, FDP2.FDR int cfl = flightDataRecord.CFLUpper / 100; int rfl = flightDataRecord.RFL / 100; int alt = flightDataRecord.CFLUpper == -1 ? rfl : cfl; - var excludeColor = SelectASDTrackColour(track) == GetConflictColour(flightDataRecord.Callsign) ? null : SelectASDTrackColour(track); - var colour = (isNonRVSM ? NonRVSM : excludeColor); var notProbe = flightDataRecord.State == (FDR.FDRStates.STATE_PREACTIVE | FDR.FDRStates.STATE_COORDINATED) ? BorderFlags.All : BorderFlags.None; + var colour = (!flightDataRecord.RVSM ? NonRVSM : ExcludeConflictColor(track, flightDataRecord)); switch (itemType) + { + case LABEL_ITEM_SELECT_HORI: - - if (selectedCallsign) + + if (MMI.SelectedTrack?.GetFDR()?.Callsign == track.GetFDR().Callsign) { return new CustomLabelItem() { - Text = "", - Border = BorderFlags.Top + Text = " ", + Border = BorderFlags.Bottom }; } @@ -560,11 +595,11 @@ public CustomLabelItem GetCustomLabelItem(string itemType, Track track, FDP2.FDR case LABEL_ITEM_SELECT_VERT: - if (selectedCallsign) + if (MMI.SelectedTrack?.GetFDR()?.Callsign == track.GetFDR().Callsign) { return new CustomLabelItem() { - Text = "", + Text = " ", Border = BorderFlags.Left }; } @@ -580,15 +615,13 @@ public CustomLabelItem GetCustomLabelItem(string itemType, Track track, FDP2.FDR Text = "▽", //▼ BackColourIdentity = Colours.Identities.Jurisdiction, //Border = BorderFlags.All - CustomForeColour = excludeColor - }; + }; } else { return new CustomLabelItem() { Text = "⬜", - CustomForeColour = excludeColor }; } case LABEL_ITEM_ADSB_CPDLC: @@ -658,7 +691,6 @@ public CustomLabelItem GetCustomLabelItem(string itemType, Track track, FDP2.FDR return new CustomLabelItem() { Text = "◦", - CustomForeColour = excludeColor }; } @@ -667,7 +699,6 @@ public CustomLabelItem GetCustomLabelItem(string itemType, Track track, FDP2.FDR return new CustomLabelItem() { Text = "&", - CustomForeColour = excludeColor }; } @@ -679,7 +710,6 @@ public CustomLabelItem GetCustomLabelItem(string itemType, Track track, FDP2.FDR return new CustomLabelItem() { Text = "x", - CustomForeColour = excludeColor }; return null; @@ -766,7 +796,6 @@ public CustomLabelItem GetCustomLabelItem(string itemType, Track track, FDP2.FDR { Text = "★", OnMouseClick = HandleRadarFlagClick, - CustomForeColour = excludeColor }; } @@ -776,7 +805,6 @@ public CustomLabelItem GetCustomLabelItem(string itemType, Track track, FDP2.FDR { Text = "◦", OnMouseClick = HandleRadarFlagClick, - CustomForeColour = excludeColor }; } @@ -788,7 +816,6 @@ public CustomLabelItem GetCustomLabelItem(string itemType, Track track, FDP2.FDR return new CustomLabelItem() { Text = "^", - CustomForeColour = excludeColor }; } @@ -807,7 +834,9 @@ public CustomLabelItem GetCustomLabelItem(string itemType, Track track, FDP2.FDR { Text = "M" + Convert.ToDecimal(mach).ToString("F2").Replace(".", ""), //Text = "N" + flightDataRecord.TAS - CustomForeColour = excludeColor + ForeColourIdentity = Colours.Identities.Custom, + CustomForeColour = ExcludeConflictColor(track, flightDataRecord) + }; case LABEL_ITEM_3DIGIT_GROUNDSPEED: @@ -818,7 +847,8 @@ public CustomLabelItem GetCustomLabelItem(string itemType, Track track, FDP2.FDR return new CustomLabelItem() { Text = "N" + gs.ToString("000"),//format as 3 digits (with leading zeros) - CustomForeColour = excludeColor + ForeColourIdentity = Colours.Identities.Custom, + CustomForeColour = ExcludeConflictColor(track, flightDataRecord) }; default: @@ -877,14 +907,23 @@ private CustomColour GetConflictColour(string callsign) { return Imminent; } - - if (advisoryConflict.TryGetValue(callsign, out _)) + else if (advisoryConflict.TryGetValue(callsign, out _)) { return Advisory; } - else - + return null; } + + private CustomColour ExcludeConflictColor(Track track, FDP2.FDR flightDataRecord) + { + if (SelectASDTrackColour(track) == GetConflictColour(flightDataRecord.Callsign)) + { + return null; + } + return SelectASDTrackColour(track); + + } + } } \ No newline at end of file diff --git a/AuroraStripItemPlugin.cs b/AuroraStripItemPlugin.cs index 3c2baa2..c55ff9d 100644 --- a/AuroraStripItemPlugin.cs +++ b/AuroraStripItemPlugin.cs @@ -5,6 +5,7 @@ using System.Collections.Concurrent; using System.ComponentModel.Composition; //<--Need to add a reference to System.ComponentModel.Composition using static vatsys.FDP2; +using System.Security.Policy; namespace AuroraStripItemsPlugin @@ -26,6 +27,8 @@ public class AuroraStripItemsPlugin : IStripPlugin const string STRIP_ITEM_RVSM_FLAG = "AURORA_RVSM_FLAG"; const string STRIP_ITEM_VMI = "AURORA_STRIP_VMI"; const string STRIP_ITEM_COMPLEX = "AURORA_STRIP_COMPLEX"; + const string STRIP_ITEM_CLEARED_LEVEL = "AURORA_CLEARED_LEVEL"; + const string STRIP_ITEM_REQUESTED_LEVEL = "AURORA_REQUESTED_LEVEL"; const string STRIP_ITEM_MAN_EST = "AURORA_MAN_EST"; const string STRIP_ITEM_POINT = "AURORA_POINT"; const string STRIP_ITEM_ROUTE = "AURORA_ROUTE_STRIP"; @@ -33,6 +36,7 @@ public class AuroraStripItemsPlugin : IStripPlugin const string STRIP_ITEM_ANNOT_IND = "AURORA_ANNOT_STRIP"; const string STRIP_ITEM_LATERAL_FLAG = "AURORA_LATERAL_FLAG"; const string STRIP_ITEM_RESTR = "AURORA_RESTR_STRIP"; + const string STRIP_ITEM_CLRD_RTE = "AURORA_CLRD_RTE"; readonly static CustomColour NonRVSM = new CustomColour(242, 133, 0); readonly static CustomColour SepFlags = new CustomColour(0, 196, 253); readonly static CustomColour Pending = new CustomColour(46, 139, 87); @@ -101,10 +105,12 @@ public CustomStripItem GetCustomStripItem(string itemType, Track track, FDP2.FDR bool adsb = flightDataRecord.ADSB; bool rvsm = flightDataRecord.RVSM; int level = radarTrack == null ? flightDataRecord.PRL / 100 : radarTrack.CorrectedAltitude / 100; - int cfl; - bool isCfl = Int32.TryParse(flightDataRecord.CFLString, out cfl); bool isEastBound = true; eastboundCallsigns.TryGetValue(flightDataRecord.Callsign, out isEastBound); + int prl = flightDataRecord.PRL / 100; + int cfl = flightDataRecord.CFLUpper / 100; + int rfl = flightDataRecord.RFL / 100; + int alt = flightDataRecord.CFLUpper == -1 ? rfl : cfl; if (flightDataRecord == null) return null; @@ -317,6 +323,42 @@ public CustomStripItem GetCustomStripItem(string itemType, Track track, FDP2.FDR return null; + case STRIP_ITEM_CLEARED_LEVEL: + + if (cfl == 0) + { + return new CustomStripItem() + { + Text = "" + }; + } + + else + { + return new CustomStripItem() + { + Text = cfl.ToString() + }; + } + + case STRIP_ITEM_REQUESTED_LEVEL: + + if (flightDataRecord.State == FDR.FDRStates.STATE_INACTIVE || flightDataRecord.State == FDR.FDRStates.STATE_INACTIVE) + { + return new CustomStripItem() + { + Text = rfl.ToString(), + }; + } + + else + { + return new CustomStripItem() + { + Text = "" + }; + } + //case STRIP_ITEM_MAN_EST: //if (Estimates) @@ -399,6 +441,14 @@ public CustomStripItem GetCustomStripItem(string itemType, Track track, FDP2.FDR return null; + case STRIP_ITEM_CLRD_RTE: + + return new CustomStripItem() + { + Text = "Cleared Route:" + flightDataRecord.RouteNoParse + }; + + default: return null; } } From 7bdfa49494d864673c78a5dfdddaafb576d5a753 Mon Sep 17 00:00:00 2001 From: Dominic Nguyen Date: Sun, 17 Dec 2023 18:01:56 -0800 Subject: [PATCH 33/76] External TOC/CPAR --- CPAR.cs | 13 +++++------ TOC.cs | 71 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 77 insertions(+), 7 deletions(-) create mode 100644 TOC.cs diff --git a/CPAR.cs b/CPAR.cs index e0839a5..5eb4bde 100644 --- a/CPAR.cs +++ b/CPAR.cs @@ -13,23 +13,22 @@ namespace vatsys { public class CPAR { - public List Segments = new List(); + public List Segments1 = new List(); + public List Segments2 = new List(); public DateTime Timeout = DateTime.MaxValue; - public CPAR(Track track1, Track track2, int value) => this.CalculateLATC(track1, track2, value); + public CPAR(FDP2.FDR fdr1, FDP2.FDR fdr2, int value) => this.CalculateLATC(fdr1, fdr2, value); public CPAR() { } - private void CalculateLATC(Track track1, Track track2, int value) + public void CalculateLATC(FDP2.FDR fdr1, FDP2.FDR fdr2, int value) { - FDP2.FDR fdr1 = track1.GetFDR(); - FDP2.FDR fdr2 = track2.GetFDR(); if (fdr1 == null || fdr2 == null) return; - this.Segments.AddRange((IEnumerable)this.CalculateAreaOfConflict(fdr1, fdr2, value)); - this.Segments.AddRange((IEnumerable)this.CalculateAreaOfConflict(fdr2, fdr1, value)); + this.Segments1.AddRange((IEnumerable)this.CalculateAreaOfConflict(fdr1, fdr2, value)); + this.Segments2.AddRange((IEnumerable)this.CalculateAreaOfConflict(fdr2, fdr1, value)); } public List CalculateAreaOfConflict(FDP2.FDR fdr1, FDP2.FDR fdr2, int value) diff --git a/TOC.cs b/TOC.cs new file mode 100644 index 0000000..01bbfc6 --- /dev/null +++ b/TOC.cs @@ -0,0 +1,71 @@ +#region Assembly vatSys, Version=0.4.8114.34539, Culture=neutral, PublicKeyToken=null +// E:\vatsys\bin\vatSys.exe +// Decompiled with ICSharpCode.Decompiler 7.1.0.6543 +#endregion + +using System; +using System.Collections.Generic; +using System.ComponentModel; +using System.Drawing; +using System.Linq; + + +namespace vatsys +{ + public class TOC + { + public FDP2.FDR fdr; + + public List sectors; + + public SectorsVolumes.Sector nextSector; + + public TOC(FDP2.FDR fdr) + { + this.fdr = fdr; + FDP2.FDR.ExtractedRoute.Segment segment = (from s in fdr.ParsedRoute.ToList() + where s.Type == FDP2.FDR.ExtractedRoute.Segment.SegmentTypes.ZPOINT && fdr.ControllingSector != SectorsVolumes.FindSector((SectorsVolumes.Volume)s.Tag) + select s).FirstOrDefault((FDP2.FDR.ExtractedRoute.Segment s) => s.ETO > DateTime.UtcNow); + SectorsVolumes.Volume volume = null; + if (segment != null) + { + volume = (SectorsVolumes.Volume)segment.Tag; + } + + if (volume != null) + { + nextSector = SectorsVolumes.FindSector(volume); + } + else + { + nextSector = null; + } + + if (nextSector != null) + { + SectorsVolumes.Sector sector = null; + foreach (SectorsVolumes.Sector s2 in SectorsVolumes.SectorGroupings.Keys) + { + if (s2.SubSectors.Contains(nextSector) && (sector == null || sector.SubSectors.Count > s2.SubSectors.Count)) + { + sector = s2; + } + } + if (sector != null) + { + nextSector = sector; + } + } + + } + public void HandoffNextSector() + { + if (nextSector != null) + { + MMI.HandoffJurisdiction(fdr, nextSector); + } + } + } + } + + From 0a3d2985b586062778d2a745a777a506d0056702 Mon Sep 17 00:00:00 2001 From: Dominic Nguyen Date: Thu, 1 Feb 2024 05:29:41 -0800 Subject: [PATCH 34/76] Moved CPAR elements to prep for CPAR display --- AdvancedTechnologyOceanicProcedures.csproj | 71 +++++ AuroraLabelItemsPlugin.cs | 325 ++++++--------------- AuroraStripItemPlugin.cs | 59 +++- CPAR.cs | 210 +++++++++++++ 4 files changed, 418 insertions(+), 247 deletions(-) create mode 100644 AdvancedTechnologyOceanicProcedures.csproj diff --git a/AdvancedTechnologyOceanicProcedures.csproj b/AdvancedTechnologyOceanicProcedures.csproj new file mode 100644 index 0000000..483638a --- /dev/null +++ b/AdvancedTechnologyOceanicProcedures.csproj @@ -0,0 +1,71 @@ + + + + + Debug + AnyCPU + {59170BAC-129C-4AB8-884D-F583E460AA63} + Library + Properties + AuroraLabelItemsPlugin + AdvancedTechnologyOceanicProcedures + v4.7.2 + 512 + true + + + true + full + false + bin\Debug\ + DEBUG;TRACE + prompt + 4 + x86 + + + pdbonly + true + bin\Release\ + TRACE + prompt + 4 + x86 + + + + + + + + + + + + + + + False + E:\vatsys\bin\vatSys.exe + + + + + + + designer + + + ConflictSummaryWindw.cs + + + + + + + + ConflictSummaryWindw.cs + + + + \ No newline at end of file diff --git a/AuroraLabelItemsPlugin.cs b/AuroraLabelItemsPlugin.cs index dea458a..ffd66bb 100644 --- a/AuroraLabelItemsPlugin.cs +++ b/AuroraLabelItemsPlugin.cs @@ -8,9 +8,10 @@ using vatsys.Plugin; using static vatsys.FDP2; using static vatsys.SectorsVolumes; -using static vatsys.Network; using System.Collections.Generic; -using System.Net; +using System.Runtime.CompilerServices; + + @@ -41,6 +42,7 @@ public class AuroraLabelItemsPlugin : ILabelPlugin const string LABEL_ITEM_INHIBIT_IND = "AURORA_INHIBIT_IND"; //field l(1) const string LABEL_ITEM_FILED_SPEED = "AURORA_FILEDSPEED"; //field m(4) const string LABEL_ITEM_3DIGIT_GROUNDSPEED = "AURORA_GROUNDSPEED"; //field n(5) + const string LABEL_ITEM_DESTINATION = "AURORA_DESTINATION"; //field o(4) readonly static CustomColour EastboundColour = new CustomColour(240, 255, 255); readonly static CustomColour WestboundColour = new CustomColour(240, 231, 140); readonly static CustomColour NonRVSM = new CustomColour(242, 133, 0); @@ -49,6 +51,7 @@ public class AuroraLabelItemsPlugin : ILabelPlugin readonly static CustomColour Advisory = new CustomColour(255, 165, 0); readonly static CustomColour Imminent = new CustomColour(255, 0, 0); readonly static CustomColour SpecialConditionCode = new CustomColour(255, 255, 0); + readonly static CustomColour ApsBlue = new CustomColour(141, 182, 205); readonly ConcurrentDictionary eastboundCallsigns = new ConcurrentDictionary(); readonly ConcurrentDictionary adsbcpdlcValues = new ConcurrentDictionary(); readonly ConcurrentDictionary adsflagValues = new ConcurrentDictionary(); @@ -58,9 +61,9 @@ public class AuroraLabelItemsPlugin : ILabelPlugin readonly ConcurrentDictionary radartoggle = new ConcurrentDictionary(); readonly ConcurrentDictionary mntflagtoggle = new ConcurrentDictionary(); readonly ConcurrentDictionary downlink = new ConcurrentDictionary(); - readonly ConcurrentDictionary> advisoryConflict = new ConcurrentDictionary>(); - readonly ConcurrentDictionary> imminentConflict = new ConcurrentDictionary>(); - + public readonly ConcurrentDictionary> advisoryConflict = new ConcurrentDictionary>(); + public readonly ConcurrentDictionary> imminentConflict = new ConcurrentDictionary>(); + public readonly ConcurrentDictionary> conflictData = new ConcurrentDictionary>(); public AuroraLabelItemsPlugin() @@ -222,21 +225,23 @@ public void OnFDRUpdate(FDP2.FDR updated) TransferOfControl(updated); - if (jet & rnp4 & cpdlc & adsc) ///Using CalculateAreaofConflict method + CPAR cpar = new CPAR(); + + if (jet & rnp4 & cpdlc & adsc) ///Using CalculateAreaofConflict method against intruder aircraft { - ConflictProbe(updated, 23); + cpar.ConflictProbe(updated, 23); } else if (rnp4 || rnp10) { - ConflictProbe(updated, 50); + cpar.ConflictProbe(updated, 50); } else if (rnp10) { - ConflictProbe(updated, 75); + cpar.ConflictProbe(updated, 75); } else { - ConflictProbe(updated, 100); + cpar.ConflictProbe(updated, 100); } } } @@ -282,7 +287,7 @@ private static void TransferOfControl(FDP2.FDR fdr) if (MMI.GetSectorEntryTime(fdr) == DateTime.MaxValue && MMI.SectorsControlled.ToList().TrueForAll(s => !s.IsInSector(fdr.GetLocation(), fdr.PRL))) // && whichFIR != fdr.ControllingSector { - toc.HandoffNextSector(); + //toc.HandoffNextSector(); MMI.HandoffJurisdiction(fdr, whichFIR); MMI.Inhibit(fdr); Thread.Sleep(300000); @@ -301,7 +306,8 @@ private static void TransferOfControl(FDP2.FDR fdr) // string text = "NEXT DATA AUTHORITY KZAK"; // if (freq.AliasFrequency != VSCSFrequency.None.Frequency) // { - // text = text + " (" + Conversions.FrequencyToString(freq.AliasFrequency) + ")"; + // text = text + " (" + Conversions.FrequencyToString(freq.AliasFrequency) + ")"; + //Network.Instance.SendRadioMessage(radioMessage.FSDFrequencies, radioMessage.Address, "Unable", ThisRequiresResponse: false, radioMessage, CloseRequest: true); // } // // network.SendTextMessage(pilot.Callsign, text); @@ -309,211 +315,6 @@ private static void TransferOfControl(FDP2.FDR fdr) // } //} - public void ConflictProbe(FDP2.FDR fdr, int value) - { - if ((fdr == null) || !MMI.IsMySectorConcerned(fdr)) return; - int cfl = fdr.CFLUpper; - int rfl = fdr.RFL; - int alt = cfl == -1 ? rfl : cfl; - var isRvsm = fdr.RVSM; - - foreach (var fdr2 in FDP2.GetFDRs) - { - if (fdr2 == null || fdr.Callsign == fdr2.Callsign || !MMI.IsMySectorConcerned(fdr2)) continue; - var rte = fdr.ParsedRoute; - var rte2 = fdr2.ParsedRoute; - double trk = Conversions.CalculateTrack(rte.First().Intersection.LatLong, - rte.Last().Intersection.LatLong); - double trk2 = Conversions.CalculateTrack(rte2.First().Intersection.LatLong, - rte2.Last().Intersection.LatLong); - var trkdelta = Math.Abs(trk2 - trk); - bool sameDir = trkdelta < 45; - bool crossing = (trkdelta >= 45 && trkdelta <= 135) || (trkdelta >= 315 && trkdelta <= 225); - bool oppoDir = trkdelta > 135 && trkdelta < 225; - int cfl2 = fdr2.CFLUpper; - int rfl2 = fdr2.RFL; - int alt2 = cfl2 == -1 ? rfl2 : cfl2; - var isRvsm2 = fdr2.RVSM; - var delta = Math.Abs(alt - alt2); - int verticalSep = (alt > 45000 && alt < 60000) ? 4000 : alt > 60000 ? 5000 : (alt2 > 45000 && alt2 < 60000) ? 4000 : alt2 > 60000 ? 5000 : - (alt > FDP2.RVSM_BAND_LOWER && !isRvsm) || - (alt2 > FDP2.RVSM_BAND_LOWER && !isRvsm2) || (alt > FDP2.RVSM_BAND_UPPER || alt2 > FDP2.RVSM_BAND_UPPER) - ? 2000 - : 1000; - - if (delta < verticalSep) - { - Match pbn2 = Regex.Match(fdr2.Remarks, @"PBN\/\w+\s"); - bool rnp10 = pbn2.Value.Contains("A1"); - bool rnp4 = pbn2.Value.Contains("L1"); - bool cpdlc = (Regex.IsMatch(fdr2.AircraftEquip, @"J5") || Regex.IsMatch(fdr2.AircraftEquip, @"J7")); - bool adsc = Regex.IsMatch(fdr2.AircraftSurvEquip, @"D1"); - bool jet = fdr2.PerformanceData?.IsJet ?? false; - - var newValue = value; - - if (rnp4 && adsc && cpdlc) - { - newValue = Math.Max(newValue, 23); - } - - - else if (rnp10 && adsc && cpdlc) - { - newValue = Math.Max(newValue, 50); - } - - else - { - newValue = Math.Max(newValue, 100); - } - var cpar = new CPAR(fdr2, fdr, newValue); - var segments1 = cpar.Segments1; - var segments2 = cpar.Segments2; - - segments1.Sort((Comparison)((s, t) => s.startTime.CompareTo(t.startTime))); //sort by first conflict time - segments2.Sort((Comparison)((s, t) => s.startTime.CompareTo(t.startTime))); - - var firstConflictTime = segments1.FirstOrDefault(); - var firstConflictTime2 = segments2.FirstOrDefault(); - var isConflictPair = segments1.Count > 0; - if (firstConflictTime == null || firstConflictTime2 == null) continue; - - - var timeLongSame = sameDir && isConflictPair && firstConflictTime.endTime > DateTime.UtcNow - && (firstConflictTime2.startTime - firstConflictTime.startTime).Duration() < (jet ? (new TimeSpan(0, 0, 10, 0)) : (new TimeSpan(0, 0, 15, 0)));//check time based longitudinal for same direction - var timeLongCross = crossing && isConflictPair && firstConflictTime.endTime > DateTime.UtcNow - && (firstConflictTime2.startTime - firstConflictTime.startTime).Duration() < (new TimeSpan(0, 0, 15, 0)); - var distLongSame = sameDir && isConflictPair && firstConflictTime.endTime > DateTime.UtcNow - && Conversions.CalculateDistance(firstConflictTime.startLatlong, firstConflictTime2.startLatlong) - < (jet && rnp4 && cpdlc && adsc ? 30 : (rnp4 || rnp10) ? 50 : 50); - - var timeLongOpposite = false; - TimeOfPassing top = null; - - if (isConflictPair && oppoDir) - { - try - { - top = new TimeOfPassing(fdr, fdr2); - } - - catch (Exception e) - { - return; - } - timeLongOpposite = top.Time > DateTime.UtcNow - && (top.Time.Add(new TimeSpan(0, 0, 10, 0)) > DateTime.UtcNow) && (top.Time.Subtract(new TimeSpan(0, 0, 10, 0)) < DateTime.UtcNow); - } - - - - - //var distLongOpposite = oppoDir && isConflictPair && firstConflictTime.endTime > DateTime.UtcNow - // && Conversions.CalculateDistance(firstConflictTime.endLatlong, firstConflictTime.endLatlong) - // < (jet && rnp4 && cpdlc && adsc ? 30 : (rnp4 || rnp10) ? 50 : 50); - - - var lossOfSep = timeLongSame || timeLongCross || distLongSame || timeLongOpposite; // || distLongOpposite - var earliestLOS = (isConflictPair && oppoDir ? top.Time.Subtract(new TimeSpan(0, 0, 10, 0)) - : (DateTime.Compare(firstConflictTime.startTime, firstConflictTime2.startTime) < 0 ? firstConflictTime.startTime : firstConflictTime2.startTime)); - var imminentConflicts = (isConflictPair && oppoDir && (delta < verticalSep)) ? (new TimeSpan(0, 0, 30, 0, 0) >= earliestLOS.Subtract(DateTime.UtcNow).Duration()) - : (lossOfSep && new TimeSpan(0, 0, 30, 0, 0) >= earliestLOS.Subtract(DateTime.UtcNow).Duration()); //check if timediff < 30 mins - var advisoryConflicts = (isConflictPair && oppoDir && (delta < verticalSep)) ? (new TimeSpan(0, 2, 0, 0, 0) > earliestLOS.Subtract(DateTime.UtcNow).Duration()) - && (earliestLOS.Subtract(DateTime.UtcNow).Duration() >= new TimeSpan(0, 0, 30, 0, 0)) - : (lossOfSep && new TimeSpan(0, 2, 0, 0, 0) > earliestLOS.Subtract(DateTime.UtcNow).Duration()) - && (earliestLOS.Subtract(DateTime.UtcNow).Duration() >= new TimeSpan(0, 0, 30, 0, 0)); //check if timediff < 2 hours - - - - if (imminentConflicts) - { - imminentConflict.AddOrUpdate(fdr.Callsign, new HashSet(new string[] { fdr2.Callsign }), - (k, v) => { v.Add(fdr2.Callsign); return v; }); - - - } - else - { - HashSet maybeSet; - bool exists = imminentConflict.TryGetValue(fdr.Callsign, out maybeSet); - if (exists) - { - maybeSet.Clear(); - } - - - var emptyImminentConflicts = imminentConflict.Where(pair => pair.Value.Count == 0) - .Select(pair => pair.Key) - .ToList(); - foreach (var callsign in emptyImminentConflicts) - { - imminentConflict.TryRemove(callsign, out _); - } - - - - if (advisoryConflicts) - { - advisoryConflict.AddOrUpdate(fdr.Callsign, new HashSet(new string[] { fdr2.Callsign }), - (k, v) => { v.Add(fdr2.Callsign); return v; }); - - } - else - { - HashSet admaybeSet; - bool adexists = advisoryConflict.TryGetValue(fdr.Callsign, out admaybeSet); - if (adexists) - { - admaybeSet.Clear(); - } - - var emptyAdvisoryConflicts = advisoryConflict.Where(pair => pair.Value.Count == 0) - .Select(pair => pair.Key) - .ToList(); - foreach (var callsign in emptyAdvisoryConflicts) - { - advisoryConflict.TryRemove(callsign, out _); - } - - } - - } - } - else - { - HashSet maybeSet; // defines an uninitialized variable for the result of the below method to get placed in - HashSet admaybeSet; - bool adexists = advisoryConflict.TryGetValue(fdr.Callsign, out admaybeSet); - bool exists = imminentConflict.TryGetValue(fdr.Callsign, out maybeSet); // tries to get the set of conflicts corresponding to a callsign, places it in the `maybeSet` variable if it exists. The bool `exists` represents whether there was a set of conflicts for that callsign - if (exists) - { - maybeSet.Remove(fdr2.Callsign); // remove the fdr2 (which is the one we are currently evaluating for conflicts against fdr) from the set of conflicts - } - if (adexists) - { - admaybeSet.Remove(fdr2.Callsign); // remove the fdr2 (which is the one we are currently evaluating for conflicts against fdr) from the set of conflicts - } - - var emptyAdvisoryConflicts = advisoryConflict.Where(pair => pair.Value.Count == 0) - .Select(pair => pair.Key) - .ToList(); - foreach (var callsign in emptyAdvisoryConflicts) - { - advisoryConflict.TryRemove(callsign, out _); - } - var emptyImminentConflicts = imminentConflict.Where(pair => pair.Value.Count == 0) - .Select(pair => pair.Key) - .ToList(); - foreach (var callsign in emptyImminentConflicts) - { - imminentConflict.TryRemove(callsign, out _); - } - } - } - } - - @@ -574,6 +375,7 @@ public CustomLabelItem GetCustomLabelItem(string itemType, Track track, FDP2.FDR int alt = flightDataRecord.CFLUpper == -1 ? rfl : cfl; var notProbe = flightDataRecord.State == (FDR.FDRStates.STATE_PREACTIVE | FDR.FDRStates.STATE_COORDINATED) ? BorderFlags.All : BorderFlags.None; var colour = (!flightDataRecord.RVSM ? NonRVSM : ExcludeConflictColor(track, flightDataRecord)); + var excludeConflict = (SelectASDTrackColour(track) == GetConflictColour(flightDataRecord.Callsign)); switch (itemType) @@ -586,7 +388,7 @@ public CustomLabelItem GetCustomLabelItem(string itemType, Track track, FDP2.FDR return new CustomLabelItem() { - Text = " ", + Text = "", Border = BorderFlags.Bottom }; } @@ -599,7 +401,7 @@ public CustomLabelItem GetCustomLabelItem(string itemType, Track track, FDP2.FDR { return new CustomLabelItem() { - Text = " ", + Text = "", Border = BorderFlags.Left }; } @@ -612,16 +414,19 @@ public CustomLabelItem GetCustomLabelItem(string itemType, Track track, FDP2.FDR { return new CustomLabelItem() { - Text = "▽", //▼ - BackColourIdentity = Colours.Identities.Jurisdiction, - //Border = BorderFlags.All - }; + Text = "▼", + Border = BorderFlags.All, + ForeColourIdentity = excludeConflict ? Colours.Identities.Custom : default, + CustomForeColour = ExcludeConflictColor(track, flightDataRecord) + }; } else { return new CustomLabelItem() { Text = "⬜", + ForeColourIdentity = excludeConflict ? Colours.Identities.Custom : default, + CustomForeColour = ExcludeConflictColor(track, flightDataRecord) }; } case LABEL_ITEM_ADSB_CPDLC: @@ -643,6 +448,8 @@ public CustomLabelItem GetCustomLabelItem(string itemType, Track track, FDP2.FDR return new CustomLabelItem() { Text = c1.ToString(), + ForeColourIdentity = excludeConflict ? Colours.Identities.Custom : default, + CustomForeColour = ExcludeConflictColor(track, flightDataRecord) }; } @@ -651,6 +458,8 @@ public CustomLabelItem GetCustomLabelItem(string itemType, Track track, FDP2.FDR return new CustomLabelItem() { Text = c2.ToString(), + ForeColourIdentity = excludeConflict ? Colours.Identities.Custom : default, + CustomForeColour = ExcludeConflictColor(track, flightDataRecord) }; @@ -661,6 +470,8 @@ public CustomLabelItem GetCustomLabelItem(string itemType, Track track, FDP2.FDR return new CustomLabelItem() { Text = c3.ToString(), + ForeColourIdentity = excludeConflict ? Colours.Identities.Custom : default, + CustomForeColour = ExcludeConflictColor(track, flightDataRecord) }; } @@ -691,6 +502,8 @@ public CustomLabelItem GetCustomLabelItem(string itemType, Track track, FDP2.FDR return new CustomLabelItem() { Text = "◦", + ForeColourIdentity = excludeConflict ? Colours.Identities.Custom : default, + CustomForeColour = ExcludeConflictColor(track, flightDataRecord) }; } @@ -699,6 +512,8 @@ public CustomLabelItem GetCustomLabelItem(string itemType, Track track, FDP2.FDR return new CustomLabelItem() { Text = "&", + ForeColourIdentity = excludeConflict ? Colours.Identities.Custom : default, + CustomForeColour = ExcludeConflictColor(track, flightDataRecord) }; } @@ -710,6 +525,8 @@ public CustomLabelItem GetCustomLabelItem(string itemType, Track track, FDP2.FDR return new CustomLabelItem() { Text = "x", + ForeColourIdentity = excludeConflict ? Colours.Identities.Custom : default, + CustomForeColour = ExcludeConflictColor(track, flightDataRecord) }; return null; @@ -724,18 +541,19 @@ public CustomLabelItem GetCustomLabelItem(string itemType, Track track, FDP2.FDR Text = level.ToString(), Border = notProbe, BorderColourIdentity = Colours.Identities.Custom, - CustomBorderColour = NotCDA - }; + CustomBorderColour = NotCDA, + ForeColourIdentity = excludeConflict ? Colours.Identities.Custom : default, + CustomForeColour = colour + + }; case LABEL_ITEM_VMI: return new CustomLabelItem() { Text = h1.ToString(), - ForeColourIdentity = isNonRVSM - ? Colours.Identities.Custom - : default, - CustomForeColour = NonRVSM + ForeColourIdentity = excludeConflict ? Colours.Identities.Custom : default, + CustomForeColour = colour }; @@ -743,7 +561,7 @@ public CustomLabelItem GetCustomLabelItem(string itemType, Track track, FDP2.FDR case LABEL_ITEM_CLEARED_LEVEL: - if (radarTrack.ReachedCFL || prl == alt || Math.Abs(flightDataRecord.PRL - alt) <= 299) + if (radarTrack.ReachedCFL || prl == alt || Math.Abs(flightDataRecord.PRL - alt) < 300) return new CustomLabelItem() { Text = "" @@ -756,7 +574,9 @@ public CustomLabelItem GetCustomLabelItem(string itemType, Track track, FDP2.FDR Text = alt.ToString(), Border = notProbe, BorderColourIdentity = Colours.Identities.Custom, - CustomBorderColour = NotCDA + CustomBorderColour = NotCDA, + ForeColourIdentity = excludeConflict ? Colours.Identities.Custom : default, + CustomForeColour = colour }; } @@ -796,6 +616,8 @@ public CustomLabelItem GetCustomLabelItem(string itemType, Track track, FDP2.FDR { Text = "★", OnMouseClick = HandleRadarFlagClick, + ForeColourIdentity = excludeConflict ? Colours.Identities.Custom : default, + CustomForeColour = ExcludeConflictColor(track, flightDataRecord) }; } @@ -805,6 +627,8 @@ public CustomLabelItem GetCustomLabelItem(string itemType, Track track, FDP2.FDR { Text = "◦", OnMouseClick = HandleRadarFlagClick, + ForeColourIdentity = excludeConflict ? Colours.Identities.Custom : default, + CustomForeColour = ExcludeConflictColor(track, flightDataRecord) }; } @@ -816,6 +640,8 @@ public CustomLabelItem GetCustomLabelItem(string itemType, Track track, FDP2.FDR return new CustomLabelItem() { Text = "^", + ForeColourIdentity = excludeConflict ? Colours.Identities.Custom : default, + CustomForeColour = ExcludeConflictColor(track, flightDataRecord) }; } @@ -834,7 +660,7 @@ public CustomLabelItem GetCustomLabelItem(string itemType, Track track, FDP2.FDR { Text = "M" + Convert.ToDecimal(mach).ToString("F2").Replace(".", ""), //Text = "N" + flightDataRecord.TAS - ForeColourIdentity = Colours.Identities.Custom, + ForeColourIdentity = excludeConflict ? Colours.Identities.Custom : default, CustomForeColour = ExcludeConflictColor(track, flightDataRecord) }; @@ -847,7 +673,16 @@ public CustomLabelItem GetCustomLabelItem(string itemType, Track track, FDP2.FDR return new CustomLabelItem() { Text = "N" + gs.ToString("000"),//format as 3 digits (with leading zeros) - ForeColourIdentity = Colours.Identities.Custom, + ForeColourIdentity = excludeConflict ? Colours.Identities.Custom : default, + CustomForeColour = ExcludeConflictColor(track, flightDataRecord) + }; + + case LABEL_ITEM_DESTINATION: + + return new CustomLabelItem() + { + Text = flightDataRecord.DesAirport, + ForeColourIdentity = excludeConflict ? Colours.Identities.Custom : default, CustomForeColour = ExcludeConflictColor(track, flightDataRecord) }; @@ -869,7 +704,7 @@ public CustomColour SelectASDTrackColour(Track track) if (track.State == MMI.HMIStates.Jurisdiction) //read our dictionary of stored bools (true means is easterly) and return the correct colour { - return GetConflictColour(fdr.Callsign) ?? GetDirectionColour(fdr.Callsign); + return GetConflictColour(fdr.Callsign) ?? GetDirectionColour(fdr.Callsign, fdr); } if (fdr.State != (FDR.FDRStates.STATE_PREACTIVE | FDR.FDRStates.STATE_COORDINATED)) //only apply conflict colours if planes are of concern @@ -879,7 +714,7 @@ public CustomColour SelectASDTrackColour(Track track) else - return null; + return default; } @@ -888,7 +723,7 @@ public CustomColour SelectGroundTrackColour(Track track) return null; } - private CustomColour GetDirectionColour(string callsign) + private CustomColour GetDirectionColour(string callsign, FDR fdr) { if (eastboundCallsigns.TryGetValue(callsign, out bool east)) { @@ -898,30 +733,34 @@ private CustomColour GetDirectionColour(string callsign) return WestboundColour; } - return null; + return default; } private CustomColour GetConflictColour(string callsign) { - if (imminentConflict.TryGetValue(callsign, out _)) + if (imminentConflict.Count % 2 == 0 && imminentConflict.TryGetValue(callsign, out _)) { return Imminent; } - else if (advisoryConflict.TryGetValue(callsign, out _)) + else if (advisoryConflict.Count % 2 == 0 && advisoryConflict.TryGetValue(callsign, out _)) { return Advisory; } - return null; + return default; } private CustomColour ExcludeConflictColor(Track track, FDP2.FDR flightDataRecord) { - if (SelectASDTrackColour(track) == GetConflictColour(flightDataRecord.Callsign)) + if ((imminentConflict.Count > 0 || advisoryConflict.Count > 0) && track.State == MMI.HMIStates.Jurisdiction) { - return null; + return GetDirectionColour(flightDataRecord.Callsign, flightDataRecord); + } + else if (imminentConflict.Count > 0 || advisoryConflict.Count > 0) + { + return ApsBlue; } - return SelectASDTrackColour(track); + return default; } diff --git a/AuroraStripItemPlugin.cs b/AuroraStripItemPlugin.cs index c55ff9d..166de59 100644 --- a/AuroraStripItemPlugin.cs +++ b/AuroraStripItemPlugin.cs @@ -5,8 +5,6 @@ using System.Collections.Concurrent; using System.ComponentModel.Composition; //<--Need to add a reference to System.ComponentModel.Composition using static vatsys.FDP2; -using System.Security.Policy; - namespace AuroraStripItemsPlugin { @@ -14,7 +12,8 @@ namespace AuroraStripItemsPlugin public class AuroraStripItemsPlugin : IStripPlugin { - + AuroraLabelItemsPlugin.AuroraLabelItemsPlugin label = new AuroraLabelItemsPlugin.AuroraLabelItemsPlugin(); + CPAR cpar = new CPAR(); /// The name of the custom label item we've added to Labels /// in the Profile const string LABEL_ITEM_ADSB_CPDLC = "AURORA_ADSB_CPDLC"; //field c(4) @@ -37,6 +36,13 @@ public class AuroraStripItemsPlugin : IStripPlugin const string STRIP_ITEM_LATERAL_FLAG = "AURORA_LATERAL_FLAG"; const string STRIP_ITEM_RESTR = "AURORA_RESTR_STRIP"; const string STRIP_ITEM_CLRD_RTE = "AURORA_CLRD_RTE"; + const string CPAR_ITEM_INTRUDER = "CPAR_INT"; + const string CPAR_ITEM_ATT_INT = "CPAR_ATT_INT"; + const string CPAR_ITEM_ACTIVE = "CPAR_ACT"; + const string CPAR_ITEM_ATT_ACT = "CPAR_ATT_ACT"; + const string CPAR_ITEM_TYPE = "CPAR_TYP"; + const string CPAR_ITEM_STARTIME = "CPAR_START_TIME"; + const string CPAR_ITEM_ENDTIME = "CPAR_END_TIME"; readonly static CustomColour NonRVSM = new CustomColour(242, 133, 0); readonly static CustomColour SepFlags = new CustomColour(0, 196, 253); readonly static CustomColour Pending = new CustomColour(46, 139, 87); @@ -96,7 +102,7 @@ private void ItemMouseClick(CustomStripItemMouseClickEventArgs e) } public CustomStripItem GetCustomStripItem(string itemType, Track track, FDP2.FDR flightDataRecord, RDP.RadarTrack radarTrack) - { + { var pbn = Regex.Match(flightDataRecord.Remarks, @"PBN\/\w+\s"); bool rnp10 = pbn.Value.Contains("A1"); bool rnp4 = pbn.Value.Contains("L1"); @@ -448,6 +454,51 @@ public CustomStripItem GetCustomStripItem(string itemType, Track track, FDP2.FDR Text = "Cleared Route:" + flightDataRecord.RouteNoParse }; + case CPAR_ITEM_INTRUDER: + + return new CustomStripItem() + { + }; + + case CPAR_ITEM_ATT_INT: + + return new CustomStripItem() + { + }; + + case CPAR_ITEM_ACTIVE: + + if (label.imminentConflict.TryGetValue(flightDataRecord.Callsign, out _) || (label.advisoryConflict.TryGetValue(flightDataRecord.Callsign, out)) == flightDataRecord.Callsign; + + return new CustomStripItem() + { + Text = cpar.s + }; + + case CPAR_ITEM_ATT_ACT: + + return new CustomStripItem() + { + }; + + case CPAR_ITEM_TYPE: + + return new CustomStripItem() + { + }; + + case CPAR_ITEM_STARTIME: + + return new CustomStripItem() + { + }; + + case CPAR_ITEM_ENDTIME: + + return new CustomStripItem() + { + }; + default: return null; } diff --git a/CPAR.cs b/CPAR.cs index 5eb4bde..efa0d7a 100644 --- a/CPAR.cs +++ b/CPAR.cs @@ -8,6 +8,7 @@ using System; using System.Collections.Generic; using System.Linq; +using System.Text.RegularExpressions; namespace vatsys { @@ -15,6 +16,7 @@ public class CPAR { public List Segments1 = new List(); public List Segments2 = new List(); + AuroraLabelItemsPlugin.AuroraLabelItemsPlugin label = new AuroraLabelItemsPlugin.AuroraLabelItemsPlugin(); public DateTime Timeout = DateTime.MaxValue; public CPAR(FDP2.FDR fdr1, FDP2.FDR fdr2, int value) => this.CalculateLATC(fdr1, fdr2, value); @@ -159,5 +161,213 @@ public class Segment public DateTime endTime = DateTime.MaxValue; public FDP2.FDR.ExtractedRoute.Segment routeSegment; } + public void ConflictProbe(FDP2.FDR fdr, int latSep1) + { + if ((fdr == null) || !MMI.IsMySectorConcerned(fdr)) return; + int cfl = fdr.CFLUpper; + int rfl = fdr.RFL; + int alt = cfl == -1 ? rfl : cfl; + var isRvsm = fdr.RVSM; + + foreach (var fdr2 in FDP2.GetFDRs) + { + if (fdr2 == null || fdr.Callsign == fdr2.Callsign || !MMI.IsMySectorConcerned(fdr2)) continue; + var rte = fdr.ParsedRoute; + var rte2 = fdr2.ParsedRoute; + double trk = Conversions.CalculateTrack(rte.First().Intersection.LatLong, + rte.Last().Intersection.LatLong); + double trk2 = Conversions.CalculateTrack(rte2.First().Intersection.LatLong, + rte2.Last().Intersection.LatLong); + var trkdelta = Math.Abs(trk2 - trk); + bool sameDir = trkdelta < 45; + bool crossing = (trkdelta >= 45 && trkdelta <= 135) || (trkdelta >= 315 && trkdelta <= 225); + bool oppoDir = trkdelta > 135 && trkdelta < 225; + int cfl2 = fdr2.CFLUpper; + int rfl2 = fdr2.RFL; + int alt2 = cfl2 == -1 ? rfl2 : cfl2; + var isRvsm2 = fdr2.RVSM; + var delta = Math.Abs(alt - alt2); + int verticalSep = (alt > 45000 && alt < 60000) ? 4000 : alt > 60000 ? 5000 : (alt2 > 45000 && alt2 < 60000) ? 4000 : alt2 > 60000 ? 5000 : + (alt > FDP2.RVSM_BAND_LOWER && !isRvsm) || + (alt2 > FDP2.RVSM_BAND_LOWER && !isRvsm2) || (alt > FDP2.RVSM_BAND_UPPER || alt2 > FDP2.RVSM_BAND_UPPER) + ? 2000 + : 1000; + + if (delta < verticalSep) + { + Match pbn2 = Regex.Match(fdr2.Remarks, @"PBN\/\w+\s"); + bool rnp10 = pbn2.Value.Contains("A1"); + bool rnp4 = pbn2.Value.Contains("L1"); + bool cpdlc = (Regex.IsMatch(fdr2.AircraftEquip, @"J5") || Regex.IsMatch(fdr2.AircraftEquip, @"J7")); + bool adsc = Regex.IsMatch(fdr2.AircraftSurvEquip, @"D1"); + bool jet = fdr2.PerformanceData?.IsJet ?? false; + + var newValue = latSep1; + + if (rnp4 && adsc && cpdlc) + { + newValue = Math.Max(latSep1, 23); + } + + + else if (rnp10 || rnp4) + { + newValue = Math.Max(latSep1, 50); + } + + else if (!rnp10 && !rnp4) + { + newValue = Math.Max(latSep1, 100); + } + + else if (newValue != latSep1 && newValue == 100); + { + newValue = (50 + 100) / 2; + } + + var cpar = new CPAR(fdr2, fdr, newValue); + var segments1 = cpar.Segments1; + var segments2 = cpar.Segments2; + + segments1.Sort((Comparison)((s, t) => s.startTime.CompareTo(t.startTime))); //sort by first conflict time + segments2.Sort((Comparison)((s, t) => s.startTime.CompareTo(t.startTime))); + + var firstConflictTime = segments1.FirstOrDefault(); + var firstConflictTime2 = segments2.FirstOrDefault(); + var isConflictPair = segments1.Count > 0; + if (firstConflictTime == null || firstConflictTime2 == null) continue; + + + var timeLongSame = sameDir && isConflictPair && firstConflictTime.endTime > DateTime.UtcNow + && (firstConflictTime2.startTime - firstConflictTime.startTime).Duration() < (jet ? (new TimeSpan(0, 0, 10, 0)) : (new TimeSpan(0, 0, 15, 0)));//check time based longitudinal for same direction + var timeLongCross = crossing && isConflictPair && firstConflictTime.endTime > DateTime.UtcNow + && (firstConflictTime2.startTime - firstConflictTime.startTime).Duration() < (new TimeSpan(0, 0, 15, 0)); + var distLongSame = sameDir && isConflictPair && firstConflictTime.endTime > DateTime.UtcNow + && Conversions.CalculateDistance(firstConflictTime.startLatlong, firstConflictTime2.startLatlong) + < (jet && rnp4 && cpdlc && adsc ? 30 : (rnp4 || rnp10) ? 50 : 50); + + var timeLongOpposite = false; + TimeOfPassing top = null; + + if (isConflictPair && oppoDir) + { + try + { + top = new TimeOfPassing(fdr, fdr2); + } + + catch (Exception e) + { + return; + } + timeLongOpposite = top.Time > DateTime.UtcNow + && (top.Time.Add(new TimeSpan(0, 0, 10, 0)) > DateTime.UtcNow) && (top.Time.Subtract(new TimeSpan(0, 0, 10, 0)) < DateTime.UtcNow); + } + + + var lossOfSep = timeLongSame || timeLongCross || distLongSame || timeLongOpposite; + + var earliestLOS = (isConflictPair && oppoDir ? top.Time.Subtract(new TimeSpan(0, 0, 10, 0)) + : (DateTime.Compare(firstConflictTime.startTime, firstConflictTime2.startTime) < 0 ? firstConflictTime.startTime : firstConflictTime2.startTime)); + + var actualConflicts = (isConflictPair && oppoDir && (delta < verticalSep)) ? (new TimeSpan(0, 0, 1, 0, 0) >= earliestLOS.Subtract(DateTime.UtcNow).Duration()) + : (lossOfSep && new TimeSpan(0, 0, 1, 0, 0) >= earliestLOS.Subtract(DateTime.UtcNow).Duration()) || earliestLOS < DateTime.UtcNow; + + var imminentConflicts = (isConflictPair && oppoDir && (delta < verticalSep)) ? (new TimeSpan(0, 0, 30, 0, 0) >= earliestLOS.Subtract(DateTime.UtcNow).Duration()) + : (lossOfSep && new TimeSpan(0, 0, 30, 0, 0) >= earliestLOS.Subtract(DateTime.UtcNow).Duration()); //check if timediff < 30 min + + var advisoryConflicts = (isConflictPair && oppoDir && (delta < verticalSep)) ? (new TimeSpan(0, 2, 0, 0, 0) > earliestLOS.Subtract(DateTime.UtcNow).Duration()) + && (earliestLOS.Subtract(DateTime.UtcNow).Duration() >= new TimeSpan(0, 0, 30, 0, 0)) + : (lossOfSep && new TimeSpan(0, 2, 0, 0, 0) > earliestLOS.Subtract(DateTime.UtcNow).Duration()) + && (earliestLOS.Subtract(DateTime.UtcNow).Duration() >= new TimeSpan(0, 0, 30, 0, 0)); //check if 2 hours > timediff > 30 mins + + + + if (actualConflicts || imminentConflicts) + { + label.imminentConflict.AddOrUpdate(fdr.Callsign, new HashSet(new string[] { fdr2.Callsign }), + (k, v) => { v.Add(fdr2.Callsign); return v; }); + + + } + else + { + HashSet maybeSet; + bool exists = label.imminentConflict.TryGetValue(fdr.Callsign, out maybeSet); + if (exists) + { + maybeSet.Clear(); + } + + + var emptyImminentConflicts = label.imminentConflict.Where(pair => pair.Value.Count == 0) + .Select(pair => pair.Key) + .ToList(); + foreach (var callsign in emptyImminentConflicts) + { + label.imminentConflict.TryRemove(callsign, out _); + } + + + + if (advisoryConflicts) + { + label.advisoryConflict.AddOrUpdate(fdr.Callsign, new HashSet(new string[] { fdr2.Callsign }), + (k, v) => { v.Add(fdr2.Callsign); return v; }); + + } + else + { + HashSet admaybeSet; + bool adexists = label.advisoryConflict.TryGetValue(fdr.Callsign, out admaybeSet); + if (adexists) + { + admaybeSet.Clear(); + } + + var emptyAdvisoryConflicts = label.advisoryConflict.Where(pair => pair.Value.Count == 0) + .Select(pair => pair.Key) + .ToList(); + foreach (var callsign in emptyAdvisoryConflicts) + { + label.advisoryConflict.TryRemove(callsign, out _); + } + + } + + } + } + else + { + HashSet maybeSet; // defines an uninitialized variable for the result of the below method to get placed in + HashSet admaybeSet; + bool adexists = label.advisoryConflict.TryGetValue(fdr.Callsign, out admaybeSet); + bool exists = label.imminentConflict.TryGetValue(fdr.Callsign, out maybeSet); // tries to get the set of conflicts corresponding to a callsign, places it in the `maybeSet` variable if it exists. The bool `exists` represents whether there was a set of conflicts for that callsign + if (exists) + { + maybeSet.Remove(fdr2.Callsign); // remove the fdr2 (which is the one we are currently evaluating for conflicts against fdr) from the set of conflicts + } + if (adexists) + { + admaybeSet.Remove(fdr2.Callsign); // remove the fdr2 (which is the one we are currently evaluating for conflicts against fdr) from the set of conflicts + } + + var emptyAdvisoryConflicts = label.advisoryConflict.Where(pair => pair.Value.Count == 0) + .Select(pair => pair.Key) + .ToList(); + foreach (var callsign in emptyAdvisoryConflicts) + { + label.advisoryConflict.TryRemove(callsign, out _); + } + var emptyImminentConflicts = label.imminentConflict.Where(pair => pair.Value.Count == 0) + .Select(pair => pair.Key) + .ToList(); + foreach (var callsign in emptyImminentConflicts) + { + label.imminentConflict.TryRemove(callsign, out _); + } + } + } + } } } From 815a5c02fb973d4ac9329020aae94726fcb50e80 Mon Sep 17 00:00:00 2001 From: Dominic Nguyen Date: Fri, 2 Feb 2024 05:42:54 -0800 Subject: [PATCH 35/76] Create public ConflictData variables --- AuroraLabelItemsPlugin.cs | 2 +- AuroraStripItemPlugin.cs | 192 ++++++++++++++++++++++++++++---------- CPAR.cs | 28 +++--- 3 files changed, 162 insertions(+), 60 deletions(-) diff --git a/AuroraLabelItemsPlugin.cs b/AuroraLabelItemsPlugin.cs index ffd66bb..495a900 100644 --- a/AuroraLabelItemsPlugin.cs +++ b/AuroraLabelItemsPlugin.cs @@ -63,7 +63,7 @@ public class AuroraLabelItemsPlugin : ILabelPlugin readonly ConcurrentDictionary downlink = new ConcurrentDictionary(); public readonly ConcurrentDictionary> advisoryConflict = new ConcurrentDictionary>(); public readonly ConcurrentDictionary> imminentConflict = new ConcurrentDictionary>(); - public readonly ConcurrentDictionary> conflictData = new ConcurrentDictionary>(); + public AuroraLabelItemsPlugin() diff --git a/AuroraStripItemPlugin.cs b/AuroraStripItemPlugin.cs index 166de59..c0ed8e8 100644 --- a/AuroraStripItemPlugin.cs +++ b/AuroraStripItemPlugin.cs @@ -5,6 +5,8 @@ using System.Collections.Concurrent; using System.ComponentModel.Composition; //<--Need to add a reference to System.ComponentModel.Composition using static vatsys.FDP2; +using System.Collections.Generic; +using System.Linq; namespace AuroraStripItemsPlugin { @@ -36,19 +38,31 @@ public class AuroraStripItemsPlugin : IStripPlugin const string STRIP_ITEM_LATERAL_FLAG = "AURORA_LATERAL_FLAG"; const string STRIP_ITEM_RESTR = "AURORA_RESTR_STRIP"; const string STRIP_ITEM_CLRD_RTE = "AURORA_CLRD_RTE"; - const string CPAR_ITEM_INTRUDER = "CPAR_INT"; - const string CPAR_ITEM_ATT_INT = "CPAR_ATT_INT"; - const string CPAR_ITEM_ACTIVE = "CPAR_ACT"; - const string CPAR_ITEM_ATT_ACT = "CPAR_ATT_ACT"; const string CPAR_ITEM_TYPE = "CPAR_TYP"; - const string CPAR_ITEM_STARTIME = "CPAR_START_TIME"; - const string CPAR_ITEM_ENDTIME = "CPAR_END_TIME"; + const string CPAR_ITEM_REQUIRED = "CPAR_REQUIRED"; + const string CPAR_ITEM_INTRUDER = "CPAR_INT"; + const string CPAR_ITEM_LOS = "CPAR_LOS"; + const string CPAR_ITEM_ACTUAL = "CPAR_ACTUAL"; + const string CPAR_ITEM_PASSING = "CPAR_PASSING"; + const string CPAR_ITEM_CONF_SEG_START_1 = "CPAR_CONF_SEG_START_1"; + const string CPAR_ITEM_CONF_SEG_START_2 = "CPAR_CONF_SEG_START_2"; + const string CPAR_ITEM_CONF_SEG_END_1 = "CPAR_CONF_SEG_END_1"; + const string CPAR_ITEM_CONF_SEG_END_2 = "CPAR_CONF_SEG_END_2"; + const string CPAR_ITEM_STARTIME_1 = "CPAR_START_TIME_1"; + const string CPAR_ITEM_STARTIME_2 = "CPAR_START_TIME_2"; + const string CPAR_ITEM_ENDTIME_1 = "CPAR_END_TIME_1"; + const string CPAR_ITEM_ENDTIME_2 = "CPAR_END_TIME_2"; + const string CPAR_ITEM_AID_2 = "CPAR_AID_2"; + const string CPAR_ITEM_TYP_2 = "CPAR_TYP_2"; + const string CPAR_ITEM_SPD_2 = "CPAR_SPD_2"; + const string CPAR_ITEM_ALT_2 = "CPAR_ALT_2"; readonly static CustomColour NonRVSM = new CustomColour(242, 133, 0); readonly static CustomColour SepFlags = new CustomColour(0, 196, 253); readonly static CustomColour Pending = new CustomColour(46, 139, 87); readonly static CustomColour NotCDA = new CustomColour(100, 0, 100); readonly ConcurrentDictionary eastboundCallsigns = new ConcurrentDictionary(); readonly ConcurrentDictionary flagtoggle = new ConcurrentDictionary(); + /// Plugin Name public string Name { get => "Aurora Label Items"; } @@ -454,51 +468,133 @@ public CustomStripItem GetCustomStripItem(string itemType, Track track, FDP2.FDR Text = "Cleared Route:" + flightDataRecord.RouteNoParse }; - case CPAR_ITEM_INTRUDER: - - return new CustomStripItem() - { - }; - - case CPAR_ITEM_ATT_INT: - - return new CustomStripItem() - { - }; - - case CPAR_ITEM_ACTIVE: - if (label.imminentConflict.TryGetValue(flightDataRecord.Callsign, out _) || (label.advisoryConflict.TryGetValue(flightDataRecord.Callsign, out)) == flightDataRecord.Callsign; - - return new CustomStripItem() - { - Text = cpar.s - }; - - case CPAR_ITEM_ATT_ACT: - - return new CustomStripItem() - { - }; - + case CPAR_ITEM_TYPE: - - return new CustomStripItem() - { - }; - - case CPAR_ITEM_STARTIME: - - return new CustomStripItem() - { - }; - - case CPAR_ITEM_ENDTIME: - - return new CustomStripItem() - { - }; + return new CustomStripItem() + { + Text = + }; + + case CPAR_ITEM_REQUIRED: + + return new CustomStripItem() + { + Text = cpar.Segments1[0].callsign + }; + + case CPAR_ITEM_INTRUDER: + + return new CustomStripItem() + { + Text = cpar.Segments1[0].callsign + }; + + case CPAR_ITEM_LOS: + + return new CustomStripItem() + { + Text = cpar.Segments1[0].callsign + }; + + case CPAR_ITEM_ACTUAL: + + return new CustomStripItem() + { + Text = cpar.Segments1[0].callsign + }; + + case CPAR_ITEM_PASSING: + + return new CustomStripItem() + { + Text = cpar.Segments1[0].callsign + }; + + case CPAR_ITEM_CONF_SEG_START_1: + + return new CustomStripItem() + { + Text = cpar.Segments1[0].startLatlong.ToString() + }; + + case CPAR_ITEM_CONF_SEG_START_2: + + return new CustomStripItem() + { + Text = cpar.Segments2[0].startLatlong.ToString() + }; + + case CPAR_ITEM_CONF_SEG_END_1: + + return new CustomStripItem() + { + Text = cpar.Segments1[0].endLatlong.ToString() + }; + + case CPAR_ITEM_CONF_SEG_END_2: + + return new CustomStripItem() + { + Text = cpar.Segments2[0].endLatlong.ToString() + }; + + case CPAR_ITEM_STARTIME_1: + + return new CustomStripItem() + { + Text = cpar.Segments1[0].startTime.ToString() + }; + + case CPAR_ITEM_STARTIME_2: + + return new CustomStripItem() + { + Text = cpar.Segments2[0].startTime.ToString() + }; + + case CPAR_ITEM_ENDTIME_1: + + return new CustomStripItem() + { + Text = cpar.Segments1[0].endTime.ToString() + }; + + case CPAR_ITEM_ENDTIME_2: + + return new CustomStripItem() + { + Text = cpar.Segments2[0].endTime.ToString() + }; + + case CPAR_ITEM_AID_2: + + return new CustomStripItem() + { + Text = cpar.Segments2[0].callsign + }; + + case CPAR_ITEM_TYP_2: + + return new CustomStripItem() + { + Text = + }; + + case CPAR_ITEM_SPD_2: + + return new CustomStripItem() + { + Text = + }; + + case CPAR_ITEM_ALT_2: + + return new CustomStripItem() + { + Text = + }; default: return null; } diff --git a/CPAR.cs b/CPAR.cs index efa0d7a..9c343e4 100644 --- a/CPAR.cs +++ b/CPAR.cs @@ -6,6 +6,7 @@ // XML documentation location: E:\vatsys\bin\vatSys.xml using System; +using System.Collections.Concurrent; using System.Collections.Generic; using System.Linq; using System.Text.RegularExpressions; @@ -20,7 +21,6 @@ public class CPAR public DateTime Timeout = DateTime.MaxValue; public CPAR(FDP2.FDR fdr1, FDP2.FDR fdr2, int value) => this.CalculateLATC(fdr1, fdr2, value); - public CPAR() { } @@ -161,6 +161,13 @@ public class Segment public DateTime endTime = DateTime.MaxValue; public FDP2.FDR.ExtractedRoute.Segment routeSegment; } + + public class ConflictData + { + public string callsign; + public bool sameDir; + public + } public void ConflictProbe(FDP2.FDR fdr, int latSep1) { if ((fdr == null) || !MMI.IsMySectorConcerned(fdr)) return; @@ -234,22 +241,22 @@ public void ConflictProbe(FDP2.FDR fdr, int latSep1) var firstConflictTime = segments1.FirstOrDefault(); var firstConflictTime2 = segments2.FirstOrDefault(); - var isConflictPair = segments1.Count > 0; + var failedLateral = segments1.Count > 0; if (firstConflictTime == null || firstConflictTime2 == null) continue; - var timeLongSame = sameDir && isConflictPair && firstConflictTime.endTime > DateTime.UtcNow + var timeLongSame = sameDir && failedLateral && firstConflictTime.endTime > DateTime.UtcNow && (firstConflictTime2.startTime - firstConflictTime.startTime).Duration() < (jet ? (new TimeSpan(0, 0, 10, 0)) : (new TimeSpan(0, 0, 15, 0)));//check time based longitudinal for same direction - var timeLongCross = crossing && isConflictPair && firstConflictTime.endTime > DateTime.UtcNow + var timeLongCross = crossing && failedLateral && firstConflictTime.endTime > DateTime.UtcNow && (firstConflictTime2.startTime - firstConflictTime.startTime).Duration() < (new TimeSpan(0, 0, 15, 0)); - var distLongSame = sameDir && isConflictPair && firstConflictTime.endTime > DateTime.UtcNow + var distLongSame = sameDir && failedLateral && firstConflictTime.endTime > DateTime.UtcNow && Conversions.CalculateDistance(firstConflictTime.startLatlong, firstConflictTime2.startLatlong) < (jet && rnp4 && cpdlc && adsc ? 30 : (rnp4 || rnp10) ? 50 : 50); var timeLongOpposite = false; TimeOfPassing top = null; - if (isConflictPair && oppoDir) + if (failedLateral && oppoDir) { try { @@ -267,16 +274,16 @@ public void ConflictProbe(FDP2.FDR fdr, int latSep1) var lossOfSep = timeLongSame || timeLongCross || distLongSame || timeLongOpposite; - var earliestLOS = (isConflictPair && oppoDir ? top.Time.Subtract(new TimeSpan(0, 0, 10, 0)) + var earliestLOS = (failedLateral && oppoDir ? top.Time.Subtract(new TimeSpan(0, 0, 10, 0)) : (DateTime.Compare(firstConflictTime.startTime, firstConflictTime2.startTime) < 0 ? firstConflictTime.startTime : firstConflictTime2.startTime)); - var actualConflicts = (isConflictPair && oppoDir && (delta < verticalSep)) ? (new TimeSpan(0, 0, 1, 0, 0) >= earliestLOS.Subtract(DateTime.UtcNow).Duration()) + var actualConflicts = (failedLateral && oppoDir && (delta < verticalSep)) ? (new TimeSpan(0, 0, 1, 0, 0) >= earliestLOS.Subtract(DateTime.UtcNow).Duration()) : (lossOfSep && new TimeSpan(0, 0, 1, 0, 0) >= earliestLOS.Subtract(DateTime.UtcNow).Duration()) || earliestLOS < DateTime.UtcNow; - var imminentConflicts = (isConflictPair && oppoDir && (delta < verticalSep)) ? (new TimeSpan(0, 0, 30, 0, 0) >= earliestLOS.Subtract(DateTime.UtcNow).Duration()) + var imminentConflicts = (failedLateral && oppoDir && (delta < verticalSep)) ? (new TimeSpan(0, 0, 30, 0, 0) >= earliestLOS.Subtract(DateTime.UtcNow).Duration()) : (lossOfSep && new TimeSpan(0, 0, 30, 0, 0) >= earliestLOS.Subtract(DateTime.UtcNow).Duration()); //check if timediff < 30 min - var advisoryConflicts = (isConflictPair && oppoDir && (delta < verticalSep)) ? (new TimeSpan(0, 2, 0, 0, 0) > earliestLOS.Subtract(DateTime.UtcNow).Duration()) + var advisoryConflicts = (failedLateral && oppoDir && (delta < verticalSep)) ? (new TimeSpan(0, 2, 0, 0, 0) > earliestLOS.Subtract(DateTime.UtcNow).Duration()) && (earliestLOS.Subtract(DateTime.UtcNow).Duration() >= new TimeSpan(0, 0, 30, 0, 0)) : (lossOfSep && new TimeSpan(0, 2, 0, 0, 0) > earliestLOS.Subtract(DateTime.UtcNow).Duration()) && (earliestLOS.Subtract(DateTime.UtcNow).Duration() >= new TimeSpan(0, 0, 30, 0, 0)); //check if 2 hours > timediff > 30 mins @@ -288,7 +295,6 @@ public void ConflictProbe(FDP2.FDR fdr, int latSep1) label.imminentConflict.AddOrUpdate(fdr.Callsign, new HashSet(new string[] { fdr2.Callsign }), (k, v) => { v.Add(fdr2.Callsign); return v; }); - } else { From dbab7b27fdc27fea293d61f5d1ce444b7b3f409d Mon Sep 17 00:00:00 2001 From: Dominic Nguyen Date: Fri, 2 Feb 2024 13:59:14 -0800 Subject: [PATCH 36/76] global conflict var --- CPAR.cs | 66 ++++++++++++++++++++++++++++++++++++--------------------- 1 file changed, 42 insertions(+), 24 deletions(-) diff --git a/CPAR.cs b/CPAR.cs index 9c343e4..9cb3605 100644 --- a/CPAR.cs +++ b/CPAR.cs @@ -164,18 +164,36 @@ public class Segment public class ConflictData { - public string callsign; - public bool sameDir; - public + public FDP2.FDR fdr; + public FDP2.FDR fdr2; + public double trkDelta; + public int delta; + public int verticalSep; + public string conflictType; + public Segment startLatlong; + public Segment endLatlong; + public Segment startTime; + public Segment endTime; + public bool timeLongsame; + public bool timeLongcross; + public bool distLongsame; + public bool timeLongopposite; + public DateTime earliestLOS; + public bool actualConflicts; + public bool imminentConflicts; + public bool advisoryConflicts; + public TimeOfPassing top; } public void ConflictProbe(FDP2.FDR fdr, int latSep1) { + List conDict = new List(); + if ((fdr == null) || !MMI.IsMySectorConcerned(fdr)) return; int cfl = fdr.CFLUpper; int rfl = fdr.RFL; int alt = cfl == -1 ? rfl : cfl; var isRvsm = fdr.RVSM; - + for (int i = 0; i < conDict.Count; i++) foreach (var fdr2 in FDP2.GetFDRs) { if (fdr2 == null || fdr.Callsign == fdr2.Callsign || !MMI.IsMySectorConcerned(fdr2)) continue; @@ -185,10 +203,10 @@ public void ConflictProbe(FDP2.FDR fdr, int latSep1) rte.Last().Intersection.LatLong); double trk2 = Conversions.CalculateTrack(rte2.First().Intersection.LatLong, rte2.Last().Intersection.LatLong); - var trkdelta = Math.Abs(trk2 - trk); - bool sameDir = trkdelta < 45; - bool crossing = (trkdelta >= 45 && trkdelta <= 135) || (trkdelta >= 315 && trkdelta <= 225); - bool oppoDir = trkdelta > 135 && trkdelta < 225; + conDict[i].trkDelta = Math.Abs(trk2 - trk); + bool sameDir = conDict[i].trkDelta < 45; + bool crossing = (conDict[i].trkDelta >= 45 && conDict[i].trkDelta <= 135) || (conDict[i].trkDelta >= 315 && conDict[i].trkDelta <= 225); + bool oppoDir = conDict[i].trkDelta > 135 && conDict[i].trkDelta < 225; int cfl2 = fdr2.CFLUpper; int rfl2 = fdr2.RFL; int alt2 = cfl2 == -1 ? rfl2 : cfl2; @@ -245,15 +263,15 @@ public void ConflictProbe(FDP2.FDR fdr, int latSep1) if (firstConflictTime == null || firstConflictTime2 == null) continue; - var timeLongSame = sameDir && failedLateral && firstConflictTime.endTime > DateTime.UtcNow + conDict[i].timeLongsame = sameDir && failedLateral && firstConflictTime.endTime > DateTime.UtcNow && (firstConflictTime2.startTime - firstConflictTime.startTime).Duration() < (jet ? (new TimeSpan(0, 0, 10, 0)) : (new TimeSpan(0, 0, 15, 0)));//check time based longitudinal for same direction - var timeLongCross = crossing && failedLateral && firstConflictTime.endTime > DateTime.UtcNow + conDict[i].timeLongcross = crossing && failedLateral && firstConflictTime.endTime > DateTime.UtcNow && (firstConflictTime2.startTime - firstConflictTime.startTime).Duration() < (new TimeSpan(0, 0, 15, 0)); - var distLongSame = sameDir && failedLateral && firstConflictTime.endTime > DateTime.UtcNow + conDict[i].distLongsame = sameDir && failedLateral && firstConflictTime.endTime > DateTime.UtcNow && Conversions.CalculateDistance(firstConflictTime.startLatlong, firstConflictTime2.startLatlong) < (jet && rnp4 && cpdlc && adsc ? 30 : (rnp4 || rnp10) ? 50 : 50); - var timeLongOpposite = false; + var timeLongopposite = false; TimeOfPassing top = null; if (failedLateral && oppoDir) @@ -267,30 +285,30 @@ public void ConflictProbe(FDP2.FDR fdr, int latSep1) { return; } - timeLongOpposite = top.Time > DateTime.UtcNow + conDict[i].timeLongopposite = top.Time > DateTime.UtcNow && (top.Time.Add(new TimeSpan(0, 0, 10, 0)) > DateTime.UtcNow) && (top.Time.Subtract(new TimeSpan(0, 0, 10, 0)) < DateTime.UtcNow); } - var lossOfSep = timeLongSame || timeLongCross || distLongSame || timeLongOpposite; + var lossOfSep = conDict[i].timeLongsame || conDict[i].timeLongcross || conDict[i].distLongsame || timeLongopposite; - var earliestLOS = (failedLateral && oppoDir ? top.Time.Subtract(new TimeSpan(0, 0, 10, 0)) + conDict[i].earliestLOS = (failedLateral && oppoDir ? top.Time.Subtract(new TimeSpan(0, 0, 10, 0)) : (DateTime.Compare(firstConflictTime.startTime, firstConflictTime2.startTime) < 0 ? firstConflictTime.startTime : firstConflictTime2.startTime)); - var actualConflicts = (failedLateral && oppoDir && (delta < verticalSep)) ? (new TimeSpan(0, 0, 1, 0, 0) >= earliestLOS.Subtract(DateTime.UtcNow).Duration()) - : (lossOfSep && new TimeSpan(0, 0, 1, 0, 0) >= earliestLOS.Subtract(DateTime.UtcNow).Duration()) || earliestLOS < DateTime.UtcNow; + conDict[i].actualConflicts = (failedLateral && oppoDir && (delta < verticalSep)) ? (new TimeSpan(0, 0, 1, 0, 0) >= conDict[i].earliestLOS.Subtract(DateTime.UtcNow).Duration()) + : (lossOfSep && new TimeSpan(0, 0, 1, 0, 0) >= conDict[i].earliestLOS.Subtract(DateTime.UtcNow).Duration()) || conDict[i].earliestLOS < DateTime.UtcNow; - var imminentConflicts = (failedLateral && oppoDir && (delta < verticalSep)) ? (new TimeSpan(0, 0, 30, 0, 0) >= earliestLOS.Subtract(DateTime.UtcNow).Duration()) - : (lossOfSep && new TimeSpan(0, 0, 30, 0, 0) >= earliestLOS.Subtract(DateTime.UtcNow).Duration()); //check if timediff < 30 min + conDict[i].imminentConflicts = (failedLateral && oppoDir && (delta < verticalSep)) ? (new TimeSpan(0, 0, 30, 0, 0) >= earliestLOS.Subtract(DateTime.UtcNow).Duration()) + : (lossOfSep && new TimeSpan(0, 0, 30, 0, 0) >= conDict[i].earliestLOS.Subtract(DateTime.UtcNow).Duration()); //check if timediff < 30 min - var advisoryConflicts = (failedLateral && oppoDir && (delta < verticalSep)) ? (new TimeSpan(0, 2, 0, 0, 0) > earliestLOS.Subtract(DateTime.UtcNow).Duration()) - && (earliestLOS.Subtract(DateTime.UtcNow).Duration() >= new TimeSpan(0, 0, 30, 0, 0)) - : (lossOfSep && new TimeSpan(0, 2, 0, 0, 0) > earliestLOS.Subtract(DateTime.UtcNow).Duration()) - && (earliestLOS.Subtract(DateTime.UtcNow).Duration() >= new TimeSpan(0, 0, 30, 0, 0)); //check if 2 hours > timediff > 30 mins + conDict[i].advisoryConflicts = (failedLateral && oppoDir && (delta < verticalSep)) ? (new TimeSpan(0, 2, 0, 0, 0) > earliestLOS.Subtract(DateTime.UtcNow).Duration()) + && (conDict[i].earliestLOS.Subtract(DateTime.UtcNow).Duration() >= new TimeSpan(0, 0, 30, 0, 0)) + : (lossOfSep && new TimeSpan(0, 2, 0, 0, 0) > conDict[i].earliestLOS.Subtract(DateTime.UtcNow).Duration()) + && (conDict[i].earliestLOS.Subtract(DateTime.UtcNow).Duration() >= new TimeSpan(0, 0, 30, 0, 0)); //check if 2 hours > timediff > 30 mins - if (actualConflicts || imminentConflicts) + if (conDict[i].actualConflicts || conDict[i].imminentConflicts) { label.imminentConflict.AddOrUpdate(fdr.Callsign, new HashSet(new string[] { fdr2.Callsign }), (k, v) => { v.Add(fdr2.Callsign); return v; }); From 91741202864ebb39e5341f4e0a3402773b2ee94e Mon Sep 17 00:00:00 2001 From: Dominic Nguyen Date: Tue, 6 Feb 2024 05:46:47 -0800 Subject: [PATCH 37/76] Update global conflict --- CPAR.cs | 128 ++++++----- FPAP.cs | 114 ++++++++++ GEO.cs | 664 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ Strips.cs | 620 ++++++++++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 1468 insertions(+), 58 deletions(-) create mode 100644 FPAP.cs create mode 100644 GEO.cs create mode 100644 Strips.cs diff --git a/CPAR.cs b/CPAR.cs index 9cb3605..2f007c5 100644 --- a/CPAR.cs +++ b/CPAR.cs @@ -5,10 +5,12 @@ // Assembly location: E:\vatsys\bin\vatSys.exe // XML documentation location: E:\vatsys\bin\vatSys.xml +using AuroraLabelItemsPlugin; using System; using System.Collections.Concurrent; using System.Collections.Generic; using System.Linq; +using System.Runtime.CompilerServices; using System.Text.RegularExpressions; namespace vatsys @@ -17,7 +19,7 @@ public class CPAR { public List Segments1 = new List(); public List Segments2 = new List(); - AuroraLabelItemsPlugin.AuroraLabelItemsPlugin label = new AuroraLabelItemsPlugin.AuroraLabelItemsPlugin(); + AuroraLabelItemsPlugin.GEO label = new AuroraLabelItemsPlugin.GEO(); public DateTime Timeout = DateTime.MaxValue; public CPAR(FDP2.FDR fdr1, FDP2.FDR fdr2, int value) => this.CalculateLATC(fdr1, fdr2, value); @@ -166,27 +168,36 @@ public class ConflictData { public FDP2.FDR fdr; public FDP2.FDR fdr2; - public double trkDelta; - public int delta; + public double trkAngle; + public int verticalAct; public int verticalSep; + public int latAct; + public int latSep; + public bool longType; + public TimeSpan longTimesep; + public TimeSpan longTimeact; + public bool mnt; + public double longDistsep; + public double longDistact; + public TimeOfPassing top; public string conflictType; public Segment startLatlong; public Segment endLatlong; public Segment startTime; public Segment endTime; + public DateTime earliestLOS; public bool timeLongsame; - public bool timeLongcross; public bool distLongsame; + public bool timeLongcross; public bool timeLongopposite; - public DateTime earliestLOS; public bool actualConflicts; public bool imminentConflicts; public bool advisoryConflicts; - public TimeOfPassing top; } - public void ConflictProbe(FDP2.FDR fdr, int latSep1) + public void ConflictProbe(FDP2.FDR fdr, int latSep) { List conDict = new List(); + FPAP fpap = new FPAP(); if ((fdr == null) || !MMI.IsMySectorConcerned(fdr)) return; int cfl = fdr.CFLUpper; @@ -197,60 +208,55 @@ public void ConflictProbe(FDP2.FDR fdr, int latSep1) foreach (var fdr2 in FDP2.GetFDRs) { if (fdr2 == null || fdr.Callsign == fdr2.Callsign || !MMI.IsMySectorConcerned(fdr2)) continue; + var data = new ConflictData(); var rte = fdr.ParsedRoute; var rte2 = fdr2.ParsedRoute; double trk = Conversions.CalculateTrack(rte.First().Intersection.LatLong, rte.Last().Intersection.LatLong); double trk2 = Conversions.CalculateTrack(rte2.First().Intersection.LatLong, rte2.Last().Intersection.LatLong); - conDict[i].trkDelta = Math.Abs(trk2 - trk); - bool sameDir = conDict[i].trkDelta < 45; - bool crossing = (conDict[i].trkDelta >= 45 && conDict[i].trkDelta <= 135) || (conDict[i].trkDelta >= 315 && conDict[i].trkDelta <= 225); - bool oppoDir = conDict[i].trkDelta > 135 && conDict[i].trkDelta < 225; + data.trkAngle = Math.Abs(trk2 - trk); + bool sameDir = data.trkAngle < 45; + bool crossing = (data.trkAngle >= 45 && data.trkAngle <= 135) || (data.trkAngle >= 315 && data.trkAngle <= 225); + bool oppoDir = data.trkAngle > 135 && data.trkAngle < 225; int cfl2 = fdr2.CFLUpper; int rfl2 = fdr2.RFL; int alt2 = cfl2 == -1 ? rfl2 : cfl2; var isRvsm2 = fdr2.RVSM; - var delta = Math.Abs(alt - alt2); - int verticalSep = (alt > 45000 && alt < 60000) ? 4000 : alt > 60000 ? 5000 : (alt2 > 45000 && alt2 < 60000) ? 4000 : alt2 > 60000 ? 5000 : + data.verticalAct = Math.Abs(alt - alt2); + data.verticalSep = (alt > 45000 && alt < 60000) ? 4000 : alt > 60000 ? 5000 : (alt2 > 45000 && alt2 < 60000) ? 4000 : alt2 > 60000 ? 5000 : (alt > FDP2.RVSM_BAND_LOWER && !isRvsm) || (alt2 > FDP2.RVSM_BAND_LOWER && !isRvsm2) || (alt > FDP2.RVSM_BAND_UPPER || alt2 > FDP2.RVSM_BAND_UPPER) ? 2000 : 1000; - if (delta < verticalSep) + if (data.verticalAct < data.verticalSep) { - Match pbn2 = Regex.Match(fdr2.Remarks, @"PBN\/\w+\s"); - bool rnp10 = pbn2.Value.Contains("A1"); - bool rnp4 = pbn2.Value.Contains("L1"); - bool cpdlc = (Regex.IsMatch(fdr2.AircraftEquip, @"J5") || Regex.IsMatch(fdr2.AircraftEquip, @"J7")); - bool adsc = Regex.IsMatch(fdr2.AircraftSurvEquip, @"D1"); - bool jet = fdr2.PerformanceData?.IsJet ?? false; - var newValue = latSep1; + //data.latSep = latSep1; - if (rnp4 && adsc && cpdlc) + if (fpap.rnp4 && fpap.pbcs && fpap.adsc && fpap.cpdlc) { - newValue = Math.Max(latSep1, 23); + data.latSep = Math.Max(latSep, 23); } - else if (rnp10 || rnp4) + else if (fpap.rnp10 || fpap.rnp4) { - newValue = Math.Max(latSep1, 50); + data.latSep = Math.Max(latSep, 50); } - else if (!rnp10 && !rnp4) + else if (!fpap.rnp10 && !fpap.rnp4) { - newValue = Math.Max(latSep1, 100); + data.latSep = Math.Max(latSep, 100); } - else if (newValue != latSep1 && newValue == 100); + else if (data.latSep != 100 && data.latSep == 100); { - newValue = (50 + 100) / 2; + data.latSep = (50 + 100) / 2; } - var cpar = new CPAR(fdr2, fdr, newValue); + var cpar = new CPAR(fdr2, fdr, data.latSep); var segments1 = cpar.Segments1; var segments2 = cpar.Segments2; @@ -261,58 +267,64 @@ public void ConflictProbe(FDP2.FDR fdr, int latSep1) var firstConflictTime2 = segments2.FirstOrDefault(); var failedLateral = segments1.Count > 0; if (firstConflictTime == null || firstConflictTime2 == null) continue; - - - conDict[i].timeLongsame = sameDir && failedLateral && firstConflictTime.endTime > DateTime.UtcNow - && (firstConflictTime2.startTime - firstConflictTime.startTime).Duration() < (jet ? (new TimeSpan(0, 0, 10, 0)) : (new TimeSpan(0, 0, 15, 0)));//check time based longitudinal for same direction - conDict[i].timeLongcross = crossing && failedLateral && firstConflictTime.endTime > DateTime.UtcNow + + data.mnt = sameDir && fpap.jet; + data.longTimesep = data.mnt ? (new TimeSpan(0, 0, 10, 0)) : (new TimeSpan(0, 0, 15, 0)); + data.longTimeact = (firstConflictTime2.startTime - firstConflictTime.startTime).Duration(); + data.longDistsep = fpap.jet && fpap.rnp4 && fpap.pbcs && fpap.cpdlc && fpap.adsc ? 30 : fpap.jet && fpap.rnp10 && fpap.pbcs && fpap.cpdlc && fpap.adsc ? 50 : default; + data.longDistact = Conversions.CalculateDistance(firstConflictTime.startLatlong, firstConflictTime2.startLatlong); + data.timeLongsame = sameDir && failedLateral && firstConflictTime.endTime > DateTime.UtcNow + && data.longTimeact < data.longTimesep;//check time based longitudinal for same direction + data.timeLongcross = crossing && failedLateral && firstConflictTime.endTime > DateTime.UtcNow && (firstConflictTime2.startTime - firstConflictTime.startTime).Duration() < (new TimeSpan(0, 0, 15, 0)); - conDict[i].distLongsame = sameDir && failedLateral && firstConflictTime.endTime > DateTime.UtcNow - && Conversions.CalculateDistance(firstConflictTime.startLatlong, firstConflictTime2.startLatlong) - < (jet && rnp4 && cpdlc && adsc ? 30 : (rnp4 || rnp10) ? 50 : 50); + data.distLongsame = sameDir && failedLateral && firstConflictTime.endTime > DateTime.UtcNow + && data.longDistact < data.longDistsep; - var timeLongopposite = false; - TimeOfPassing top = null; + data.timeLongopposite = false; + data.top = null; if (failedLateral && oppoDir) { try { - top = new TimeOfPassing(fdr, fdr2); + data.top = new TimeOfPassing(fdr, fdr2); } catch (Exception e) { return; } - conDict[i].timeLongopposite = top.Time > DateTime.UtcNow - && (top.Time.Add(new TimeSpan(0, 0, 10, 0)) > DateTime.UtcNow) && (top.Time.Subtract(new TimeSpan(0, 0, 10, 0)) < DateTime.UtcNow); - } - + data.timeLongopposite = data.top.Time > DateTime.UtcNow + && (data.top.Time.Add(new TimeSpan(0, 0, 10, 0)) > DateTime.UtcNow) && (data.top.Time.Subtract(new TimeSpan(0, 0, 10, 0)) < DateTime.UtcNow); + } - var lossOfSep = conDict[i].timeLongsame || conDict[i].timeLongcross || conDict[i].distLongsame || timeLongopposite; + data.longType = (fpap.adsc && fpap.cpdlc && (fpap.rnp4 || fpap.rnp10) && fpap.pbcs) ? data.distLongsame : data.timeLongsame; - conDict[i].earliestLOS = (failedLateral && oppoDir ? top.Time.Subtract(new TimeSpan(0, 0, 10, 0)) - : (DateTime.Compare(firstConflictTime.startTime, firstConflictTime2.startTime) < 0 ? firstConflictTime.startTime : firstConflictTime2.startTime)); + var lossOfSep = data.longType || data.timeLongcross || data.timeLongopposite; + data.conflictType = lossOfSep && sameDir ? "same" : lossOfSep && crossing ? "crossing" : lossOfSep && oppoDir ? "opposite" : null; + data.earliestLOS = (failedLateral && oppoDir ? data.top.Time.Subtract(new TimeSpan(0, 0, 10, 0)) + : (DateTime.Compare(firstConflictTime.startTime, firstConflictTime2.startTime) < 0 ? firstConflictTime.startTime : firstConflictTime2.startTime)); - conDict[i].actualConflicts = (failedLateral && oppoDir && (delta < verticalSep)) ? (new TimeSpan(0, 0, 1, 0, 0) >= conDict[i].earliestLOS.Subtract(DateTime.UtcNow).Duration()) - : (lossOfSep && new TimeSpan(0, 0, 1, 0, 0) >= conDict[i].earliestLOS.Subtract(DateTime.UtcNow).Duration()) || conDict[i].earliestLOS < DateTime.UtcNow; + data.actualConflicts = (failedLateral && oppoDir && (data.verticalAct < data.verticalSep)) ? (new TimeSpan(0, 0, 1, 0, 0) >= data.earliestLOS.Subtract(DateTime.UtcNow).Duration()) + : (lossOfSep && new TimeSpan(0, 0, 1, 0, 0) >= data.earliestLOS.Subtract(DateTime.UtcNow).Duration()) || data.earliestLOS < DateTime.UtcNow; - conDict[i].imminentConflicts = (failedLateral && oppoDir && (delta < verticalSep)) ? (new TimeSpan(0, 0, 30, 0, 0) >= earliestLOS.Subtract(DateTime.UtcNow).Duration()) - : (lossOfSep && new TimeSpan(0, 0, 30, 0, 0) >= conDict[i].earliestLOS.Subtract(DateTime.UtcNow).Duration()); //check if timediff < 30 min + data.imminentConflicts = (failedLateral && oppoDir && (data.verticalAct < data.verticalSep)) ? (new TimeSpan(0, 0, 30, 0, 0) >= data.earliestLOS.Subtract(DateTime.UtcNow).Duration()) + : (lossOfSep && new TimeSpan(0, 0, 30, 0, 0) >= data.earliestLOS.Subtract(DateTime.UtcNow).Duration()); //check if timediff < 30 min - conDict[i].advisoryConflicts = (failedLateral && oppoDir && (delta < verticalSep)) ? (new TimeSpan(0, 2, 0, 0, 0) > earliestLOS.Subtract(DateTime.UtcNow).Duration()) - && (conDict[i].earliestLOS.Subtract(DateTime.UtcNow).Duration() >= new TimeSpan(0, 0, 30, 0, 0)) - : (lossOfSep && new TimeSpan(0, 2, 0, 0, 0) > conDict[i].earliestLOS.Subtract(DateTime.UtcNow).Duration()) - && (conDict[i].earliestLOS.Subtract(DateTime.UtcNow).Duration() >= new TimeSpan(0, 0, 30, 0, 0)); //check if 2 hours > timediff > 30 mins + data.advisoryConflicts = (failedLateral && oppoDir && (data.verticalAct < data.verticalSep)) ? (new TimeSpan(0, 2, 0, 0, 0) > data.earliestLOS.Subtract(DateTime.UtcNow).Duration()) + && (data.earliestLOS.Subtract(DateTime.UtcNow).Duration() >= new TimeSpan(0, 0, 30, 0, 0)) + : (lossOfSep && new TimeSpan(0, 2, 0, 0, 0) > data.earliestLOS.Subtract(DateTime.UtcNow).Duration()) + && (data.earliestLOS.Subtract(DateTime.UtcNow).Duration() >= new TimeSpan(0, 0, 30, 0, 0)); //check if 2 hours > timediff > 30 mins - if (conDict[i].actualConflicts || conDict[i].imminentConflicts) + if (data.actualConflicts || data.imminentConflicts) { label.imminentConflict.AddOrUpdate(fdr.Callsign, new HashSet(new string[] { fdr2.Callsign }), (k, v) => { v.Add(fdr2.Callsign); return v; }); + conDict.Add(data); + } else { @@ -334,7 +346,7 @@ public void ConflictProbe(FDP2.FDR fdr, int latSep1) - if (advisoryConflicts) + if (data.advisoryConflicts) { label.advisoryConflict.AddOrUpdate(fdr.Callsign, new HashSet(new string[] { fdr2.Callsign }), (k, v) => { v.Add(fdr2.Callsign); return v; }); diff --git a/FPAP.cs b/FPAP.cs new file mode 100644 index 0000000..bcc4db9 --- /dev/null +++ b/FPAP.cs @@ -0,0 +1,114 @@ +using System; +using System.Linq; +using System.Text.RegularExpressions; +using static vatsys.SectorsVolumes; +using System.Threading; +using vatsys.Plugin; +using vatsys; +using System.ComponentModel.Composition; + +namespace AuroraLabelItemsPlugin +{ + public class FPAP + { + public Match pbn; + public Match sur; + public bool rnp10; + public bool rnp4; + public bool pbcs; + public bool cpdlc; + public bool adsc; + public bool jet; + public double vs; + public int prl; + public int cfl; + public int rfl; + public int alt; + + public void OnFDRUpdate(FDP2.FDR updated) + { + pbn = Regex.Match(updated.Remarks, @"PBN\/\w+\s"); + sur = Regex.Match(updated.Remarks, @"SUR\/\w+\s"); + rnp10 = pbn.Value.Contains("A1") && updated.AircraftEquip.Contains("R"); + rnp4 = pbn.Value.Contains("L1") && updated.AircraftEquip.Contains("R"); + pbcs = sur.Value.Contains("RSP180") && updated.AircraftSurvEquip.Contains("P2"); + cpdlc = updated.AircraftEquip.Contains("J5") || updated.AircraftEquip.Contains("J7"); + adsc = updated.AircraftSurvEquip.Contains("D1"); + jet = updated.PerformanceData?.IsJet ?? false; + vs = updated.PredictedPosition.VerticalSpeed; + prl = updated.PRL / 100; + cfl = updated.CFLUpper; + rfl = updated.RFL; + alt = cfl == -1 ? rfl : cfl; + } + + public void TOC(RDP.RadarTrack rt) + { + var fdr = rt.CoupledFDR; + if (fdr != null && rt != null) + { + TransferOfControl(fdr); + } + } + + + public static void TransferOfControl(FDP2.FDR fdr) + { + TOC toc; + toc = new TOC(fdr); + + var rt = fdr.CoupledTrack; + if (fdr != null) + if (!fdr.ESTed && MMI.IsMySectorConcerned(fdr)) + { + MMI.EstFDR(fdr); + } + + if (MMI.SectorsControlled.ToList() + .Exists(s => s.IsInSector(fdr.GetLocation(), fdr.PRL)) && !fdr.IsTrackedByMe && !fdr.IsTracked) //MMI.SectorsControlled.Contains(fdr.ControllingSector) || fdr.ControllingSector == null + { + MMI.AcceptJurisdiction(fdr); + } + + + + foreach (Volume volume in Volumes) + { + if (rt != null && (fdr.PRL == -1 || (fdr.PRL <= volume.UpperLevel && fdr.PRL > volume.LowerLevel)) && Conversions.IsLatlonInPoly(fdr.GetLocation(), volume.Boundary)) + { + + var whichVol = volume; + var whichFIR = SectorsVolumes.FindSector(whichVol); + if (MMI.GetSectorEntryTime(fdr) == DateTime.MaxValue && MMI.SectorsControlled.ToList().TrueForAll(s => !s.IsInSector(fdr.GetLocation(), fdr.PRL))) // && whichFIR != fdr.ControllingSector + + { + //toc.HandoffNextSector(); + MMI.HandoffJurisdiction(fdr, whichFIR); + MMI.Inhibit(fdr); + Thread.Sleep(300000); + RDP.DeCouple(rt); + } + } + } + + } + + //void SendNextDataAuthority(Network network, NetworkPilot pilot, VSCSFrequency freq) + //{ + // + // if (network.ValidATC && network.HaveConnection && !((DateTime.UtcNow - pilot.LastContactMe).TotalMinutes < 1.0)) + // { + // string text = "NEXT DATA AUTHORITY KZAK"; + // if (freq.AliasFrequency != VSCSFrequency.None.Frequency) + // { + // text = text + " (" + Conversions.FrequencyToString(freq.AliasFrequency) + ")"; + //Network.Instance.SendRadioMessage(radioMessage.FSDFrequencies, radioMessage.Address, "Unable", ThisRequiresResponse: false, radioMessage, CloseRequest: true); + // } + // + // network.SendTextMessage(pilot.Callsign, text); + // pilot.LastContactMe = DateTime.UtcNow; + // } + //} + + } +} diff --git a/GEO.cs b/GEO.cs new file mode 100644 index 0000000..65e3fed --- /dev/null +++ b/GEO.cs @@ -0,0 +1,664 @@ +using System; +using System.Threading; +using System.Collections.Concurrent; +using System.ComponentModel.Composition; +using System.Linq; //<--Need to add a reference to System.ComponentModel.Composition +using System.Text.RegularExpressions; +using vatsys; +using vatsys.Plugin; +using static vatsys.FDP2; +using static vatsys.SectorsVolumes; +using System.Collections.Generic; +using System.Runtime.CompilerServices; + + +//Note the reference to vatsys (set Copy Local to false) -----> + +namespace AuroraLabelItemsPlugin +{ + [Export(typeof(IPlugin))] + public class GEO : ILabelPlugin + { + /// The name of the custom label item we've added to Labels + /// in the Profile + const string LABEL_ITEM_SELECT_HORI = "SELECT_HORI"; + const string LABEL_ITEM_SELECT_VERT = "SELECT_VERT"; + const string LABEL_ITEM_COMM_ICON = "AURORA_COMM_ICON"; //field a(2) + const string LABEL_ITEM_ADSB_CPDLC = "AURORA_ADSB_CPDLC"; //field c(4) + const string LABEL_ITEM_ADS_FLAGS = "AURORA_ADS_FLAGS"; //field c(4) + const string LABEL_ITEM_MNT_FLAGS = "AURORA_MNT_FLAGS"; //field c(4) + const string LABEL_ITEM_SCC = "AURORA_SCC"; //field d(5) + const string LABEL_ITEM_ANNOT_IND = "AURORA_ANNOT_IND"; //field e(1) + const string LABEL_ITEM_RESTR = "AURORA_RESTR"; //field f(1) + const string LABEL_ITEM_LEVEL = "AURORA_LEVEL"; //field g(3) + const string LABEL_ITEM_VMI = "AURORA_VMI"; //field h(1) + const string LABEL_ITEM_CLEARED_LEVEL = "AURORA_CLEARED_LEVEL"; //field i(7) + const string LABEL_ITEM_HANDOFF_IND = "AURORA_HO_IND"; //field j(4) + const string LABEL_ITEM_RADAR_IND = "AURORA_RADAR_IND"; //field k(1) + const string LABEL_ITEM_INHIBIT_IND = "AURORA_INHIBIT_IND"; //field l(1) + const string LABEL_ITEM_FILED_SPEED = "AURORA_FILEDSPEED"; //field m(4) + const string LABEL_ITEM_3DIGIT_GROUNDSPEED = "AURORA_GROUNDSPEED"; //field n(5) + const string LABEL_ITEM_DESTINATION = "AURORA_DESTINATION"; //field o(4) + readonly static CustomColour EastboundColour = new CustomColour(240, 255, 255); + readonly static CustomColour WestboundColour = new CustomColour(240, 231, 140); + readonly static CustomColour NonRVSM = new CustomColour(242, 133, 0); + readonly static CustomColour Probe = new CustomColour(0, 255, 0); + readonly static CustomColour NotCDA = new CustomColour(100, 0, 100); + readonly static CustomColour Advisory = new CustomColour(255, 165, 0); + readonly static CustomColour Imminent = new CustomColour(255, 0, 0); + readonly static CustomColour SpecialConditionCode = new CustomColour(255, 255, 0); + readonly static CustomColour ApsBlue = new CustomColour(141, 182, 205); + readonly ConcurrentDictionary eastboundCallsigns = new ConcurrentDictionary(); + readonly ConcurrentDictionary adsbcpdlcValues = new ConcurrentDictionary(); + readonly ConcurrentDictionary adsflagValues = new ConcurrentDictionary(); + readonly ConcurrentDictionary mntflagValues = new ConcurrentDictionary(); + readonly ConcurrentDictionary sccflagValues = new ConcurrentDictionary(); + readonly ConcurrentDictionary altValues = new ConcurrentDictionary(); + readonly ConcurrentDictionary radartoggle = new ConcurrentDictionary(); + readonly ConcurrentDictionary mntflagtoggle = new ConcurrentDictionary(); + readonly ConcurrentDictionary downlink = new ConcurrentDictionary(); + public readonly ConcurrentDictionary> advisoryConflict = new ConcurrentDictionary>(); + public readonly ConcurrentDictionary> imminentConflict = new ConcurrentDictionary>(); + + + + public GEO() + { + Network.PrivateMessagesChanged += Network_PrivateMessagesChanged; + Network.RadioMessageAcknowledged += Network_RadioMessageAcknowledged; + } + + + private void Network_RadioMessageAcknowledged(object sender, RadioMessageEventArgs e) + { + throw new NotImplementedException(); + } + + private void Network_PrivateMessagesChanged(object sender, Network.GenericMessageEventArgs e) + { + bool downLink = e.Message.Sent == true; + + if (downLink) + { + downlink.TryRemove(e.Message.Address, out _); + } + else + { + downlink.TryAdd(e.Message.Address, 0); + } + } + + + /// Plugin Name + public string Name + { + get => "Aurora Label Items"; + } + + /// This is called each time a flight data record is updated + /// Here we are updating the eastbound callsigns dictionary with each flight data record + /// When the FDR is updated we check if it still exists in the Flight Data Processor and remove from our dictionary if not. Otherwise we do some simple regex matching to find + /// the flight planned PBN category and store the character we want to display in the label in the dictionary. + public void OnFDRUpdate(FDP2.FDR updated) + { + FPAP fpap = new FPAP(); + + + if (FDP2.GetFDRIndex(updated.Callsign) == -1) + { + eastboundCallsigns.TryRemove(updated.Callsign, out _); + adsbcpdlcValues.TryRemove(updated.Callsign, out _); + adsflagValues.TryRemove(updated.Callsign, out _); + mntflagValues.TryRemove(updated.Callsign, out _); + sccflagValues.TryRemove(updated.Callsign, out _); + altValues.TryRemove(updated.Callsign, out _); + radartoggle.TryRemove(updated.Callsign, out _); + mntflagtoggle.TryRemove(updated.Callsign, out _); + downlink.TryRemove(updated.Callsign, out _); + advisoryConflict.TryRemove(updated.Callsign, out _); + imminentConflict.TryRemove(updated.Callsign, out _); + + } + else + { + + + char c1 = default; + + if (!updated.ADSB && fpap.cpdlc) + + c1 = '⧆'; + + else if (!updated.ADSB) + + c1 = '⎕'; + + else if (fpap.cpdlc) + + c1 = '✱'; + + + adsbcpdlcValues.AddOrUpdate(updated.Callsign, c1, (k, v) => c1); + + char c2 = default; + + if (fpap.adsc & fpap.cpdlc & fpap.rnp4) + c2 = '3'; + + else if (fpap.adsc & fpap.cpdlc & fpap.rnp10) + c2 = 'D'; + + adsflagValues.AddOrUpdate(updated.Callsign, c2, (k, v) => c2); + + char c3 = default; + + if (updated.PerformanceData?.IsJet ?? false) + c3 = 'M'; + + mntflagValues.AddOrUpdate(updated.Callsign, c3, (k, v) => c3); + + NetworkPilot code; + code = new NetworkPilot(); + + string d1 = string.Empty; + + if (!fpap.rnp10 && !fpap.rnp4) + d1 = "RNP"; + + else if (code.TransponderCode == 7700) + d1 = "EMG"; + + else if (code.TransponderCode == 7600) + d1 = "RCF"; + + else if (code.TransponderCode == 7777) + d1 = "MTI"; + + else if (code.TransponderCode == 7700) + d1 = "EMG"; + + sccflagValues.AddOrUpdate(updated.Callsign, d1, (k, v) => d1); + + char h1 = default; + + if (Math.Abs(updated.PRL - fpap.alt) <= 299) //level flight + h1 = default; + + else if (fpap.alt / 100 > fpap.prl || fpap.vs > 300) //Issued or trending climb + h1 = '↑'; + + else if (fpap.alt / 100 > 0 && fpap.alt < fpap.prl || fpap.vs < -300) //Issued or trending descent + h1 = '↓'; + + else if (fpap.prl - fpap.alt / 100 >= 3) //deviating above + h1 = '+'; + + else if (fpap.prl - fpap.alt / 100 <= -3) //deviating below + h1 = '-'; + + + altValues.AddOrUpdate(updated.Callsign, h1, (k, v) => h1); + + if (updated.ParsedRoute.Count > 1) + { + //calculate track from first route point to last (Departure point to destination point) + var rte = updated.ParsedRoute; + double trk = Conversions.CalculateTrack(rte.First().Intersection.LatLong, + rte.Last().Intersection.LatLong); + bool east = trk >= 0 && trk < 180; + eastboundCallsigns.AddOrUpdate(updated.Callsign, east, (c, e) => east); + } + + FPAP.TransferOfControl(updated); + + CPAR cpar = new CPAR(); + CPAR.ConflictData reqLat = new CPAR.ConflictData(); + + cpar.ConflictProbe(updated, reqLat.latSep); + + } + } + /// Could use the new position of the radar track or its change in state (cancelled, etc.) to do some processing. + public void OnRadarTrackUpdate(RDP.RadarTrack updated) + { + + } + + private void HandleRadarFlagClick(CustomLabelItemMouseClickEventArgs e) + { + bool radarToggled = radartoggle.TryGetValue(e.Track.GetFDR().Callsign, out _); + + if (radarToggled) + { + radartoggle.TryRemove(e.Track.GetFDR().Callsign, out _); + } + else + { + radartoggle.TryAdd(e.Track.GetFDR().Callsign, 0); + } + + e.Handled = true; + } + + + /// vatSys calls this function when it encounters a custom label item (defined in Labels.xml) during the label rendering. + /// itemType is the value of the Type attribute in Labels.xml + /// If it's not our item being called (another plugins, for example), return null. + /// As a general rule, don't do processing in here as you'll slow down the ASD refresh. In the case of parsing a level to a string though, that's fine. + public CustomLabelItem GetCustomLabelItem(string itemType, Track track, FDP2.FDR flightDataRecord, RDP.RadarTrack radarTrack) + { + FPAP fpap = new FPAP(); + + if (flightDataRecord == null || radarTrack == null) + return null; + + char c1; + adsbcpdlcValues.TryGetValue(flightDataRecord.Callsign, out c1); + char c2; + adsflagValues.TryGetValue(flightDataRecord.Callsign, out c2); + char c3; + mntflagValues.TryGetValue(flightDataRecord.Callsign, out c3); + string d1; + sccflagValues.TryGetValue(flightDataRecord.Callsign, out d1); + char h1; + altValues.TryGetValue(flightDataRecord.Callsign, out h1); + + + + bool radarToggled = radartoggle.TryGetValue(flightDataRecord.Callsign, out _); + bool mntflagToggled = mntflagtoggle.TryGetValue(flightDataRecord.Callsign, out _); + bool downLink = downlink.TryGetValue(flightDataRecord.Callsign, out _); + bool isNonRVSM = !flightDataRecord.RVSM; + var notProbe = flightDataRecord.State == (FDR.FDRStates.STATE_PREACTIVE | FDR.FDRStates.STATE_COORDINATED) ? BorderFlags.All : BorderFlags.None; + var colour = (!flightDataRecord.RVSM ? NonRVSM : ExcludeConflictColor(track, flightDataRecord)); + var excludeConflict = (SelectASDTrackColour(track) == GetConflictColour(flightDataRecord.Callsign)); + + switch (itemType) + + { + + case LABEL_ITEM_SELECT_HORI: + + if (MMI.SelectedTrack?.GetFDR()?.Callsign == track.GetFDR().Callsign) + { + return new CustomLabelItem() + + { + Text = "", + Border = BorderFlags.Bottom + }; + } + + return null; + + case LABEL_ITEM_SELECT_VERT: + + if (MMI.SelectedTrack?.GetFDR()?.Callsign == track.GetFDR().Callsign) + { + return new CustomLabelItem() + { + Text = "", + Border = BorderFlags.Left + }; + } + + return null; + + case LABEL_ITEM_COMM_ICON: + + if (downLink) + { + return new CustomLabelItem() + { + Text = "▼", + Border = BorderFlags.All, + ForeColourIdentity = excludeConflict ? Colours.Identities.Custom : default, + CustomForeColour = ExcludeConflictColor(track, flightDataRecord) + }; + } + else + { + return new CustomLabelItem() + { + Text = "⬜", + ForeColourIdentity = excludeConflict ? Colours.Identities.Custom : default, + CustomForeColour = ExcludeConflictColor(track, flightDataRecord) + }; + } + case LABEL_ITEM_ADSB_CPDLC: + + bool useCustomForeColour = + flightDataRecord.State == (FDR.FDRStates.STATE_PREACTIVE | FDR.FDRStates.STATE_COORDINATED); + + if (useCustomForeColour) + { + return new CustomLabelItem() + { + ForeColourIdentity = Colours.Identities.Custom, + CustomForeColour = NotCDA, + Text = c1.ToString() + }; + } + else + { + return new CustomLabelItem() + { + Text = c1.ToString(), + ForeColourIdentity = excludeConflict ? Colours.Identities.Custom : default, + CustomForeColour = ExcludeConflictColor(track, flightDataRecord) + }; + } + + case LABEL_ITEM_ADS_FLAGS: + + return new CustomLabelItem() + { + Text = c2.ToString(), + ForeColourIdentity = excludeConflict ? Colours.Identities.Custom : default, + CustomForeColour = ExcludeConflictColor(track, flightDataRecord) + }; + + + case LABEL_ITEM_MNT_FLAGS: + + if (mntflagToggled) + { + return new CustomLabelItem() + { + Text = c3.ToString(), + ForeColourIdentity = excludeConflict ? Colours.Identities.Custom : default, + CustomForeColour = ExcludeConflictColor(track, flightDataRecord) + }; + } + + else + return new CustomLabelItem() + { + Text = "", + }; + + + case LABEL_ITEM_SCC: + + { + return new CustomLabelItem() + { + Text = d1, + ForeColourIdentity = Colours.Identities.Custom, + CustomForeColour = SpecialConditionCode + }; + } + + + case LABEL_ITEM_ANNOT_IND: + bool scratch = String.IsNullOrEmpty(flightDataRecord.LabelOpData); + + if (scratch) + { + return new CustomLabelItem() + { + Text = "◦", + ForeColourIdentity = excludeConflict ? Colours.Identities.Custom : default, + CustomForeColour = ExcludeConflictColor(track, flightDataRecord) + }; + } + + else + { + return new CustomLabelItem() + { + Text = "&", + ForeColourIdentity = excludeConflict ? Colours.Identities.Custom : default, + CustomForeColour = ExcludeConflictColor(track, flightDataRecord) + }; + } + + case LABEL_ITEM_RESTR: + + if (flightDataRecord.LabelOpData.Contains("AT ") || flightDataRecord.LabelOpData.Contains(" BY ") || + flightDataRecord.LabelOpData.Contains("CLEARED TO ")) + + return new CustomLabelItem() + { + Text = "x", + ForeColourIdentity = excludeConflict ? Colours.Identities.Custom : default, + CustomForeColour = ExcludeConflictColor(track, flightDataRecord) + }; + + return null; + + case LABEL_ITEM_LEVEL: + + var level = fpap.prl == -1 ? null : (radarTrack.CorrectedAltitude / 100).ToString(); + + + return new CustomLabelItem() + { + Text = level.ToString(), + Border = notProbe, + BorderColourIdentity = Colours.Identities.Custom, + CustomBorderColour = NotCDA, + ForeColourIdentity = excludeConflict ? Colours.Identities.Custom : default, + CustomForeColour = colour + + }; + + case LABEL_ITEM_VMI: + + return new CustomLabelItem() + { + Text = h1.ToString(), + ForeColourIdentity = excludeConflict ? Colours.Identities.Custom : default, + CustomForeColour = colour + }; + + + + case LABEL_ITEM_CLEARED_LEVEL: + + + if (radarTrack.ReachedCFL || fpap.prl == fpap.alt || Math.Abs(flightDataRecord.PRL - fpap.alt) < 300) + return new CustomLabelItem() + { + Text = "" + }; + + else + { + return new CustomLabelItem() + { + Text = fpap.alt.ToString(), + Border = notProbe, + BorderColourIdentity = Colours.Identities.Custom, + CustomBorderColour = NotCDA, + ForeColourIdentity = excludeConflict ? Colours.Identities.Custom : default, + CustomForeColour = colour + }; + } + +// case LABEL_ITEM_HANDOFF_IND: +// +// +// if (flightDataRecord.IsHandoff) +// { +// return new CustomLabelItem() +// { +// Text = "H" + flightDataRecord.HandoffSector.Name, +// }; +// } +// +// else if (flightDataRecord.State == FDR.FDRStates.STATE_HANDOVER_FIRST) +// { +// return new CustomLabelItem() +// { +// Text = "O" + flightDataRecord.HandoffSector.Name, +// }; +// } +// +// else +// { +// return new CustomLabelItem() +// { +// Text = "" +// }; +// } + + case LABEL_ITEM_RADAR_IND: + + + if (radarToggled) + { + return new CustomLabelItem() + { + Text = "★", + OnMouseClick = HandleRadarFlagClick, + ForeColourIdentity = excludeConflict ? Colours.Identities.Custom : default, + CustomForeColour = ExcludeConflictColor(track, flightDataRecord) + }; + } + + else + { + return new CustomLabelItem() + { + Text = "◦", + OnMouseClick = HandleRadarFlagClick, + ForeColourIdentity = excludeConflict ? Colours.Identities.Custom : default, + CustomForeColour = ExcludeConflictColor(track, flightDataRecord) + }; + } + + case LABEL_ITEM_INHIBIT_IND: + + + if (flightDataRecord.State == FDR.FDRStates.STATE_INHIBITED) + { + return new CustomLabelItem() + { + Text = "^", + ForeColourIdentity = excludeConflict ? Colours.Identities.Custom : default, + CustomForeColour = ExcludeConflictColor(track, flightDataRecord) + }; + } + + else + { + return new CustomLabelItem() + { + Text = "" + }; + } + + + case LABEL_ITEM_FILED_SPEED: + var mach = Conversions.CalculateMach(flightDataRecord.TAS, GRIB.FindTemperature(flightDataRecord.PRL, track.GetLocation(), true)); + return new CustomLabelItem() + { + Text = "M" + Convert.ToDecimal(mach).ToString("F2").Replace(".", ""), + //Text = "N" + flightDataRecord.TAS + ForeColourIdentity = excludeConflict ? Colours.Identities.Custom : default, + CustomForeColour = ExcludeConflictColor(track, flightDataRecord) + + }; + + case LABEL_ITEM_3DIGIT_GROUNDSPEED: + //get groundspeed value from either FDR or radarTrack if coupled + var gs = radarTrack == null + ? flightDataRecord.PredictedPosition.Groundspeed + : radarTrack.GroundSpeed; + return new CustomLabelItem() + { + Text = "N" + gs.ToString("000"),//format as 3 digits (with leading zeros) + ForeColourIdentity = excludeConflict ? Colours.Identities.Custom : default, + CustomForeColour = ExcludeConflictColor(track, flightDataRecord) + }; + + case LABEL_ITEM_DESTINATION: + + return new CustomLabelItem() + { + Text = flightDataRecord.DesAirport, + ForeColourIdentity = excludeConflict ? Colours.Identities.Custom : default, + CustomForeColour = ExcludeConflictColor(track, flightDataRecord) + }; + + default: + return null; + } + } + + public CustomColour SelectASDTrackColour(Track track) + { + var fdr = track.GetFDR(); + var fdr2 = track.GetFDR(); + //if track doesn't have an FDR coupled do nothing + if (fdr == null) + return null; + + + //only apply East/West colour to jurisdiction state + if (track.State == MMI.HMIStates.Jurisdiction) //read our dictionary of stored bools (true means is easterly) and return the correct colour + { + + return GetConflictColour(fdr.Callsign) ?? GetDirectionColour(fdr.Callsign, fdr); + } + + if (fdr.State != (FDR.FDRStates.STATE_PREACTIVE | FDR.FDRStates.STATE_COORDINATED)) //only apply conflict colours if planes are of concern + { + return GetConflictColour(fdr.Callsign) ?? null; + } + + else + + return default; + + } + + public CustomColour SelectGroundTrackColour(Track track) + { + return null; + } + + private CustomColour GetDirectionColour(string callsign, FDR fdr) + { + if (eastboundCallsigns.TryGetValue(callsign, out bool east)) + { + if (east) + return EastboundColour; + else + return WestboundColour; + } + + return default; + } + + private CustomColour GetConflictColour(string callsign) + { + if (imminentConflict.Count % 2 == 0 && imminentConflict.TryGetValue(callsign, out _)) + { + return Imminent; + } + else if (advisoryConflict.Count % 2 == 0 && advisoryConflict.TryGetValue(callsign, out _)) + { + return Advisory; + } + + return default; + } + + private CustomColour ExcludeConflictColor(Track track, FDP2.FDR flightDataRecord) + { + if ((imminentConflict.Count > 0 || advisoryConflict.Count > 0) && track.State == MMI.HMIStates.Jurisdiction) + { + return GetDirectionColour(flightDataRecord.Callsign, flightDataRecord); + } + else if (imminentConflict.Count > 0 || advisoryConflict.Count > 0) + { + return ApsBlue; + } + return default; + + } + + } +} \ No newline at end of file diff --git a/Strips.cs b/Strips.cs new file mode 100644 index 0000000..e9f42bc --- /dev/null +++ b/Strips.cs @@ -0,0 +1,620 @@ +using System; +using System.Text.RegularExpressions; +using vatsys; +using vatsys.Plugin; +using System.Collections.Concurrent; +using System.ComponentModel.Composition; //<--Need to add a reference to System.ComponentModel.Composition +using static vatsys.FDP2; +using System.Collections.Generic; +using System.Linq; +using AuroraLabelItemsPlugin; + +namespace AuroraStripItemsPlugin +{ + [Export(typeof(IPlugin))] + + public class AuroraStripItemsPlugin : IStripPlugin + { + AuroraLabelItemsPlugin.GEO label = new AuroraLabelItemsPlugin.GEO(); + CPAR.ConflictData cpar = new CPAR.ConflictData(); + FPAP fpap = new FPAP(); + /// The name of the custom label item we've added to Labels + /// in the Profile + const string LABEL_ITEM_ADSB_CPDLC = "AURORA_ADSB_CPDLC"; //field c(4) + const string STRIP_ITEM_CALLSIGN = "AURORA_CALLSIGN"; + const string STRIP_ITEM_CTLSECTOR = "AURORA_CDA"; + const string STRIP_ITEM_NXTSECTOR = "AURORA_NDA"; + const string STRIP_ITEM_T10_FLAG = "AURORA_T10_FLAG"; + const string STRIP_ITEM_MNT_FLAG = "AURORA_MNT_FLAG"; + const string STRIP_ITEM_DIST_FLAG = "AURORA_DIST_FLAG"; + const string STRIP_ITEM_RVSM_FLAG = "AURORA_RVSM_FLAG"; + const string STRIP_ITEM_VMI = "AURORA_STRIP_VMI"; + const string STRIP_ITEM_COMPLEX = "AURORA_STRIP_COMPLEX"; + const string STRIP_ITEM_CLEARED_LEVEL = "AURORA_CLEARED_LEVEL"; + const string STRIP_ITEM_REQUESTED_LEVEL = "AURORA_REQUESTED_LEVEL"; + const string STRIP_ITEM_MAN_EST = "AURORA_MAN_EST"; + const string STRIP_ITEM_POINT = "AURORA_POINT"; + const string STRIP_ITEM_ROUTE = "AURORA_ROUTE_STRIP"; + const string STRIP_ITEM_RADAR_IND = "AURORA_RADAR_IND"; + const string STRIP_ITEM_ANNOT_IND = "AURORA_ANNOT_STRIP"; + const string STRIP_ITEM_LATERAL_FLAG = "AURORA_LATERAL_FLAG"; + const string STRIP_ITEM_RESTR = "AURORA_RESTR_STRIP"; + const string STRIP_ITEM_CLRD_RTE = "AURORA_CLRD_RTE"; + const string CPAR_ITEM_TYPE = "CPAR_TYP"; + const string CPAR_ITEM_REQUIRED = "CPAR_REQUIRED"; + const string CPAR_ITEM_ANGLE = "CPAR_ANGLE"; + const string CPAR_ITEM_LOS = "CPAR_LOS"; + const string CPAR_ITEM_ACTUAL = "CPAR_ACTUAL"; + const string CPAR_ITEM_PASSING = "CPAR_PASSING"; + const string CPAR_ITEM_CONF_SEG_START_1 = "CPAR_CONF_SEG_START_1"; + const string CPAR_ITEM_CONF_SEG_START_2 = "CPAR_CONF_SEG_START_2"; + const string CPAR_ITEM_CONF_SEG_END_1 = "CPAR_CONF_SEG_END_1"; + const string CPAR_ITEM_CONF_SEG_END_2 = "CPAR_CONF_SEG_END_2"; + const string CPAR_ITEM_STARTIME_1 = "CPAR_START_TIME_1"; + const string CPAR_ITEM_STARTIME_2 = "CPAR_START_TIME_2"; + const string CPAR_ITEM_ENDTIME_1 = "CPAR_END_TIME_1"; + const string CPAR_ITEM_ENDTIME_2 = "CPAR_END_TIME_2"; + const string CPAR_ITEM_AID_2 = "CPAR_AID_2"; + const string CPAR_ITEM_TYP_2 = "CPAR_TYP_2"; + const string CPAR_ITEM_SPD_2 = "CPAR_SPD_2"; + const string CPAR_ITEM_ALT_2 = "CPAR_ALT_2"; + readonly static CustomColour NonRVSM = new CustomColour(242, 133, 0); + readonly static CustomColour SepFlags = new CustomColour(0, 196, 253); + readonly static CustomColour Pending = new CustomColour(46, 139, 87); + readonly static CustomColour NotCDA = new CustomColour(100, 0, 100); + readonly ConcurrentDictionary eastboundCallsigns = new ConcurrentDictionary(); + readonly ConcurrentDictionary flagtoggle = new ConcurrentDictionary(); + + /// Plugin Name + public string Name { get => "Aurora Label Items"; } + + public void OnFDRUpdate(FDP2.FDR updated) + { + if (FDP2.GetFDRIndex(updated.Callsign) == -1) //FDR was removed (that's what triggered the update) + { + eastboundCallsigns.TryRemove(updated.Callsign, out _); + flagtoggle.TryRemove(updated.Callsign, out _); + } + + else + + { + + if (updated.ParsedRoute.Count > 1) + { + //calculate track from first route point to last (Departure point to destination point) + var rte = updated.ParsedRoute; + double trk = Conversions.CalculateTrack(rte.First().Intersection.LatLong, rte.Last().Intersection.LatLong); + bool east = trk >= 0 && trk < 180; + eastboundCallsigns.AddOrUpdate(updated.Callsign, east, (c, e) => east); + } + } + } + + /// This is called each time a radar track is updated + public void OnRadarTrackUpdate(RDP.RadarTrack updated) + { + + } + + //public void Estimates(FDP2.FDR.ExtractedRoute.Segment estimate) + //{ + // estimate.IsPETO = true; + //} + + private void ItemMouseClick(CustomStripItemMouseClickEventArgs e) + { + bool flagToggled = flagtoggle.TryGetValue(e.Track.GetFDR().Callsign, out _); + + if (flagToggled) + { + flagtoggle.TryRemove(e.Track.GetFDR().Callsign, out _); + } + else + { + flagtoggle.TryAdd(e.Track.GetFDR().Callsign, 0); + } + e.Handled = true; + } + public CustomStripItem GetCustomStripItem(string itemType, Track track, FDP2.FDR flightDataRecord, RDP.RadarTrack radarTrack) + + { + int level = radarTrack == null ? flightDataRecord.PRL / 100 : radarTrack.CorrectedAltitude / 100; + bool isEastBound = true; + eastboundCallsigns.TryGetValue(flightDataRecord.Callsign, out isEastBound); + + + if (flightDataRecord == null) + return null; + + switch (itemType) + { + case STRIP_ITEM_CALLSIGN: + + + if (isEastBound) + { + return new CustomStripItem() + { + BackColourIdentity = Colours.Identities.StripText, + ForeColourIdentity = Colours.Identities.StripBackground, + Text = flightDataRecord.Callsign + }; + } + else + { + return new CustomStripItem() + { + BackColourIdentity = Colours.Identities.StripBackground, + ForeColourIdentity = Colours.Identities.StripText, + Text = flightDataRecord.Callsign + }; + } + + case STRIP_ITEM_CTLSECTOR: + + bool pendingCoordination = flightDataRecord.State == (FDR.FDRStates.STATE_PREACTIVE | FDR.FDRStates.STATE_COORDINATED); + string sectorName = flightDataRecord.ControllingSector == null ? "" : flightDataRecord.ControllingSector.Name; + + { + return new CustomStripItem() + { + ForeColourIdentity = pendingCoordination ? Colours.Identities.Custom : default, + CustomForeColour = Pending, + Text = sectorName + }; + } + + + + + case STRIP_ITEM_NXTSECTOR: + + TOC toc; + toc = new TOC(flightDataRecord); + + string firName = toc.nextSector == null ? "" : toc.nextSector.Name; + + { + return new CustomStripItem() + { + ForeColourIdentity = Colours.Identities.Custom, + CustomForeColour = Pending, + Text = firName + }; + } + + + + case LABEL_ITEM_ADSB_CPDLC: + + + if (!isEastBound && !flightDataRecord.ADSB && fpap.cpdlc) + + return new CustomStripItem() + { + BackColourIdentity = Colours.Identities.StripBackground, + ForeColourIdentity = Colours.Identities.StripText, + Text = "⧆" + }; + + if (isEastBound && !flightDataRecord.ADSB && fpap.cpdlc) + + return new CustomStripItem() + { + BackColourIdentity = Colours.Identities.StripText, + ForeColourIdentity = Colours.Identities.StripBackground, + Text = "⧆" + }; + + if (!isEastBound && !flightDataRecord.ADSB) + + return new CustomStripItem() + { + BackColourIdentity = Colours.Identities.StripBackground, + ForeColourIdentity = Colours.Identities.StripText, + Text = "⎕" + }; + + if (isEastBound && !flightDataRecord.ADSB) + + return new CustomStripItem() + { + BackColourIdentity = Colours.Identities.StripText, + ForeColourIdentity = Colours.Identities.StripBackground, + Text = "⎕" + }; + + if (!isEastBound && flightDataRecord.ADSB) + + return new CustomStripItem() + { + BackColourIdentity = Colours.Identities.StripBackground, + ForeColourIdentity = Colours.Identities.StripText, + Text = "*" + }; + + if (isEastBound && fpap.cpdlc) + + return new CustomStripItem() + { + BackColourIdentity = Colours.Identities.StripText, + ForeColourIdentity = Colours.Identities.StripBackground, + Text = "*" + }; + + return null; + + case STRIP_ITEM_T10_FLAG: + + if (flightDataRecord.PerformanceData?.IsJet ?? false) + + return new CustomStripItem() + { + //BackColourIdentity = Colours.Identities.Custom, + //CustomBackColour = SepFlags, + Text = "M" + //OnMouseClick = ItemMouseClick + }; + + return null; + + case STRIP_ITEM_MNT_FLAG: + + if (flightDataRecord.PerformanceData?.IsJet ?? false) + + return new CustomStripItem() + { + //BackColourIdentity = Colours.Identities.Custom, + //CustomBackColour = SepFlags, + Text = "R" + }; + + return null; + + case STRIP_ITEM_DIST_FLAG: + + if (fpap.adsc && fpap.cpdlc && (fpap.rnp4 || fpap.rnp10) && fpap.pbcs) + + + return new CustomStripItem() + { + BackColourIdentity = Colours.Identities.Custom, + CustomBackColour = SepFlags, + Text = fpap.rnp4 ? "3" : "D" + }; + return null; + + case STRIP_ITEM_RVSM_FLAG: + + if (flightDataRecord.RVSM) + + return new CustomStripItem() + { + BackColourIdentity = Colours.Identities.Custom, + CustomBackColour = SepFlags, + Text = "W" + }; + + return null; + + case STRIP_ITEM_VMI: + var vs = radarTrack == null ? flightDataRecord.PredictedPosition.VerticalSpeed : radarTrack.VerticalSpeed; + + if (level == fpap.cfl || level == flightDataRecord.RFL)//level + + return new CustomStripItem() + { + Text = "" + }; + else if (fpap.cfl > level && track.NewCFL || vs > 300)//Issued or trending climb + + return new CustomStripItem() + { + Text = "↑", + }; + + else if (fpap.cfl > 0 && fpap.cfl < level && track.NewCFL || vs < -300)//Issued or trending descent + + return new CustomStripItem() + { + Text = "↓", + }; + + return null; + + case STRIP_ITEM_COMPLEX: + + if (flightDataRecord.LabelOpData.Contains("AT ") || flightDataRecord.LabelOpData.Contains(" BY ") || + flightDataRecord.LabelOpData.Contains("CLEARED TO ")) + + return new CustomStripItem() + { + Text = "*" + }; + + return null; + + case STRIP_ITEM_CLEARED_LEVEL: + + if (fpap.cfl == 0) + { + return new CustomStripItem() + { + Text = "" + }; + } + + else + { + return new CustomStripItem() + { + Text = fpap.cfl.ToString() + }; + } + + case STRIP_ITEM_REQUESTED_LEVEL: + + if (flightDataRecord.State == FDR.FDRStates.STATE_INACTIVE || flightDataRecord.State == FDR.FDRStates.STATE_INACTIVE) + { + return new CustomStripItem() + { + Text = fpap.rfl.ToString(), + }; + } + + else + { + return new CustomStripItem() + { + Text = "" + }; + } + + //case STRIP_ITEM_MAN_EST: + + //if (Estimates) + // return new CustomStripItem() + // { + // BackColourIdentity = Colours.Identities.HighlightedText + // }; + //return null; + + //case STRIP_ITEM_POINT: + // Coordinate coordinate = Conversions.ConvertToCoordinate(FDR.ExtractedRoute); + // + // if (StripItemType.Point == ) + // return new CustomStripItem() + // { + // Text = Conversions.ConvertToFlightplanLatLong() + // }; + case STRIP_ITEM_ROUTE: + + return new CustomStripItem() + { + Text = "F", + //OnMouseClick = ItemMouseClick + }; + + + case STRIP_ITEM_RADAR_IND: + + return new CustomStripItem() + { + Text = "A", + //OnMouseClick = + }; + + + case STRIP_ITEM_ANNOT_IND: + + bool scratch = String.IsNullOrEmpty(flightDataRecord.LabelOpData); + + if (scratch) + { + return new CustomStripItem() + { + Text = "." + }; + } + + else + { + return new CustomStripItem() + { + Text = "&" + }; + } + + + case STRIP_ITEM_LATERAL_FLAG: + + if (fpap.adsc && fpap.cpdlc && (fpap.rnp4 || fpap.rnp10) && fpap.pbcs) + + + return new CustomStripItem() + { + BackColourIdentity = Colours.Identities.Custom, + CustomBackColour = SepFlags, + Text = fpap.rnp4 ? "4" : fpap.rnp10 ? "R" : "", + //OnMouseClick = ItemMouseClick + }; + return null; + + case STRIP_ITEM_RESTR: + + if (flightDataRecord.LabelOpData.Contains("AT ") || flightDataRecord.LabelOpData.Contains(" BY ") || + flightDataRecord.LabelOpData.Contains("CLEARED TO ")) + + return new CustomStripItem() + { + Text = "x" + }; + + return null; + + case STRIP_ITEM_CLRD_RTE: + + return new CustomStripItem() + { + Text = "Cleared Route:" + flightDataRecord.RouteNoParse + }; + + //if (label.imminentConflict.TryGetValue(flightDataRecord.Callsign, out _) || (label.advisoryConflict.TryGetValue(flightDataRecord.Callsign, out)) == flightDataRecord.Callsign; + + case CPAR_ITEM_TYPE: + + return new CustomStripItem() + { + Text = cpar.conflictType + }; + + case CPAR_ITEM_REQUIRED: + + if(cpar.longType == cpar.timeLongsame) + + return new CustomStripItem() + { + Text = "REQUIRED " + cpar.longTimesep + " ( " + cpar.latSep + ") " + cpar.verticalSep + " ft" + }; + + else + return new CustomStripItem() + { + Text = "REQUIRED " + cpar.longDistsep + " ( " + cpar.latSep + ") " + cpar.verticalSep + " ft" + }; + + case CPAR_ITEM_ANGLE: + + return new CustomStripItem() + { + Text = cpar.trkAngle.ToString() + " degrees" + }; + + case CPAR_ITEM_LOS: + + return new CustomStripItem() + { + Text = cpar.earliestLOS.ToString() + }; + + case CPAR_ITEM_ACTUAL: + + if (cpar.longType == cpar.timeLongsame) + + return new CustomStripItem() + { + Text = " ACTUAL " + cpar.longTimeact + " ( " + cpar.latAct + ") " + cpar.verticalAct + " ft" + }; + + else + return new CustomStripItem() + { + Text = " ACTUAL " + cpar.longDistact + " ( " + cpar.latAct +") " + cpar.verticalAct + " ft" + }; + + case CPAR_ITEM_PASSING: + + return new CustomStripItem() + { + Text = cpar.top.Time.ToString() + }; + + case CPAR_ITEM_CONF_SEG_START_1: + + return new CustomStripItem() + { + Text = cpar.startLatlong.ToString() + }; + + case CPAR_ITEM_CONF_SEG_START_2: + + return new CustomStripItem() + { + Text = cpar.startLatlong.ToString() + }; + + case CPAR_ITEM_CONF_SEG_END_1: + + return new CustomStripItem() + { + Text = cpar.endLatlong.ToString() + }; + + case CPAR_ITEM_CONF_SEG_END_2: + + return new CustomStripItem() + { + Text = cpar.endLatlong.ToString() + }; + + case CPAR_ITEM_STARTIME_1: + + return new CustomStripItem() + { + Text = cpar.startTime.ToString() + }; + + case CPAR_ITEM_STARTIME_2: + + return new CustomStripItem() + { + Text = cpar.startTime.ToString() + }; + + case CPAR_ITEM_ENDTIME_1: + + return new CustomStripItem() + { + Text = cpar.endTime.ToString() + }; + + case CPAR_ITEM_ENDTIME_2: + + return new CustomStripItem() + { + Text = cpar.endTime.ToString() + }; + + case CPAR_ITEM_AID_2: + + return new CustomStripItem() + { + Text = cpar.fdr2.Callsign + }; + + case CPAR_ITEM_TYP_2: + + return new CustomStripItem() + { + Text = cpar.fdr2.AircraftType + }; + + case CPAR_ITEM_SPD_2: + + return new CustomStripItem() + { + Text = cpar.fdr2.TAS.ToString() + }; + + case CPAR_ITEM_ALT_2: + + return new CustomStripItem() + { + Text = cpar.fdr2.PredictedPosition.Altitude.ToString() + }; + + default: return null; + } + } + //private CustomColour PETOColor(FDP2.FDR.ExtractedRoute.Segment estimate, Colours.Identities state) + //{ + // if (estimate.IsPETO) + // { + // return state = state; + // } + // + // return null; + //} + } +} From c3ad2ef3f9ab009e0a57c0f54a2034cd71baabe6 Mon Sep 17 00:00:00 2001 From: Maxim Salikhov Date: Mon, 12 Feb 2024 21:54:18 -0500 Subject: [PATCH 38/76] Reformat code and cleanup --- .gitignore | 5 +- AdvancedTechnologyOceanicProcedures.csproj | 71 - AuroraLabelItemsPlugin.cs | 614 +-- AuroraLabelItemsPlugin.csproj | 110 +- AuroraStripItemPlugin.cs | 647 ++- CPAR.cs | 621 ++- ConflictSummaryWindw.Designer.cs | 267 - ConflictSummaryWindw.cs | 34 - ConflictSummaryWindw.resx | 4632 ----------------- FAAStripItemPlugin.cs | 156 - FPAP.cs | 57 +- GEO.cs | 480 +- MEARTSLabelItemsPlugin.cs | 319 -- Properties/AssemblyInfo.cs | 2 +- Strips.cs | 620 --- TOC.cs | 52 +- bin/Release/AuroraLabelItemsPlugin.dll | Bin 10752 -> 0 bytes bin/Release/AuroraLabelItemsPlugin.pdb | Bin 26112 -> 0 bytes ...ework,Version=v4.7.2.AssemblyAttributes.cs | 4 - ...gnTimeResolveAssemblyReferencesInput.cache | Bin 6879 -> 0 bytes ...ework,Version=v4.7.2.AssemblyAttributes.cs | 4 - ...ItemsPlugin.csproj.CoreCompileInputs.cache | 1 - ...belItemsPlugin.csproj.FileListAbsolute.txt | 12 - obj/Release/AuroraLabelItemsPlugin.dll | Bin 10752 -> 0 bytes obj/Release/AuroraLabelItemsPlugin.pdb | Bin 26112 -> 0 bytes ...gnTimeResolveAssemblyReferencesInput.cache | Bin 6883 -> 0 bytes 26 files changed, 1240 insertions(+), 7468 deletions(-) delete mode 100644 AdvancedTechnologyOceanicProcedures.csproj delete mode 100644 ConflictSummaryWindw.Designer.cs delete mode 100644 ConflictSummaryWindw.cs delete mode 100644 ConflictSummaryWindw.resx delete mode 100644 FAAStripItemPlugin.cs delete mode 100644 MEARTSLabelItemsPlugin.cs delete mode 100644 Strips.cs delete mode 100644 bin/Release/AuroraLabelItemsPlugin.dll delete mode 100644 bin/Release/AuroraLabelItemsPlugin.pdb delete mode 100644 obj/Debug/.NETFramework,Version=v4.7.2.AssemblyAttributes.cs delete mode 100644 obj/Debug/DesignTimeResolveAssemblyReferencesInput.cache delete mode 100644 obj/Release/.NETFramework,Version=v4.7.2.AssemblyAttributes.cs delete mode 100644 obj/Release/AuroraLabelItemsPlugin.csproj.CoreCompileInputs.cache delete mode 100644 obj/Release/AuroraLabelItemsPlugin.csproj.FileListAbsolute.txt delete mode 100644 obj/Release/AuroraLabelItemsPlugin.dll delete mode 100644 obj/Release/AuroraLabelItemsPlugin.pdb delete mode 100644 obj/Release/DesignTimeResolveAssemblyReferencesInput.cache diff --git a/.gitignore b/.gitignore index 4ce6fdd..339ce9e 100644 --- a/.gitignore +++ b/.gitignore @@ -337,4 +337,7 @@ ASALocalRun/ .localhistory/ # BeatPulse healthcheck temp database -healthchecksdb \ No newline at end of file +healthchecksdb + +obj/ +bin/ \ No newline at end of file diff --git a/AdvancedTechnologyOceanicProcedures.csproj b/AdvancedTechnologyOceanicProcedures.csproj deleted file mode 100644 index 483638a..0000000 --- a/AdvancedTechnologyOceanicProcedures.csproj +++ /dev/null @@ -1,71 +0,0 @@ - - - - - Debug - AnyCPU - {59170BAC-129C-4AB8-884D-F583E460AA63} - Library - Properties - AuroraLabelItemsPlugin - AdvancedTechnologyOceanicProcedures - v4.7.2 - 512 - true - - - true - full - false - bin\Debug\ - DEBUG;TRACE - prompt - 4 - x86 - - - pdbonly - true - bin\Release\ - TRACE - prompt - 4 - x86 - - - - - - - - - - - - - - - False - E:\vatsys\bin\vatSys.exe - - - - - - - designer - - - ConflictSummaryWindw.cs - - - - - - - - ConflictSummaryWindw.cs - - - - \ No newline at end of file diff --git a/AuroraLabelItemsPlugin.cs b/AuroraLabelItemsPlugin.cs index 495a900..2c28aae 100644 --- a/AuroraLabelItemsPlugin.cs +++ b/AuroraLabelItemsPlugin.cs @@ -1,19 +1,15 @@ -using System; -using System.Threading; +//<--Need to add a reference to System.ComponentModel.Composition +using System; using System.Collections.Concurrent; +using System.Collections.Generic; using System.ComponentModel.Composition; -using System.Linq; //<--Need to add a reference to System.ComponentModel.Composition +using System.Linq; using System.Text.RegularExpressions; +using System.Threading; using vatsys; using vatsys.Plugin; using static vatsys.FDP2; using static vatsys.SectorsVolumes; -using System.Collections.Generic; -using System.Runtime.CompilerServices; - - - - //Note the reference to vatsys (set Copy Local to false) -----> @@ -25,45 +21,55 @@ public class AuroraLabelItemsPlugin : ILabelPlugin { /// The name of the custom label item we've added to Labels /// in the Profile - const string LABEL_ITEM_SELECT_HORI = "SELECT_HORI"; - const string LABEL_ITEM_SELECT_VERT = "SELECT_VERT"; - const string LABEL_ITEM_COMM_ICON = "AURORA_COMM_ICON"; //field a(2) - const string LABEL_ITEM_ADSB_CPDLC = "AURORA_ADSB_CPDLC"; //field c(4) - const string LABEL_ITEM_ADS_FLAGS = "AURORA_ADS_FLAGS"; //field c(4) - const string LABEL_ITEM_MNT_FLAGS = "AURORA_MNT_FLAGS"; //field c(4) - const string LABEL_ITEM_SCC = "AURORA_SCC"; //field d(5) - const string LABEL_ITEM_ANNOT_IND = "AURORA_ANNOT_IND"; //field e(1) - const string LABEL_ITEM_RESTR = "AURORA_RESTR"; //field f(1) - const string LABEL_ITEM_LEVEL = "AURORA_LEVEL"; //field g(3) - const string LABEL_ITEM_VMI = "AURORA_VMI"; //field h(1) - const string LABEL_ITEM_CLEARED_LEVEL = "AURORA_CLEARED_LEVEL"; //field i(7) - const string LABEL_ITEM_HANDOFF_IND = "AURORA_HO_IND"; //field j(4) - const string LABEL_ITEM_RADAR_IND = "AURORA_RADAR_IND"; //field k(1) - const string LABEL_ITEM_INHIBIT_IND = "AURORA_INHIBIT_IND"; //field l(1) - const string LABEL_ITEM_FILED_SPEED = "AURORA_FILEDSPEED"; //field m(4) - const string LABEL_ITEM_3DIGIT_GROUNDSPEED = "AURORA_GROUNDSPEED"; //field n(5) - const string LABEL_ITEM_DESTINATION = "AURORA_DESTINATION"; //field o(4) - readonly static CustomColour EastboundColour = new CustomColour(240, 255, 255); - readonly static CustomColour WestboundColour = new CustomColour(240, 231, 140); - readonly static CustomColour NonRVSM = new CustomColour(242, 133, 0); - readonly static CustomColour Probe = new CustomColour(0, 255, 0); - readonly static CustomColour NotCDA = new CustomColour(100, 0, 100); - readonly static CustomColour Advisory = new CustomColour(255, 165, 0); - readonly static CustomColour Imminent = new CustomColour(255, 0, 0); - readonly static CustomColour SpecialConditionCode = new CustomColour(255, 255, 0); - readonly static CustomColour ApsBlue = new CustomColour(141, 182, 205); - readonly ConcurrentDictionary eastboundCallsigns = new ConcurrentDictionary(); - readonly ConcurrentDictionary adsbcpdlcValues = new ConcurrentDictionary(); - readonly ConcurrentDictionary adsflagValues = new ConcurrentDictionary(); - readonly ConcurrentDictionary mntflagValues = new ConcurrentDictionary(); - readonly ConcurrentDictionary sccflagValues = new ConcurrentDictionary(); - readonly ConcurrentDictionary altValues = new ConcurrentDictionary(); - readonly ConcurrentDictionary radartoggle = new ConcurrentDictionary(); - readonly ConcurrentDictionary mntflagtoggle = new ConcurrentDictionary(); - readonly ConcurrentDictionary downlink = new ConcurrentDictionary(); - public readonly ConcurrentDictionary> advisoryConflict = new ConcurrentDictionary>(); - public readonly ConcurrentDictionary> imminentConflict = new ConcurrentDictionary>(); - + private const string LABEL_ITEM_SELECT_HORI = "SELECT_HORI"; + + private const string LABEL_ITEM_SELECT_VERT = "SELECT_VERT"; + private const string LABEL_ITEM_COMM_ICON = "AURORA_COMM_ICON"; //field a(2) + private const string LABEL_ITEM_ADSB_CPDLC = "AURORA_ADSB_CPDLC"; //field c(4) + private const string LABEL_ITEM_ADS_FLAGS = "AURORA_ADS_FLAGS"; //field c(4) + private const string LABEL_ITEM_MNT_FLAGS = "AURORA_MNT_FLAGS"; //field c(4) + private const string LABEL_ITEM_SCC = "AURORA_SCC"; //field d(5) + private const string LABEL_ITEM_ANNOT_IND = "AURORA_ANNOT_IND"; //field e(1) + private const string LABEL_ITEM_RESTR = "AURORA_RESTR"; //field f(1) + private const string LABEL_ITEM_LEVEL = "AURORA_LEVEL"; //field g(3) + private const string LABEL_ITEM_VMI = "AURORA_VMI"; //field h(1) + private const string LABEL_ITEM_CLEARED_LEVEL = "AURORA_CLEARED_LEVEL"; //field i(7) + private const string LABEL_ITEM_HANDOFF_IND = "AURORA_HO_IND"; //field j(4) + private const string LABEL_ITEM_RADAR_IND = "AURORA_RADAR_IND"; //field k(1) + private const string LABEL_ITEM_INHIBIT_IND = "AURORA_INHIBIT_IND"; //field l(1) + private const string LABEL_ITEM_FILED_SPEED = "AURORA_FILEDSPEED"; //field m(4) + private const string LABEL_ITEM_3DIGIT_GROUNDSPEED = "AURORA_GROUNDSPEED"; //field n(5) + private const string LABEL_ITEM_DESTINATION = "AURORA_DESTINATION"; //field o(4) + private static readonly CustomColour EastboundColour = new CustomColour(240, 255, 255); + private static readonly CustomColour WestboundColour = new CustomColour(240, 231, 140); + private static readonly CustomColour NonRVSM = new CustomColour(242, 133, 0); + private static readonly CustomColour Probe = new CustomColour(0, 255, 0); + private static readonly CustomColour NotCDA = new CustomColour(100, 0, 100); + private static readonly CustomColour Advisory = new CustomColour(255, 165, 0); + private static readonly CustomColour Imminent = new CustomColour(255, 0, 0); + private static readonly CustomColour SpecialConditionCode = new CustomColour(255, 255, 0); + private static readonly CustomColour ApsBlue = new CustomColour(141, 182, 205); + private readonly ConcurrentDictionary adsbcpdlcValues = new ConcurrentDictionary(); + private readonly ConcurrentDictionary adsflagValues = new ConcurrentDictionary(); + + public readonly ConcurrentDictionary> advisoryConflict = + new ConcurrentDictionary>(); + + private readonly ConcurrentDictionary altValues = new ConcurrentDictionary(); + private readonly ConcurrentDictionary downlink = new ConcurrentDictionary(); + + private readonly ConcurrentDictionary eastboundCallsigns = + new ConcurrentDictionary(); + + public readonly ConcurrentDictionary> imminentConflict = + new ConcurrentDictionary>(); + + private readonly ConcurrentDictionary mntflagtoggle = new ConcurrentDictionary(); + private readonly ConcurrentDictionary mntflagValues = new ConcurrentDictionary(); + private readonly ConcurrentDictionary radartoggle = new ConcurrentDictionary(); + + private readonly ConcurrentDictionary + sccflagValues = new ConcurrentDictionary(); public AuroraLabelItemsPlugin() @@ -73,52 +79,29 @@ public AuroraLabelItemsPlugin() } - private void Network_RadioMessageAcknowledged(object sender, RadioMessageEventArgs e) - { - throw new NotImplementedException(); - } - - private void Network_PrivateMessagesChanged(object sender, Network.GenericMessageEventArgs e) - { - bool downLink = e.Message.Sent == true; - - if (downLink) - { - downlink.TryRemove(e.Message.Address, out _); - } - else - { - downlink.TryAdd(e.Message.Address, 0); - } - } - - /// Plugin Name - public string Name - { - get => "Aurora Label Items"; - } + public string Name => "Aurora Label Items"; /// This is called each time a flight data record is updated /// Here we are updating the eastbound callsigns dictionary with each flight data record /// When the FDR is updated we check if it still exists in the Flight Data Processor and remove from our dictionary if not. Otherwise we do some simple regex matching to find /// the flight planned PBN category and store the character we want to display in the label in the dictionary. - public void OnFDRUpdate(FDP2.FDR updated) + public void OnFDRUpdate(FDR updated) { var pbn = Regex.Match(updated.Remarks, @"PBN\/\w+\s"); - bool rnp10 = pbn.Value.Contains ("A1"); - bool rnp4 = pbn.Value.Contains("L1"); - bool cpdlc = updated.AircraftEquip.Contains("J5") || updated.AircraftEquip.Contains("J7"); - bool adsc = updated.AircraftSurvEquip.Contains("D1"); - bool jet = updated.PerformanceData?.IsJet ?? false; + var rnp10 = pbn.Value.Contains("A1"); + var rnp4 = pbn.Value.Contains("L1"); + var cpdlc = updated.AircraftEquip.Contains("J5") || updated.AircraftEquip.Contains("J7"); + var adsc = updated.AircraftSurvEquip.Contains("D1"); + var jet = updated.PerformanceData?.IsJet ?? false; var vs = updated.PredictedPosition.VerticalSpeed; - int prl = updated.PRL / 100; - int cfl = updated.CFLUpper; - int rfl = updated.RFL; - int alt = cfl == -1 ? rfl : cfl; + var prl = updated.PRL / 100; + var cfl = updated.CFLUpper; + var rfl = updated.RFL; + var alt = cfl == -1 ? rfl : cfl; + - - if (FDP2.GetFDRIndex(updated.Callsign) == -1) + if (GetFDRIndex(updated.Callsign) == -1) { eastboundCallsigns.TryRemove(updated.Callsign, out _); adsbcpdlcValues.TryRemove(updated.Callsign, out _); @@ -131,12 +114,9 @@ public void OnFDRUpdate(FDP2.FDR updated) downlink.TryRemove(updated.Callsign, out _); advisoryConflict.TryRemove(updated.Callsign, out _); imminentConflict.TryRemove(updated.Callsign, out _); - } else { - - char c1 = default; if (!updated.ADSB && cpdlc) @@ -174,7 +154,7 @@ public void OnFDRUpdate(FDP2.FDR updated) NetworkPilot code; code = new NetworkPilot(); - string d1 = string.Empty; + var d1 = string.Empty; if (!rnp10 || !rnp4) d1 = "RNP"; @@ -195,13 +175,13 @@ public void OnFDRUpdate(FDP2.FDR updated) char h1 = default; - if (Math.Abs(updated.PRL - alt) <= 299) //level flight + if (Math.Abs(updated.PRL - alt) <= 299) //level flight h1 = default; else if (alt / 100 > prl || vs > 300) //Issued or trending climb h1 = '↑'; - else if (alt / 100 > 0 && alt < prl || vs < -300) //Issued or trending descent + else if ((alt / 100 > 0 && alt < prl) || vs < -300) //Issued or trending descent h1 = '↓'; else if (prl - alt / 100 >= 3) //deviating above @@ -217,87 +197,27 @@ public void OnFDRUpdate(FDP2.FDR updated) { //calculate track from first route point to last (Departure point to destination point) var rte = updated.ParsedRoute; - double trk = Conversions.CalculateTrack(rte.First().Intersection.LatLong, + var trk = Conversions.CalculateTrack(rte.First().Intersection.LatLong, rte.Last().Intersection.LatLong); - bool east = trk >= 0 && trk < 180; + var east = trk >= 0 && trk < 180; eastboundCallsigns.AddOrUpdate(updated.Callsign, east, (c, e) => east); } TransferOfControl(updated); - CPAR cpar = new CPAR(); + var cpar = new CPAR(); - if (jet & rnp4 & cpdlc & adsc) ///Using CalculateAreaofConflict method against intruder aircraft - { + if (jet & rnp4 & cpdlc & adsc) ///Using CalculateAreaofConflict method against intruder aircraft cpar.ConflictProbe(updated, 23); - } else if (rnp4 || rnp10) - { cpar.ConflictProbe(updated, 50); - } else if (rnp10) - { cpar.ConflictProbe(updated, 75); - } else - { cpar.ConflictProbe(updated, 100); - } } } - - private static void TOC(RDP.RadarTrack rt) - { - var fdr = rt.CoupledFDR; - if (fdr != null && rt != null) - { - TransferOfControl(fdr); - } - } - - - private static void TransferOfControl(FDP2.FDR fdr) - { - TOC toc; - toc = new TOC(fdr); - - var rt = fdr.CoupledTrack; - if (fdr != null) - if (!fdr.ESTed && MMI.IsMySectorConcerned(fdr)) - { - MMI.EstFDR(fdr); - } - - if (MMI.SectorsControlled.ToList() - .Exists(s => s.IsInSector(fdr.GetLocation(), fdr.PRL)) && !fdr.IsTrackedByMe && !fdr.IsTracked) //MMI.SectorsControlled.Contains(fdr.ControllingSector) || fdr.ControllingSector == null - { - MMI.AcceptJurisdiction(fdr); - } - - - - foreach (Volume volume in Volumes) - { - if (rt != null && (fdr.PRL == -1 || (fdr.PRL <= volume.UpperLevel && fdr.PRL > volume.LowerLevel)) && Conversions.IsLatlonInPoly(fdr.GetLocation(), volume.Boundary)) - { - - var whichVol = volume; - var whichFIR = SectorsVolumes.FindSector(whichVol); - if (MMI.GetSectorEntryTime(fdr) == DateTime.MaxValue && MMI.SectorsControlled.ToList().TrueForAll(s => !s.IsInSector(fdr.GetLocation(), fdr.PRL))) // && whichFIR != fdr.ControllingSector - - { - //toc.HandoffNextSector(); - MMI.HandoffJurisdiction(fdr, whichFIR); - MMI.Inhibit(fdr); - Thread.Sleep(300000); - RDP.DeCouple(rt); - } - } - } - - } - //void SendNextDataAuthority(Network network, NetworkPilot pilot, VSCSFrequency freq) //{ // @@ -316,29 +236,9 @@ private static void TransferOfControl(FDP2.FDR fdr) //} - - - /// Could use the new position of the radar track or its change in state (cancelled, etc.) to do some processing. + /// Could use the new position of the radar track or its change in state (cancelled, etc.) to do some processing. public void OnRadarTrackUpdate(RDP.RadarTrack updated) { - - } - - - private void HandleRadarFlagClick(CustomLabelItemMouseClickEventArgs e) - { - bool radarToggled = radartoggle.TryGetValue(e.Track.GetFDR().Callsign, out _); - - if (radarToggled) - { - radartoggle.TryRemove(e.Track.GetFDR().Callsign, out _); - } - else - { - radartoggle.TryAdd(e.Track.GetFDR().Callsign, 0); - } - - e.Handled = true; } @@ -346,7 +246,8 @@ private void HandleRadarFlagClick(CustomLabelItemMouseClickEventArgs e) /// itemType is the value of the Type attribute in Labels.xml /// If it's not our item being called (another plugins, for example), return null. /// As a general rule, don't do processing in here as you'll slow down the ASD refresh. In the case of parsing a level to a string though, that's fine. - public CustomLabelItem GetCustomLabelItem(string itemType, Track track, FDP2.FDR flightDataRecord, RDP.RadarTrack radarTrack) + public CustomLabelItem GetCustomLabelItem(string itemType, Track track, FDR flightDataRecord, + RDP.RadarTrack radarTrack) { if (flightDataRecord == null || radarTrack == null) return null; @@ -362,100 +263,86 @@ public CustomLabelItem GetCustomLabelItem(string itemType, Track track, FDP2.FDR char h1; altValues.TryGetValue(flightDataRecord.Callsign, out h1); - bool radarToggled = radartoggle.TryGetValue(flightDataRecord.Callsign, out _); - bool mntflagToggled = mntflagtoggle.TryGetValue(flightDataRecord.Callsign, out _); - bool downLink = downlink.TryGetValue(flightDataRecord.Callsign, out _); - bool isNonRVSM = !flightDataRecord.RVSM; + var radarToggled = radartoggle.TryGetValue(flightDataRecord.Callsign, out _); + var mntflagToggled = mntflagtoggle.TryGetValue(flightDataRecord.Callsign, out _); + var downLink = downlink.TryGetValue(flightDataRecord.Callsign, out _); + var isNonRVSM = !flightDataRecord.RVSM; var pbn = Regex.Match(flightDataRecord.Remarks, @"PBN\/\w+\s"); - bool rnp10 = pbn.Value.Contains("A1"); - bool rnp4 = pbn.Value.Contains("L1"); - int prl = flightDataRecord.PRL / 100; - int cfl = flightDataRecord.CFLUpper / 100; - int rfl = flightDataRecord.RFL / 100; - int alt = flightDataRecord.CFLUpper == -1 ? rfl : cfl; - var notProbe = flightDataRecord.State == (FDR.FDRStates.STATE_PREACTIVE | FDR.FDRStates.STATE_COORDINATED) ? BorderFlags.All : BorderFlags.None; - var colour = (!flightDataRecord.RVSM ? NonRVSM : ExcludeConflictColor(track, flightDataRecord)); - var excludeConflict = (SelectASDTrackColour(track) == GetConflictColour(flightDataRecord.Callsign)); + var rnp10 = pbn.Value.Contains("A1"); + var rnp4 = pbn.Value.Contains("L1"); + var prl = flightDataRecord.PRL / 100; + var cfl = flightDataRecord.CFLUpper / 100; + var rfl = flightDataRecord.RFL / 100; + var alt = flightDataRecord.CFLUpper == -1 ? rfl : cfl; + var notProbe = flightDataRecord.State == (FDR.FDRStates.STATE_PREACTIVE | FDR.FDRStates.STATE_COORDINATED) + ? BorderFlags.All + : BorderFlags.None; + var colour = !flightDataRecord.RVSM ? NonRVSM : ExcludeConflictColor(track, flightDataRecord); + var excludeConflict = SelectASDTrackColour(track) == GetConflictColour(flightDataRecord.Callsign); switch (itemType) { + case LABEL_ITEM_SELECT_HORI: - case LABEL_ITEM_SELECT_HORI: + if (MMI.SelectedTrack?.GetFDR()?.Callsign == track.GetFDR().Callsign) + return new CustomLabelItem + { + Text = "", + Border = BorderFlags.Bottom + }; + + return null; + + case LABEL_ITEM_SELECT_VERT: if (MMI.SelectedTrack?.GetFDR()?.Callsign == track.GetFDR().Callsign) - { - return new CustomLabelItem() - - { - Text = "", - Border = BorderFlags.Bottom - }; - } - - return null; - - case LABEL_ITEM_SELECT_VERT: - - if (MMI.SelectedTrack?.GetFDR()?.Callsign == track.GetFDR().Callsign) - { - return new CustomLabelItem() - { - Text = "", - Border = BorderFlags.Left - }; - } - - return null; + return new CustomLabelItem + { + Text = "", + Border = BorderFlags.Left + }; + + return null; case LABEL_ITEM_COMM_ICON: if (downLink) - { - return new CustomLabelItem() + return new CustomLabelItem { Text = "▼", Border = BorderFlags.All, ForeColourIdentity = excludeConflict ? Colours.Identities.Custom : default, CustomForeColour = ExcludeConflictColor(track, flightDataRecord) }; - } - else + return new CustomLabelItem { - return new CustomLabelItem() - { - Text = "⬜", - ForeColourIdentity = excludeConflict ? Colours.Identities.Custom : default, - CustomForeColour = ExcludeConflictColor(track, flightDataRecord) - }; - } + Text = "⬜", + ForeColourIdentity = excludeConflict ? Colours.Identities.Custom : default, + CustomForeColour = ExcludeConflictColor(track, flightDataRecord) + }; case LABEL_ITEM_ADSB_CPDLC: - bool useCustomForeColour = + var useCustomForeColour = flightDataRecord.State == (FDR.FDRStates.STATE_PREACTIVE | FDR.FDRStates.STATE_COORDINATED); if (useCustomForeColour) - { - return new CustomLabelItem() + return new CustomLabelItem { ForeColourIdentity = Colours.Identities.Custom, CustomForeColour = NotCDA, Text = c1.ToString() }; - } - else + return new CustomLabelItem { - return new CustomLabelItem() - { - Text = c1.ToString(), - ForeColourIdentity = excludeConflict ? Colours.Identities.Custom : default, - CustomForeColour = ExcludeConflictColor(track, flightDataRecord) - }; - } + Text = c1.ToString(), + ForeColourIdentity = excludeConflict ? Colours.Identities.Custom : default, + CustomForeColour = ExcludeConflictColor(track, flightDataRecord) + }; case LABEL_ITEM_ADS_FLAGS: - return new CustomLabelItem() + return new CustomLabelItem { Text = c2.ToString(), ForeColourIdentity = excludeConflict ? Colours.Identities.Custom : default, @@ -466,63 +353,55 @@ public CustomLabelItem GetCustomLabelItem(string itemType, Track track, FDP2.FDR case LABEL_ITEM_MNT_FLAGS: if (mntflagToggled) - { - return new CustomLabelItem() + return new CustomLabelItem { Text = c3.ToString(), ForeColourIdentity = excludeConflict ? Colours.Identities.Custom : default, CustomForeColour = ExcludeConflictColor(track, flightDataRecord) }; - } - else - return new CustomLabelItem() - { - Text = "", - }; + return new CustomLabelItem + { + Text = "" + }; case LABEL_ITEM_SCC: - + + { + return new CustomLabelItem { - return new CustomLabelItem() - { - Text = d1, - ForeColourIdentity = Colours.Identities.Custom, - CustomForeColour = SpecialConditionCode - }; - } + Text = d1, + ForeColourIdentity = Colours.Identities.Custom, + CustomForeColour = SpecialConditionCode + }; + } case LABEL_ITEM_ANNOT_IND: - bool scratch = String.IsNullOrEmpty(flightDataRecord.LabelOpData); + var scratch = string.IsNullOrEmpty(flightDataRecord.LabelOpData); if (scratch) - { - return new CustomLabelItem() + return new CustomLabelItem { Text = "◦", ForeColourIdentity = excludeConflict ? Colours.Identities.Custom : default, CustomForeColour = ExcludeConflictColor(track, flightDataRecord) }; - } - else + return new CustomLabelItem { - return new CustomLabelItem() - { - Text = "&", - ForeColourIdentity = excludeConflict ? Colours.Identities.Custom : default, - CustomForeColour = ExcludeConflictColor(track, flightDataRecord) - }; - } + Text = "&", + ForeColourIdentity = excludeConflict ? Colours.Identities.Custom : default, + CustomForeColour = ExcludeConflictColor(track, flightDataRecord) + }; case LABEL_ITEM_RESTR: if (flightDataRecord.LabelOpData.Contains("AT ") || flightDataRecord.LabelOpData.Contains(" BY ") || flightDataRecord.LabelOpData.Contains("CLEARED TO ")) - return new CustomLabelItem() + return new CustomLabelItem { Text = "x", ForeColourIdentity = excludeConflict ? Colours.Identities.Custom : default, @@ -535,21 +414,20 @@ public CustomLabelItem GetCustomLabelItem(string itemType, Track track, FDP2.FDR var level = prl == -1 ? null : (radarTrack.CorrectedAltitude / 100).ToString(); - - return new CustomLabelItem() - { - Text = level.ToString(), - Border = notProbe, - BorderColourIdentity = Colours.Identities.Custom, - CustomBorderColour = NotCDA, - ForeColourIdentity = excludeConflict ? Colours.Identities.Custom : default, - CustomForeColour = colour - }; + return new CustomLabelItem + { + Text = level, + Border = notProbe, + BorderColourIdentity = Colours.Identities.Custom, + CustomBorderColour = NotCDA, + ForeColourIdentity = excludeConflict ? Colours.Identities.Custom : default, + CustomForeColour = colour + }; case LABEL_ITEM_VMI: - return new CustomLabelItem() + return new CustomLabelItem { Text = h1.ToString(), ForeColourIdentity = excludeConflict ? Colours.Identities.Custom : default, @@ -557,30 +435,26 @@ public CustomLabelItem GetCustomLabelItem(string itemType, Track track, FDP2.FDR }; - case LABEL_ITEM_CLEARED_LEVEL: if (radarTrack.ReachedCFL || prl == alt || Math.Abs(flightDataRecord.PRL - alt) < 300) - return new CustomLabelItem() + return new CustomLabelItem { Text = "" }; - else + return new CustomLabelItem { - return new CustomLabelItem() - { - Text = alt.ToString(), - Border = notProbe, - BorderColourIdentity = Colours.Identities.Custom, - CustomBorderColour = NotCDA, - ForeColourIdentity = excludeConflict ? Colours.Identities.Custom : default, - CustomForeColour = colour - }; - } + Text = alt.ToString(), + Border = notProbe, + BorderColourIdentity = Colours.Identities.Custom, + CustomBorderColour = NotCDA, + ForeColourIdentity = excludeConflict ? Colours.Identities.Custom : default, + CustomForeColour = colour + }; -// case LABEL_ITEM_HANDOFF_IND: + // case LABEL_ITEM_HANDOFF_IND: // // // if (flightDataRecord.IsHandoff) @@ -611,58 +485,48 @@ public CustomLabelItem GetCustomLabelItem(string itemType, Track track, FDP2.FDR if (radarToggled) - { - return new CustomLabelItem() + return new CustomLabelItem { Text = "★", OnMouseClick = HandleRadarFlagClick, ForeColourIdentity = excludeConflict ? Colours.Identities.Custom : default, CustomForeColour = ExcludeConflictColor(track, flightDataRecord) }; - } - else + return new CustomLabelItem { - return new CustomLabelItem() - { - Text = "◦", - OnMouseClick = HandleRadarFlagClick, - ForeColourIdentity = excludeConflict ? Colours.Identities.Custom : default, - CustomForeColour = ExcludeConflictColor(track, flightDataRecord) - }; - } + Text = "◦", + OnMouseClick = HandleRadarFlagClick, + ForeColourIdentity = excludeConflict ? Colours.Identities.Custom : default, + CustomForeColour = ExcludeConflictColor(track, flightDataRecord) + }; case LABEL_ITEM_INHIBIT_IND: if (flightDataRecord.State == FDR.FDRStates.STATE_INHIBITED) - { - return new CustomLabelItem() + return new CustomLabelItem { Text = "^", ForeColourIdentity = excludeConflict ? Colours.Identities.Custom : default, CustomForeColour = ExcludeConflictColor(track, flightDataRecord) }; - } - else + return new CustomLabelItem { - return new CustomLabelItem() - { - Text = "" - }; - } + Text = "" + }; case LABEL_ITEM_FILED_SPEED: - var mach = Conversions.CalculateMach(flightDataRecord.TAS, GRIB.FindTemperature(flightDataRecord.PRL, track.GetLocation(), true)); - return new CustomLabelItem() + var mach = Conversions.CalculateMach(flightDataRecord.TAS, + GRIB.FindTemperature(flightDataRecord.PRL, track.GetLocation(), true)); + return new CustomLabelItem { Text = "M" + Convert.ToDecimal(mach).ToString("F2").Replace(".", ""), //Text = "N" + flightDataRecord.TAS ForeColourIdentity = excludeConflict ? Colours.Identities.Custom : default, CustomForeColour = ExcludeConflictColor(track, flightDataRecord) - }; case LABEL_ITEM_3DIGIT_GROUNDSPEED: @@ -670,16 +534,16 @@ public CustomLabelItem GetCustomLabelItem(string itemType, Track track, FDP2.FDR var gs = radarTrack == null ? flightDataRecord.PredictedPosition.Groundspeed : radarTrack.GroundSpeed; - return new CustomLabelItem() + return new CustomLabelItem { - Text = "N" + gs.ToString("000"),//format as 3 digits (with leading zeros) + Text = "N" + gs.ToString("000"), //format as 3 digits (with leading zeros) ForeColourIdentity = excludeConflict ? Colours.Identities.Custom : default, CustomForeColour = ExcludeConflictColor(track, flightDataRecord) }; case LABEL_ITEM_DESTINATION: - return new CustomLabelItem() + return new CustomLabelItem { Text = flightDataRecord.DesAirport, ForeColourIdentity = excludeConflict ? Colours.Identities.Custom : default, @@ -701,36 +565,104 @@ public CustomColour SelectASDTrackColour(Track track) //only apply East/West colour to jurisdiction state - if (track.State == MMI.HMIStates.Jurisdiction) //read our dictionary of stored bools (true means is easterly) and return the correct colour - { - + if (track.State == + MMI.HMIStates + .Jurisdiction) //read our dictionary of stored bools (true means is easterly) and return the correct colour return GetConflictColour(fdr.Callsign) ?? GetDirectionColour(fdr.Callsign, fdr); - } - if (fdr.State != (FDR.FDRStates.STATE_PREACTIVE | FDR.FDRStates.STATE_COORDINATED)) //only apply conflict colours if planes are of concern - { + if (fdr.State != + (FDR.FDRStates.STATE_PREACTIVE | + FDR.FDRStates.STATE_COORDINATED)) //only apply conflict colours if planes are of concern return GetConflictColour(fdr.Callsign) ?? null; - } + return default; + } + + public CustomColour SelectGroundTrackColour(Track track) + { + return null; + } + + + private void Network_RadioMessageAcknowledged(object sender, RadioMessageEventArgs e) + { + throw new NotImplementedException(); + } + + private void Network_PrivateMessagesChanged(object sender, Network.GenericMessageEventArgs e) + { + var downLink = e.Message.Sent; + + if (downLink) + downlink.TryRemove(e.Message.Address, out _); else + downlink.TryAdd(e.Message.Address, 0); + } - return default; + private static void TOC(RDP.RadarTrack rt) + { + var fdr = rt.CoupledFDR; + if (fdr != null && rt != null) TransferOfControl(fdr); } - public CustomColour SelectGroundTrackColour(Track track) + + private static void TransferOfControl(FDR fdr) { - return null; + TOC toc; + toc = new TOC(fdr); + + var rt = fdr.CoupledTrack; + if (fdr != null) + if (!fdr.ESTed && MMI.IsMySectorConcerned(fdr)) + MMI.EstFDR(fdr); + + if (MMI.SectorsControlled.ToList() + .Exists(s => s.IsInSector(fdr.GetLocation(), fdr.PRL)) && !fdr.IsTrackedByMe && + !fdr.IsTracked) //MMI.SectorsControlled.Contains(fdr.ControllingSector) || fdr.ControllingSector == null + MMI.AcceptJurisdiction(fdr); + + + foreach (var volume in Volumes) + if (rt != null && (fdr.PRL == -1 || (fdr.PRL <= volume.UpperLevel && fdr.PRL > volume.LowerLevel)) && + Conversions.IsLatlonInPoly(fdr.GetLocation(), volume.Boundary)) + { + var whichVol = volume; + var whichFIR = FindSector(whichVol); + if (MMI.GetSectorEntryTime(fdr) == DateTime.MaxValue && MMI.SectorsControlled.ToList() + .TrueForAll(s => + !s.IsInSector(fdr.GetLocation(), fdr.PRL))) // && whichFIR != fdr.ControllingSector + + { + //toc.HandoffNextSector(); + MMI.HandoffJurisdiction(fdr, whichFIR); + MMI.Inhibit(fdr); + Thread.Sleep(300000); + RDP.DeCouple(rt); + } + } + } + + + private void HandleRadarFlagClick(CustomLabelItemMouseClickEventArgs e) + { + var radarToggled = radartoggle.TryGetValue(e.Track.GetFDR().Callsign, out _); + + if (radarToggled) + radartoggle.TryRemove(e.Track.GetFDR().Callsign, out _); + else + radartoggle.TryAdd(e.Track.GetFDR().Callsign, 0); + + e.Handled = true; } private CustomColour GetDirectionColour(string callsign, FDR fdr) { - if (eastboundCallsigns.TryGetValue(callsign, out bool east)) + if (eastboundCallsigns.TryGetValue(callsign, out var east)) { if (east) return EastboundColour; - else - return WestboundColour; + return WestboundColour; } return default; @@ -739,30 +671,18 @@ private CustomColour GetDirectionColour(string callsign, FDR fdr) private CustomColour GetConflictColour(string callsign) { if (imminentConflict.Count % 2 == 0 && imminentConflict.TryGetValue(callsign, out _)) - { return Imminent; - } - else if (advisoryConflict.Count % 2 == 0 && advisoryConflict.TryGetValue(callsign, out _)) - { - return Advisory; - } - + if (advisoryConflict.Count % 2 == 0 && advisoryConflict.TryGetValue(callsign, out _)) return Advisory; + return default; } - private CustomColour ExcludeConflictColor(Track track, FDP2.FDR flightDataRecord) + private CustomColour ExcludeConflictColor(Track track, FDR flightDataRecord) { if ((imminentConflict.Count > 0 || advisoryConflict.Count > 0) && track.State == MMI.HMIStates.Jurisdiction) - { return GetDirectionColour(flightDataRecord.Callsign, flightDataRecord); - } - else if (imminentConflict.Count > 0 || advisoryConflict.Count > 0) - { - return ApsBlue; - } + if (imminentConflict.Count > 0 || advisoryConflict.Count > 0) return ApsBlue; return default; - } - } } \ No newline at end of file diff --git a/AuroraLabelItemsPlugin.csproj b/AuroraLabelItemsPlugin.csproj index a4fcae4..5b60907 100644 --- a/AuroraLabelItemsPlugin.csproj +++ b/AuroraLabelItemsPlugin.csproj @@ -1,56 +1,60 @@  - - - Debug - AnyCPU - {59170BAC-129C-4AB8-884D-F583E460AA63} - Library - Properties - AuroraLabelItemsPlugin - AuroraLabelItemsPlugin - v4.7.2 - 512 - true - - - true - full - false - bin\Debug\ - DEBUG;TRACE - prompt - 4 - x86 - - - pdbonly - true - bin\Release\ - TRACE - prompt - 4 - x86 - - - - - - - - - - - - - E:\vatsys\bin\vatSys.exe - False - - - - - - - - + + + Debug + AnyCPU + {59170BAC-129C-4AB8-884D-F583E460AA63} + Library + Properties + AuroraLabelItemsPlugin + AuroraLabelItemsPlugin + v4.7.2 + 512 + true + + + true + full + false + bin\Debug\ + DEBUG;TRACE + prompt + 4 + x86 + + + pdbonly + true + bin\Release\ + TRACE + prompt + 4 + x86 + + + + + + + + + + + + + E:\vatsys\bin\vatSys.exe + False + + + + + + + + + + + + \ No newline at end of file diff --git a/AuroraStripItemPlugin.cs b/AuroraStripItemPlugin.cs index c0ed8e8..06eff03 100644 --- a/AuroraStripItemPlugin.cs +++ b/AuroraStripItemPlugin.cs @@ -1,74 +1,77 @@ -using System; +//<--Need to add a reference to System.ComponentModel.Composition +using System.Collections.Concurrent; +using System.ComponentModel.Composition; using System.Text.RegularExpressions; using vatsys; using vatsys.Plugin; -using System.Collections.Concurrent; -using System.ComponentModel.Composition; //<--Need to add a reference to System.ComponentModel.Composition using static vatsys.FDP2; -using System.Collections.Generic; -using System.Linq; namespace AuroraStripItemsPlugin { [Export(typeof(IPlugin))] - public class AuroraStripItemsPlugin : IStripPlugin { - AuroraLabelItemsPlugin.AuroraLabelItemsPlugin label = new AuroraLabelItemsPlugin.AuroraLabelItemsPlugin(); - CPAR cpar = new CPAR(); /// The name of the custom label item we've added to Labels /// in the Profile - const string LABEL_ITEM_ADSB_CPDLC = "AURORA_ADSB_CPDLC"; //field c(4) - const string STRIP_ITEM_CALLSIGN = "AURORA_CALLSIGN"; - const string STRIP_ITEM_CTLSECTOR = "AURORA_CDA"; - const string STRIP_ITEM_NXTSECTOR = "AURORA_NDA"; - const string STRIP_ITEM_T10_FLAG = "AURORA_T10_FLAG"; - const string STRIP_ITEM_MNT_FLAG = "AURORA_MNT_FLAG"; - const string STRIP_ITEM_DIST_FLAG = "AURORA_DIST_FLAG"; - const string STRIP_ITEM_RVSM_FLAG = "AURORA_RVSM_FLAG"; - const string STRIP_ITEM_VMI = "AURORA_STRIP_VMI"; - const string STRIP_ITEM_COMPLEX = "AURORA_STRIP_COMPLEX"; - const string STRIP_ITEM_CLEARED_LEVEL = "AURORA_CLEARED_LEVEL"; - const string STRIP_ITEM_REQUESTED_LEVEL = "AURORA_REQUESTED_LEVEL"; - const string STRIP_ITEM_MAN_EST = "AURORA_MAN_EST"; - const string STRIP_ITEM_POINT = "AURORA_POINT"; - const string STRIP_ITEM_ROUTE = "AURORA_ROUTE_STRIP"; - const string STRIP_ITEM_RADAR_IND = "AURORA_RADAR_IND"; - const string STRIP_ITEM_ANNOT_IND = "AURORA_ANNOT_STRIP"; - const string STRIP_ITEM_LATERAL_FLAG = "AURORA_LATERAL_FLAG"; - const string STRIP_ITEM_RESTR = "AURORA_RESTR_STRIP"; - const string STRIP_ITEM_CLRD_RTE = "AURORA_CLRD_RTE"; - const string CPAR_ITEM_TYPE = "CPAR_TYP"; - const string CPAR_ITEM_REQUIRED = "CPAR_REQUIRED"; - const string CPAR_ITEM_INTRUDER = "CPAR_INT"; - const string CPAR_ITEM_LOS = "CPAR_LOS"; - const string CPAR_ITEM_ACTUAL = "CPAR_ACTUAL"; - const string CPAR_ITEM_PASSING = "CPAR_PASSING"; - const string CPAR_ITEM_CONF_SEG_START_1 = "CPAR_CONF_SEG_START_1"; - const string CPAR_ITEM_CONF_SEG_START_2 = "CPAR_CONF_SEG_START_2"; - const string CPAR_ITEM_CONF_SEG_END_1 = "CPAR_CONF_SEG_END_1"; - const string CPAR_ITEM_CONF_SEG_END_2 = "CPAR_CONF_SEG_END_2"; - const string CPAR_ITEM_STARTIME_1 = "CPAR_START_TIME_1"; - const string CPAR_ITEM_STARTIME_2 = "CPAR_START_TIME_2"; - const string CPAR_ITEM_ENDTIME_1 = "CPAR_END_TIME_1"; - const string CPAR_ITEM_ENDTIME_2 = "CPAR_END_TIME_2"; - const string CPAR_ITEM_AID_2 = "CPAR_AID_2"; - const string CPAR_ITEM_TYP_2 = "CPAR_TYP_2"; - const string CPAR_ITEM_SPD_2 = "CPAR_SPD_2"; - const string CPAR_ITEM_ALT_2 = "CPAR_ALT_2"; - readonly static CustomColour NonRVSM = new CustomColour(242, 133, 0); - readonly static CustomColour SepFlags = new CustomColour(0, 196, 253); - readonly static CustomColour Pending = new CustomColour(46, 139, 87); - readonly static CustomColour NotCDA = new CustomColour(100, 0, 100); - readonly ConcurrentDictionary eastboundCallsigns = new ConcurrentDictionary(); - readonly ConcurrentDictionary flagtoggle = new ConcurrentDictionary(); + private const string LABEL_ITEM_ADSB_CPDLC = "AURORA_ADSB_CPDLC"; //field c(4) + + private const string STRIP_ITEM_CALLSIGN = "AURORA_CALLSIGN"; + private const string STRIP_ITEM_CTLSECTOR = "AURORA_CDA"; + private const string STRIP_ITEM_NXTSECTOR = "AURORA_NDA"; + private const string STRIP_ITEM_T10_FLAG = "AURORA_T10_FLAG"; + private const string STRIP_ITEM_MNT_FLAG = "AURORA_MNT_FLAG"; + private const string STRIP_ITEM_DIST_FLAG = "AURORA_DIST_FLAG"; + private const string STRIP_ITEM_RVSM_FLAG = "AURORA_RVSM_FLAG"; + private const string STRIP_ITEM_VMI = "AURORA_STRIP_VMI"; + private const string STRIP_ITEM_COMPLEX = "AURORA_STRIP_COMPLEX"; + private const string STRIP_ITEM_CLEARED_LEVEL = "AURORA_CLEARED_LEVEL"; + private const string STRIP_ITEM_REQUESTED_LEVEL = "AURORA_REQUESTED_LEVEL"; + private const string STRIP_ITEM_MAN_EST = "AURORA_MAN_EST"; + private const string STRIP_ITEM_POINT = "AURORA_POINT"; + private const string STRIP_ITEM_ROUTE = "AURORA_ROUTE_STRIP"; + private const string STRIP_ITEM_RADAR_IND = "AURORA_RADAR_IND"; + private const string STRIP_ITEM_ANNOT_IND = "AURORA_ANNOT_STRIP"; + private const string STRIP_ITEM_LATERAL_FLAG = "AURORA_LATERAL_FLAG"; + private const string STRIP_ITEM_RESTR = "AURORA_RESTR_STRIP"; + private const string STRIP_ITEM_CLRD_RTE = "AURORA_CLRD_RTE"; + private const string CPAR_ITEM_TYPE = "CPAR_TYP"; + private const string CPAR_ITEM_REQUIRED = "CPAR_REQUIRED"; + private const string CPAR_ITEM_INTRUDER = "CPAR_INT"; + private const string CPAR_ITEM_LOS = "CPAR_LOS"; + private const string CPAR_ITEM_ACTUAL = "CPAR_ACTUAL"; + private const string CPAR_ITEM_PASSING = "CPAR_PASSING"; + private const string CPAR_ITEM_CONF_SEG_START_1 = "CPAR_CONF_SEG_START_1"; + private const string CPAR_ITEM_CONF_SEG_START_2 = "CPAR_CONF_SEG_START_2"; + private const string CPAR_ITEM_CONF_SEG_END_1 = "CPAR_CONF_SEG_END_1"; + private const string CPAR_ITEM_CONF_SEG_END_2 = "CPAR_CONF_SEG_END_2"; + private const string CPAR_ITEM_STARTIME_1 = "CPAR_START_TIME_1"; + private const string CPAR_ITEM_STARTIME_2 = "CPAR_START_TIME_2"; + private const string CPAR_ITEM_ENDTIME_1 = "CPAR_END_TIME_1"; + private const string CPAR_ITEM_ENDTIME_2 = "CPAR_END_TIME_2"; + private const string CPAR_ITEM_AID_2 = "CPAR_AID_2"; + private const string CPAR_ITEM_TYP_2 = "CPAR_TYP_2"; + private const string CPAR_ITEM_SPD_2 = "CPAR_SPD_2"; + private const string CPAR_ITEM_ALT_2 = "CPAR_ALT_2"; + private static readonly CustomColour NonRVSM = new CustomColour(242, 133, 0); + private static readonly CustomColour SepFlags = new CustomColour(0, 196, 253); + private static readonly CustomColour Pending = new CustomColour(46, 139, 87); + private static readonly CustomColour NotCDA = new CustomColour(100, 0, 100); + + private readonly ConcurrentDictionary eastboundCallsigns = + new ConcurrentDictionary(); + + private readonly ConcurrentDictionary flagtoggle = new ConcurrentDictionary(); + private CPAR cpar = new CPAR(); + + private AuroraLabelItemsPlugin.AuroraLabelItemsPlugin label = + new AuroraLabelItemsPlugin.AuroraLabelItemsPlugin(); /// Plugin Name - public string Name { get => "Aurora Label Items"; } + public string Name => "Aurora Label Items"; - public void OnFDRUpdate(FDP2.FDR updated) + public void OnFDRUpdate(FDR updated) { - if (FDP2.GetFDRIndex(updated.Callsign) == -1) //FDR was removed (that's what triggered the update) + if (GetFDRIndex(updated.Callsign) == -1) //FDR was removed (that's what triggered the update) { eastboundCallsigns.TryRemove(updated.Callsign, out _); flagtoggle.TryRemove(updated.Callsign, out _); @@ -77,13 +80,13 @@ public void OnFDRUpdate(FDP2.FDR updated) else { - if (updated.ParsedRoute.Count > 1) { //calculate track from first route point to last (Departure point to destination point) var rte = updated.ParsedRoute; - double trk = Conversions.CalculateTrack(rte.First().Intersection.LatLong, rte.Last().Intersection.LatLong); - bool east = trk >= 0 && trk < 180; + var trk = Conversions.CalculateTrack(rte.First().Intersection.LatLong, + rte.Last().Intersection.LatLong); + var east = trk >= 0 && trk < 180; eastboundCallsigns.AddOrUpdate(updated.Callsign, east, (c, e) => east); } } @@ -92,45 +95,26 @@ public void OnFDRUpdate(FDP2.FDR updated) /// This is called each time a radar track is updated public void OnRadarTrackUpdate(RDP.RadarTrack updated) { - } - //public void Estimates(FDP2.FDR.ExtractedRoute.Segment estimate) - //{ - // estimate.IsPETO = true; - //} + public CustomStripItem GetCustomStripItem(string itemType, Track track, FDR flightDataRecord, + RDP.RadarTrack radarTrack) - private void ItemMouseClick(CustomStripItemMouseClickEventArgs e) { - bool flagToggled = flagtoggle.TryGetValue(e.Track.GetFDR().Callsign, out _); - - if (flagToggled) - { - flagtoggle.TryRemove(e.Track.GetFDR().Callsign, out _); - } - else - { - flagtoggle.TryAdd(e.Track.GetFDR().Callsign, 0); - } - e.Handled = true; - } - public CustomStripItem GetCustomStripItem(string itemType, Track track, FDP2.FDR flightDataRecord, RDP.RadarTrack radarTrack) - - { var pbn = Regex.Match(flightDataRecord.Remarks, @"PBN\/\w+\s"); - bool rnp10 = pbn.Value.Contains("A1"); - bool rnp4 = pbn.Value.Contains("L1"); - bool cpdlc = flightDataRecord.AircraftEquip.Contains("J5") || flightDataRecord.AircraftEquip.Contains("J7"); - bool adsc = flightDataRecord.AircraftSurvEquip.Contains("D1"); - bool adsb = flightDataRecord.ADSB; - bool rvsm = flightDataRecord.RVSM; - int level = radarTrack == null ? flightDataRecord.PRL / 100 : radarTrack.CorrectedAltitude / 100; - bool isEastBound = true; + var rnp10 = pbn.Value.Contains("A1"); + var rnp4 = pbn.Value.Contains("L1"); + var cpdlc = flightDataRecord.AircraftEquip.Contains("J5") || flightDataRecord.AircraftEquip.Contains("J7"); + var adsc = flightDataRecord.AircraftSurvEquip.Contains("D1"); + var adsb = flightDataRecord.ADSB; + var rvsm = flightDataRecord.RVSM; + var level = radarTrack == null ? flightDataRecord.PRL / 100 : radarTrack.CorrectedAltitude / 100; + var isEastBound = true; eastboundCallsigns.TryGetValue(flightDataRecord.Callsign, out isEastBound); - int prl = flightDataRecord.PRL / 100; - int cfl = flightDataRecord.CFLUpper / 100; - int rfl = flightDataRecord.RFL / 100; - int alt = flightDataRecord.CFLUpper == -1 ? rfl : cfl; + var prl = flightDataRecord.PRL / 100; + var cfl = flightDataRecord.CFLUpper / 100; + var rfl = flightDataRecord.RFL / 100; + var alt = flightDataRecord.CFLUpper == -1 ? rfl : cfl; if (flightDataRecord == null) return null; @@ -139,59 +123,54 @@ public CustomStripItem GetCustomStripItem(string itemType, Track track, FDP2.FDR { case STRIP_ITEM_CALLSIGN: - + if (isEastBound) - { - return new CustomStripItem() + return new CustomStripItem { BackColourIdentity = Colours.Identities.StripText, ForeColourIdentity = Colours.Identities.StripBackground, Text = flightDataRecord.Callsign }; - } - else + return new CustomStripItem { - return new CustomStripItem() - { - BackColourIdentity = Colours.Identities.StripBackground, - ForeColourIdentity = Colours.Identities.StripText, - Text = flightDataRecord.Callsign - }; - } + BackColourIdentity = Colours.Identities.StripBackground, + ForeColourIdentity = Colours.Identities.StripText, + Text = flightDataRecord.Callsign + }; - case STRIP_ITEM_CTLSECTOR: - - bool pendingCoordination = flightDataRecord.State == (FDR.FDRStates.STATE_PREACTIVE | FDR.FDRStates.STATE_COORDINATED); - string sectorName = flightDataRecord.ControllingSector == null ? "" : flightDataRecord.ControllingSector.Name; + case STRIP_ITEM_CTLSECTOR: + var pendingCoordination = flightDataRecord.State == + (FDR.FDRStates.STATE_PREACTIVE | FDR.FDRStates.STATE_COORDINATED); + var sectorName = flightDataRecord.ControllingSector == null + ? "" + : flightDataRecord.ControllingSector.Name; + + { + return new CustomStripItem { - return new CustomStripItem() - { - ForeColourIdentity = pendingCoordination ? Colours.Identities.Custom : default, - CustomForeColour = Pending, - Text = sectorName - }; - } + ForeColourIdentity = pendingCoordination ? Colours.Identities.Custom : default, + CustomForeColour = Pending, + Text = sectorName + }; + } + case STRIP_ITEM_NXTSECTOR: - - case STRIP_ITEM_NXTSECTOR: - TOC toc; toc = new TOC(flightDataRecord); - string firName = toc.nextSector == null ? "" : toc.nextSector.Name; + var firName = toc.nextSector == null ? "" : toc.nextSector.Name; + { + return new CustomStripItem { - return new CustomStripItem() - { - ForeColourIdentity = Colours.Identities.Custom, - CustomForeColour = Pending, - Text = firName - }; - } - + ForeColourIdentity = Colours.Identities.Custom, + CustomForeColour = Pending, + Text = firName + }; + } case LABEL_ITEM_ADSB_CPDLC: @@ -199,7 +178,7 @@ public CustomStripItem GetCustomStripItem(string itemType, Track track, FDP2.FDR if (!isEastBound && !adsb && cpdlc) - return new CustomStripItem() + return new CustomStripItem { BackColourIdentity = Colours.Identities.StripBackground, ForeColourIdentity = Colours.Identities.StripText, @@ -208,7 +187,7 @@ public CustomStripItem GetCustomStripItem(string itemType, Track track, FDP2.FDR if (isEastBound && !adsb && cpdlc) - return new CustomStripItem() + return new CustomStripItem { BackColourIdentity = Colours.Identities.StripText, ForeColourIdentity = Colours.Identities.StripBackground, @@ -217,7 +196,7 @@ public CustomStripItem GetCustomStripItem(string itemType, Track track, FDP2.FDR if (!isEastBound && !adsb) - return new CustomStripItem() + return new CustomStripItem { BackColourIdentity = Colours.Identities.StripBackground, ForeColourIdentity = Colours.Identities.StripText, @@ -226,7 +205,7 @@ public CustomStripItem GetCustomStripItem(string itemType, Track track, FDP2.FDR if (isEastBound && !adsb) - return new CustomStripItem() + return new CustomStripItem { BackColourIdentity = Colours.Identities.StripText, ForeColourIdentity = Colours.Identities.StripBackground, @@ -235,7 +214,7 @@ public CustomStripItem GetCustomStripItem(string itemType, Track track, FDP2.FDR if (!isEastBound && cpdlc) - return new CustomStripItem() + return new CustomStripItem { BackColourIdentity = Colours.Identities.StripBackground, ForeColourIdentity = Colours.Identities.StripText, @@ -244,7 +223,7 @@ public CustomStripItem GetCustomStripItem(string itemType, Track track, FDP2.FDR if (isEastBound && cpdlc) - return new CustomStripItem() + return new CustomStripItem { BackColourIdentity = Colours.Identities.StripText, ForeColourIdentity = Colours.Identities.StripBackground, @@ -257,7 +236,7 @@ public CustomStripItem GetCustomStripItem(string itemType, Track track, FDP2.FDR if (flightDataRecord.PerformanceData?.IsJet ?? false) - return new CustomStripItem() + return new CustomStripItem { //BackColourIdentity = Colours.Identities.Custom, //CustomBackColour = SepFlags, @@ -271,7 +250,7 @@ public CustomStripItem GetCustomStripItem(string itemType, Track track, FDP2.FDR if (flightDataRecord.PerformanceData?.IsJet ?? false) - return new CustomStripItem() + return new CustomStripItem { //BackColourIdentity = Colours.Identities.Custom, //CustomBackColour = SepFlags, @@ -285,7 +264,7 @@ public CustomStripItem GetCustomStripItem(string itemType, Track track, FDP2.FDR if (adsc & cpdlc & (rnp4 || rnp10)) - return new CustomStripItem() + return new CustomStripItem { BackColourIdentity = Colours.Identities.Custom, CustomBackColour = SepFlags, @@ -297,7 +276,7 @@ public CustomStripItem GetCustomStripItem(string itemType, Track track, FDP2.FDR if (rvsm) - return new CustomStripItem() + return new CustomStripItem { BackColourIdentity = Colours.Identities.Custom, CustomBackColour = SepFlags, @@ -307,26 +286,28 @@ public CustomStripItem GetCustomStripItem(string itemType, Track track, FDP2.FDR return null; case STRIP_ITEM_VMI: - var vs = radarTrack == null ? flightDataRecord.PredictedPosition.VerticalSpeed : radarTrack.VerticalSpeed; + var vs = radarTrack == null + ? flightDataRecord.PredictedPosition.VerticalSpeed + : radarTrack.VerticalSpeed; - if (level == cfl || level == flightDataRecord.RFL)//level + if (level == cfl || level == flightDataRecord.RFL) //level - return new CustomStripItem() + return new CustomStripItem { Text = "" }; - else if (cfl > level && track.NewCFL || vs > 300)//Issued or trending climb + if ((cfl > level && track.NewCFL) || vs > 300) //Issued or trending climb - return new CustomStripItem() + return new CustomStripItem { - Text = "↑", + Text = "↑" }; - else if (cfl > 0 && cfl < level && track.NewCFL || vs < -300)//Issued or trending descent + if ((cfl > 0 && cfl < level && track.NewCFL) || vs < -300) //Issued or trending descent - return new CustomStripItem() + return new CustomStripItem { - Text = "↓", + Text = "↓" }; return null; @@ -336,7 +317,7 @@ public CustomStripItem GetCustomStripItem(string itemType, Track track, FDP2.FDR if (flightDataRecord.LabelOpData.Contains("AT ") || flightDataRecord.LabelOpData.Contains(" BY ") || flightDataRecord.LabelOpData.Contains("CLEARED TO ")) - return new CustomStripItem() + return new CustomStripItem { Text = "*" }; @@ -346,38 +327,29 @@ public CustomStripItem GetCustomStripItem(string itemType, Track track, FDP2.FDR case STRIP_ITEM_CLEARED_LEVEL: if (cfl == 0) - { - return new CustomStripItem() + return new CustomStripItem { Text = "" }; - } - else + return new CustomStripItem { - return new CustomStripItem() - { - Text = cfl.ToString() - }; - } + Text = cfl.ToString() + }; case STRIP_ITEM_REQUESTED_LEVEL: - if (flightDataRecord.State == FDR.FDRStates.STATE_INACTIVE || flightDataRecord.State == FDR.FDRStates.STATE_INACTIVE) - { - return new CustomStripItem() + if (flightDataRecord.State == FDR.FDRStates.STATE_INACTIVE || + flightDataRecord.State == FDR.FDRStates.STATE_INACTIVE) + return new CustomStripItem { - Text = rfl.ToString(), + Text = rfl.ToString() }; - } - else + return new CustomStripItem { - return new CustomStripItem() - { - Text = "" - }; - } + Text = "" + }; //case STRIP_ITEM_MAN_EST: @@ -398,41 +370,36 @@ public CustomStripItem GetCustomStripItem(string itemType, Track track, FDP2.FDR // }; case STRIP_ITEM_ROUTE: - return new CustomStripItem() - { - Text = "F", - //OnMouseClick = ItemMouseClick - }; + return new CustomStripItem + { + Text = "F" + //OnMouseClick = ItemMouseClick + }; case STRIP_ITEM_RADAR_IND: - return new CustomStripItem() - { - Text = "A", - //OnMouseClick = - }; + return new CustomStripItem + { + Text = "A" + //OnMouseClick = + }; case STRIP_ITEM_ANNOT_IND: - bool scratch = String.IsNullOrEmpty(flightDataRecord.LabelOpData); + var scratch = string.IsNullOrEmpty(flightDataRecord.LabelOpData); if (scratch) - { - return new CustomStripItem() + return new CustomStripItem { Text = "." }; - } - else + return new CustomStripItem { - return new CustomStripItem() - { - Text = "&" - }; - } + Text = "&" + }; case STRIP_ITEM_LATERAL_FLAG: @@ -440,11 +407,11 @@ public CustomStripItem GetCustomStripItem(string itemType, Track track, FDP2.FDR if (adsc & cpdlc & rnp4 || rnp10) - return new CustomStripItem() + return new CustomStripItem { BackColourIdentity = Colours.Identities.Custom, CustomBackColour = SepFlags, - Text = rnp4 ? "4" : rnp10 ? "R" : "", + Text = rnp4 ? "4" : rnp10 ? "R" : "" //OnMouseClick = ItemMouseClick }; return null; @@ -454,159 +421,175 @@ public CustomStripItem GetCustomStripItem(string itemType, Track track, FDP2.FDR if (flightDataRecord.LabelOpData.Contains("AT ") || flightDataRecord.LabelOpData.Contains(" BY ") || flightDataRecord.LabelOpData.Contains("CLEARED TO ")) - return new CustomStripItem() + return new CustomStripItem { Text = "x" }; return null; - case STRIP_ITEM_CLRD_RTE: - - return new CustomStripItem() - { - Text = "Cleared Route:" + flightDataRecord.RouteNoParse - }; - - if (label.imminentConflict.TryGetValue(flightDataRecord.Callsign, out _) || (label.advisoryConflict.TryGetValue(flightDataRecord.Callsign, out)) == flightDataRecord.Callsign; - - case CPAR_ITEM_TYPE: - - return new CustomStripItem() - { - Text = - }; - - case CPAR_ITEM_REQUIRED: - - return new CustomStripItem() - { - Text = cpar.Segments1[0].callsign - }; - - case CPAR_ITEM_INTRUDER: - - return new CustomStripItem() - { - Text = cpar.Segments1[0].callsign - }; - - case CPAR_ITEM_LOS: - - return new CustomStripItem() - { - Text = cpar.Segments1[0].callsign - }; - - case CPAR_ITEM_ACTUAL: - - return new CustomStripItem() - { - Text = cpar.Segments1[0].callsign - }; - - case CPAR_ITEM_PASSING: - - return new CustomStripItem() - { - Text = cpar.Segments1[0].callsign - }; - - case CPAR_ITEM_CONF_SEG_START_1: - - return new CustomStripItem() - { - Text = cpar.Segments1[0].startLatlong.ToString() - }; - - case CPAR_ITEM_CONF_SEG_START_2: - - return new CustomStripItem() - { - Text = cpar.Segments2[0].startLatlong.ToString() - }; - - case CPAR_ITEM_CONF_SEG_END_1: - - return new CustomStripItem() - { - Text = cpar.Segments1[0].endLatlong.ToString() - }; - - case CPAR_ITEM_CONF_SEG_END_2: - - return new CustomStripItem() - { - Text = cpar.Segments2[0].endLatlong.ToString() - }; - - case CPAR_ITEM_STARTIME_1: - - return new CustomStripItem() - { - Text = cpar.Segments1[0].startTime.ToString() - }; - - case CPAR_ITEM_STARTIME_2: - - return new CustomStripItem() - { - Text = cpar.Segments2[0].startTime.ToString() - }; - - case CPAR_ITEM_ENDTIME_1: - - return new CustomStripItem() - { - Text = cpar.Segments1[0].endTime.ToString() - }; - - case CPAR_ITEM_ENDTIME_2: - - return new CustomStripItem() - { - Text = cpar.Segments2[0].endTime.ToString() - }; - - case CPAR_ITEM_AID_2: - - return new CustomStripItem() - { - Text = cpar.Segments2[0].callsign - }; - - case CPAR_ITEM_TYP_2: - - return new CustomStripItem() - { - Text = - }; - - case CPAR_ITEM_SPD_2: + // case STRIP_ITEM_CLRD_RTE: + // + // return new CustomStripItem() + // { + // Text = "Cleared Route:" + flightDataRecord.RouteNoParse + // }; + // + // if (label.imminentConflict.TryGetValue(flightDataRecord.Callsign, out _) || (label.advisoryConflict.TryGetValue(flightDataRecord.Callsign, out)) == flightDataRecord.Callsign; + // + // case CPAR_ITEM_TYPE: + // + // return new CustomStripItem() + // { + // Text = + // }; + // + // case CPAR_ITEM_REQUIRED: + // + // return new CustomStripItem() + // { + // Text = cpar.Segments1[0].callsign + // }; + // + // case CPAR_ITEM_INTRUDER: + // + // return new CustomStripItem() + // { + // Text = cpar.Segments1[0].callsign + // }; + // + // case CPAR_ITEM_LOS: + // + // return new CustomStripItem() + // { + // Text = cpar.Segments1[0].callsign + // }; + // + // case CPAR_ITEM_ACTUAL: + // + // return new CustomStripItem() + // { + // Text = cpar.Segments1[0].callsign + // }; + // + // case CPAR_ITEM_PASSING: + // + // return new CustomStripItem() + // { + // Text = cpar.Segments1[0].callsign + // }; + // + // case CPAR_ITEM_CONF_SEG_START_1: + // + // return new CustomStripItem() + // { + // Text = cpar.Segments1[0].startLatlong.ToString() + // }; + // + // case CPAR_ITEM_CONF_SEG_START_2: + // + // return new CustomStripItem() + // { + // Text = cpar.Segments2[0].startLatlong.ToString() + // }; + // + // case CPAR_ITEM_CONF_SEG_END_1: + // + // return new CustomStripItem() + // { + // Text = cpar.Segments1[0].endLatlong.ToString() + // }; + // + // case CPAR_ITEM_CONF_SEG_END_2: + // + // return new CustomStripItem() + // { + // Text = cpar.Segments2[0].endLatlong.ToString() + // }; + // + // case CPAR_ITEM_STARTIME_1: + // + // return new CustomStripItem() + // { + // Text = cpar.Segments1[0].startTime.ToString() + // }; + // + // case CPAR_ITEM_STARTIME_2: + // + // return new CustomStripItem() + // { + // Text = cpar.Segments2[0].startTime.ToString() + // }; + // + // case CPAR_ITEM_ENDTIME_1: + // + // return new CustomStripItem() + // { + // Text = cpar.Segments1[0].endTime.ToString() + // }; + // + // case CPAR_ITEM_ENDTIME_2: + // + // return new CustomStripItem() + // { + // Text = cpar.Segments2[0].endTime.ToString() + // }; + // + // case CPAR_ITEM_AID_2: + // + // return new CustomStripItem() + // { + // Text = cpar.Segments2[0].callsign + // }; + // + // case CPAR_ITEM_TYP_2: + // + // return new CustomStripItem() + // { + // Text = + // }; + // + // case CPAR_ITEM_SPD_2: + // + // return new CustomStripItem() + // { + // Text = + // }; + // + // case CPAR_ITEM_ALT_2: + // + // return new CustomStripItem() + // { + // Text = + // }; - return new CustomStripItem() - { - Text = - }; + default: return null; + } + } - case CPAR_ITEM_ALT_2: + //public void Estimates(FDP2.FDR.ExtractedRoute.Segment estimate) + //{ + // estimate.IsPETO = true; + //} - return new CustomStripItem() - { - Text = - }; + private void ItemMouseClick(CustomStripItemMouseClickEventArgs e) + { + var flagToggled = flagtoggle.TryGetValue(e.Track.GetFDR().Callsign, out _); - default: return null; - } + if (flagToggled) + flagtoggle.TryRemove(e.Track.GetFDR().Callsign, out _); + else + flagtoggle.TryAdd(e.Track.GetFDR().Callsign, 0); + e.Handled = true; } - //private CustomColour PETOColor(FDP2.FDR.ExtractedRoute.Segment estimate, Colours.Identities state) - //{ - // if (estimate.IsPETO) - // { - // return state = state; - // } - // - // return null; - //} + //private CustomColour PETOColor(FDP2.FDR.ExtractedRoute.Segment estimate, Colours.Identities state) + //{ + // if (estimate.IsPETO) + // { + // return state = state; + // } + // + // return null; + //} } -} +} \ No newline at end of file diff --git a/CPAR.cs b/CPAR.cs index 2f007c5..e574e82 100644 --- a/CPAR.cs +++ b/CPAR.cs @@ -5,66 +5,76 @@ // Assembly location: E:\vatsys\bin\vatSys.exe // XML documentation location: E:\vatsys\bin\vatSys.xml -using AuroraLabelItemsPlugin; using System; -using System.Collections.Concurrent; using System.Collections.Generic; using System.Linq; -using System.Runtime.CompilerServices; -using System.Text.RegularExpressions; +using AuroraLabelItemsPlugin; namespace vatsys { public class CPAR { - public List Segments1 = new List(); - public List Segments2 = new List(); - AuroraLabelItemsPlugin.GEO label = new AuroraLabelItemsPlugin.GEO(); + private readonly GEO label = new GEO(); + public List Segments1 = new List(); + public List Segments2 = new List(); public DateTime Timeout = DateTime.MaxValue; - public CPAR(FDP2.FDR fdr1, FDP2.FDR fdr2, int value) => this.CalculateLATC(fdr1, fdr2, value); + public CPAR(FDP2.FDR fdr1, FDP2.FDR fdr2, int value) + { + CalculateLATC(fdr1, fdr2, value); + } + public CPAR() { } - public void CalculateLATC(FDP2.FDR fdr1, FDP2.FDR fdr2, int value) + private void CalculateLATC(FDP2.FDR fdr1, FDP2.FDR fdr2, int value) { if (fdr1 == null || fdr2 == null) return; - this.Segments1.AddRange((IEnumerable)this.CalculateAreaOfConflict(fdr1, fdr2, value)); - this.Segments2.AddRange((IEnumerable)this.CalculateAreaOfConflict(fdr2, fdr1, value)); + Segments1.AddRange(CalculateAreaOfConflict(fdr1, fdr2, value)); + Segments2.AddRange(CalculateAreaOfConflict(fdr2, fdr1, value)); } - public List CalculateAreaOfConflict(FDP2.FDR fdr1, FDP2.FDR fdr2, int value) + private static List CalculateAreaOfConflict(FDP2.FDR fdr1, FDP2.FDR fdr2, int value) { - List segs = new List(); - List route1waypoints = fdr1.ParsedRoute.ToList().Where(s => s.Type == FDP2.FDR.ExtractedRoute.Segment.SegmentTypes.WAYPOINT).ToList(); - List route2waypoints = fdr2.ParsedRoute.ToList().Where(s => s.Type == FDP2.FDR.ExtractedRoute.Segment.SegmentTypes.WAYPOINT).ToList(); - for (int wp1index = 1; wp1index < route1waypoints.Count; ++wp1index) + var segs = new List(); + var route1waypoints = fdr1.ParsedRoute.ToList() + .Where(s => s.Type == FDP2.FDR.ExtractedRoute.Segment.SegmentTypes.WAYPOINT).ToList(); + var route2waypoints = fdr2.ParsedRoute.ToList() + .Where(s => s.Type == FDP2.FDR.ExtractedRoute.Segment.SegmentTypes.WAYPOINT).ToList(); + for (var wp1index = 1; wp1index < route1waypoints.Count; ++wp1index) { - List route1Segment = CreatePolygon(route1waypoints[wp1index - 1].Intersection.LatLong, route1waypoints[wp1index].Intersection.LatLong, value); - for (int wp2index = 1; wp2index < route2waypoints.Count; wp2index++) + var route1Segment = CreatePolygon(route1waypoints[wp1index - 1].Intersection.LatLong, + route1waypoints[wp1index].Intersection.LatLong, value); + for (var wp2index = 1; wp2index < route2waypoints.Count; wp2index++) { - List source = new List(); - List intersectionPoints = new List(); - source.AddRange((IEnumerable)CalculatePolygonIntersections(route1Segment, route2waypoints[wp2index - 1].Intersection.LatLong, route2waypoints[wp2index].Intersection.LatLong)); - int num1 = 0; - int num2 = 0; - foreach (Coordinate coordinate in source.ToList()) - { - if (Conversions.IsLatLonOnGC(route2waypoints[wp2index - 1].Intersection.LatLong, route2waypoints[wp2index].Intersection.LatLong, coordinate)) + var source = new List(); + var intersectionPoints = new List(); + source.AddRange(CalculatePolygonIntersections(route1Segment, + route2waypoints[wp2index - 1].Intersection.LatLong, + route2waypoints[wp2index].Intersection.LatLong)); + var num1 = 0; + var num2 = 0; + foreach (var coordinate in source.ToList()) + if (Conversions.IsLatLonOnGC(route2waypoints[wp2index - 1].Intersection.LatLong, + route2waypoints[wp2index].Intersection.LatLong, coordinate)) { intersectionPoints.Add(coordinate); } else { - double track = Conversions.CalculateTrack(route2waypoints[wp2index - 1].Intersection.LatLong, route2waypoints[wp2index].Intersection.LatLong); - if (Math.Abs(track - Conversions.CalculateTrack(route2waypoints[wp2index - 1].Intersection.LatLong, coordinate)) > 90.0) + var track = Conversions.CalculateTrack(route2waypoints[wp2index - 1].Intersection.LatLong, + route2waypoints[wp2index].Intersection.LatLong); + if (Math.Abs(track - + Conversions.CalculateTrack(route2waypoints[wp2index - 1].Intersection.LatLong, + coordinate)) > 90.0) ++num1; - if (Math.Abs(track - Conversions.CalculateTrack(coordinate, route2waypoints[wp2index].Intersection.LatLong)) > 90.0) + if (Math.Abs(track - Conversions.CalculateTrack(coordinate, + route2waypoints[wp2index].Intersection.LatLong)) > 90.0) ++num2; } - } + if (num1 % 2 != 0 && num2 % 2 != 0) { intersectionPoints.Clear(); @@ -72,23 +82,63 @@ public List CalculateAreaOfConflict(FDP2.FDR fdr1, FDP2.FDR fdr2, int v intersectionPoints.Add(route2waypoints[wp2index].Intersection.LatLong); } else if (num2 % 2 != 0) + { intersectionPoints.Add(route2waypoints[wp2index].Intersection.LatLong); + } else if (num1 % 2 != 0) + { intersectionPoints.Add(route2waypoints[wp2index - 1].Intersection.LatLong); - intersectionPoints.Sort((x, y) => Conversions.CalculateDistance(route2waypoints[wp2index - 1].Intersection.LatLong, x).CompareTo(Conversions.CalculateDistance(route2waypoints[wp2index - 1].Intersection.LatLong, y))); - for (int ipIndex = 1; ipIndex < intersectionPoints.Count; ipIndex += 2) + } + + intersectionPoints.Sort((x, y) => + Conversions.CalculateDistance(route2waypoints[wp2index - 1].Intersection.LatLong, x) + .CompareTo(Conversions.CalculateDistance(route2waypoints[wp2index - 1].Intersection.LatLong, + y))); + for (var ipIndex = 1; ipIndex < intersectionPoints.Count; ipIndex += 2) { - Segment seg = new Segment(); + var seg = new Segment(); seg.startLatlong = intersectionPoints[ipIndex - 1]; seg.endLatlong = intersectionPoints[ipIndex]; - List conflictSegments = segs.Where((Func)(s => s.routeSegment == route2waypoints[wp2index])).Where((Func)(s => Conversions.CalculateDistance(s.startLatlong, route2waypoints[wp2index - 1].Intersection.LatLong) < Conversions.CalculateDistance(seg.startLatlong, route2waypoints[wp2index - 1].Intersection.LatLong) && Conversions.CalculateDistance(s.endLatlong, route2waypoints[wp2index - 1].Intersection.LatLong) > Conversions.CalculateDistance(seg.startLatlong, route2waypoints[wp2index - 1].Intersection.LatLong) || Conversions.CalculateDistance(s.endLatlong, route2waypoints[wp2index - 1].Intersection.LatLong) > Conversions.CalculateDistance(seg.endLatlong, route2waypoints[wp2index - 1].Intersection.LatLong) && Conversions.CalculateDistance(s.startLatlong, route2waypoints[wp2index - 1].Intersection.LatLong) < Conversions.CalculateDistance(seg.endLatlong, route2waypoints[wp2index - 1].Intersection.LatLong) || Conversions.CalculateDistance(s.startLatlong, route2waypoints[wp2index - 1].Intersection.LatLong) > Conversions.CalculateDistance(seg.startLatlong, route2waypoints[wp2index - 1].Intersection.LatLong) && Conversions.CalculateDistance(s.endLatlong, route2waypoints[wp2index - 1].Intersection.LatLong) < Conversions.CalculateDistance(seg.endLatlong, route2waypoints[wp2index - 1].Intersection.LatLong) || Conversions.CalculateDistance(s.startLatlong, seg.startLatlong) < 0.01 || Conversions.CalculateDistance(s.endLatlong, seg.endLatlong) < 0.01)).ToList(); + var conflictSegments = segs.Where(s => s.routeSegment == route2waypoints[wp2index]).Where(s => + (Conversions.CalculateDistance(s.startLatlong, + route2waypoints[wp2index - 1].Intersection.LatLong) < + Conversions.CalculateDistance(seg.startLatlong, + route2waypoints[wp2index - 1].Intersection.LatLong) && + Conversions.CalculateDistance(s.endLatlong, + route2waypoints[wp2index - 1].Intersection.LatLong) > + Conversions.CalculateDistance(seg.startLatlong, + route2waypoints[wp2index - 1].Intersection.LatLong)) || + (Conversions.CalculateDistance(s.endLatlong, + route2waypoints[wp2index - 1].Intersection.LatLong) > + Conversions.CalculateDistance(seg.endLatlong, + route2waypoints[wp2index - 1].Intersection.LatLong) && + Conversions.CalculateDistance(s.startLatlong, + route2waypoints[wp2index - 1].Intersection.LatLong) < + Conversions.CalculateDistance(seg.endLatlong, + route2waypoints[wp2index - 1].Intersection.LatLong)) || + (Conversions.CalculateDistance(s.startLatlong, + route2waypoints[wp2index - 1].Intersection.LatLong) > + Conversions.CalculateDistance(seg.startLatlong, + route2waypoints[wp2index - 1].Intersection.LatLong) && + Conversions.CalculateDistance(s.endLatlong, + route2waypoints[wp2index - 1].Intersection.LatLong) < + Conversions.CalculateDistance(seg.endLatlong, + route2waypoints[wp2index - 1].Intersection.LatLong)) || + Conversions.CalculateDistance(s.startLatlong, seg.startLatlong) < 0.01 || + Conversions.CalculateDistance(s.endLatlong, seg.endLatlong) < 0.01).ToList(); if (conflictSegments.Count > 0) { - foreach (Segment segment in conflictSegments) + foreach (var segment in conflictSegments) { - if (Conversions.CalculateDistance(segment.endLatlong, route2waypoints[wp2index - 1].Intersection.LatLong) < Conversions.CalculateDistance(seg.endLatlong, route2waypoints[wp2index - 1].Intersection.LatLong)) + if (Conversions.CalculateDistance(segment.endLatlong, + route2waypoints[wp2index - 1].Intersection.LatLong) < + Conversions.CalculateDistance(seg.endLatlong, + route2waypoints[wp2index - 1].Intersection.LatLong)) segment.endLatlong = seg.endLatlong; - if (Conversions.CalculateDistance(seg.startLatlong, route2waypoints[wp2index - 1].Intersection.LatLong) < Conversions.CalculateDistance(segment.startLatlong, route2waypoints[wp2index - 1].Intersection.LatLong)) + if (Conversions.CalculateDistance(seg.startLatlong, + route2waypoints[wp2index - 1].Intersection.LatLong) < + Conversions.CalculateDistance(segment.startLatlong, + route2waypoints[wp2index - 1].Intersection.LatLong)) segment.startLatlong = seg.startLatlong; } } @@ -101,309 +151,332 @@ public List CalculateAreaOfConflict(FDP2.FDR fdr1, FDP2.FDR fdr2, int v } } } - for (int i = 0; i < segs.Count; i++) + + for (var i = 0; i < segs.Count; i++) { - if (!segs.Exists((Predicate)(s => Conversions.CalculateDistance(segs[i].startLatlong, s.endLatlong) < 0.01))) - segs[i].startTime = FDP2.GetSystemEstimateAtPosition(fdr2, segs[i].startLatlong, segs[i].routeSegment); - if (!segs.Exists((Predicate)(s => Conversions.CalculateDistance(segs[i].endLatlong, s.startLatlong) < 0.01))) + if (!segs.Exists(s => Conversions.CalculateDistance(segs[i].startLatlong, s.endLatlong) < 0.01)) + segs[i].startTime = + FDP2.GetSystemEstimateAtPosition(fdr2, segs[i].startLatlong, segs[i].routeSegment); + if (!segs.Exists(s => Conversions.CalculateDistance(segs[i].endLatlong, s.startLatlong) < 0.01)) segs[i].endTime = FDP2.GetSystemEstimateAtPosition(fdr2, segs[i].endLatlong, segs[i].routeSegment); } + return segs; } - public static List CreatePolygon(Coordinate point1, Coordinate point2, int value) + private static List CreatePolygon(Coordinate point1, Coordinate point2, int value) { - List polygon = new List(); - double track = Conversions.CalculateTrack(point1, point2); - double num1 = track - 90.0; - for (int index = 0; index <= 180; index += 10) + var polygon = new List(); + var track = Conversions.CalculateTrack(point1, point2); + var num1 = track - 90.0; + for (var index = 0; index <= 180; index += 10) { - double heading = num1 - (double)index; - Coordinate fromBearingRange = Conversions.CalculateLLFromBearingRange(point1, (double)value, heading); + var heading = num1 - index; + var fromBearingRange = Conversions.CalculateLLFromBearingRange(point1, value, heading); polygon.Add(fromBearingRange); } - double num2 = track + 90.0; - for (int index = 0; index <= 180; index += 10) + + var num2 = track + 90.0; + for (var index = 0; index <= 180; index += 10) { - double heading = num2 - (double)index; - Coordinate fromBearingRange = Conversions.CalculateLLFromBearingRange(point2, (double)value, heading); + var heading = num2 - index; + var fromBearingRange = Conversions.CalculateLLFromBearingRange(point2, value, heading); polygon.Add(fromBearingRange); } + polygon.Add(polygon[0]); return polygon; } - public static List CalculatePolygonIntersections( + private static List CalculatePolygonIntersections( List polygon, Coordinate point1, Coordinate point2) { - List polygonIntersections = new List(); - for (int index = 1; index < polygon.Count; ++index) + var polygonIntersections = new List(); + for (var index = 1; index < polygon.Count; ++index) { - List gcIntersectionLl = Conversions.CalculateAllGCIntersectionLL(polygon[index - 1], polygon[index], point1, point2); + var gcIntersectionLl = + Conversions.CalculateAllGCIntersectionLL(polygon[index - 1], polygon[index], point1, point2); if (gcIntersectionLl != null) polygonIntersections.AddRange(gcIntersectionLl); } - for (int index = 0; index < polygonIntersections.Count; ++index) + + for (var index = 0; index < polygonIntersections.Count; ++index) { - Coordinate intsect = polygonIntersections[index]; + var intsect = polygonIntersections[index]; polygonIntersections.RemoveAll(c => c != intsect && Conversions.CalculateDistance(intsect, c) < 0.01); } - return polygonIntersections; - } - - public class Segment - { - public string callsign; - public Coordinate startLatlong; - public Coordinate endLatlong; - public DateTime startTime = DateTime.MaxValue; - public DateTime endTime = DateTime.MaxValue; - public FDP2.FDR.ExtractedRoute.Segment routeSegment; + return polygonIntersections; } - public class ConflictData - { - public FDP2.FDR fdr; - public FDP2.FDR fdr2; - public double trkAngle; - public int verticalAct; - public int verticalSep; - public int latAct; - public int latSep; - public bool longType; - public TimeSpan longTimesep; - public TimeSpan longTimeact; - public bool mnt; - public double longDistsep; - public double longDistact; - public TimeOfPassing top; - public string conflictType; - public Segment startLatlong; - public Segment endLatlong; - public Segment startTime; - public Segment endTime; - public DateTime earliestLOS; - public bool timeLongsame; - public bool distLongsame; - public bool timeLongcross; - public bool timeLongopposite; - public bool actualConflicts; - public bool imminentConflicts; - public bool advisoryConflicts; - } public void ConflictProbe(FDP2.FDR fdr, int latSep) { - List conDict = new List(); - FPAP fpap = new FPAP(); + var conDict = new List(); + var fpap = new FPAP(); - if ((fdr == null) || !MMI.IsMySectorConcerned(fdr)) return; - int cfl = fdr.CFLUpper; - int rfl = fdr.RFL; - int alt = cfl == -1 ? rfl : cfl; + if (fdr == null || !MMI.IsMySectorConcerned(fdr)) return; + var cfl = fdr.CFLUpper; + var rfl = fdr.RFL; + var alt = cfl == -1 ? rfl : cfl; var isRvsm = fdr.RVSM; - for (int i = 0; i < conDict.Count; i++) - foreach (var fdr2 in FDP2.GetFDRs) - { - if (fdr2 == null || fdr.Callsign == fdr2.Callsign || !MMI.IsMySectorConcerned(fdr2)) continue; - var data = new ConflictData(); - var rte = fdr.ParsedRoute; - var rte2 = fdr2.ParsedRoute; - double trk = Conversions.CalculateTrack(rte.First().Intersection.LatLong, - rte.Last().Intersection.LatLong); - double trk2 = Conversions.CalculateTrack(rte2.First().Intersection.LatLong, - rte2.Last().Intersection.LatLong); - data.trkAngle = Math.Abs(trk2 - trk); - bool sameDir = data.trkAngle < 45; - bool crossing = (data.trkAngle >= 45 && data.trkAngle <= 135) || (data.trkAngle >= 315 && data.trkAngle <= 225); - bool oppoDir = data.trkAngle > 135 && data.trkAngle < 225; - int cfl2 = fdr2.CFLUpper; - int rfl2 = fdr2.RFL; - int alt2 = cfl2 == -1 ? rfl2 : cfl2; - var isRvsm2 = fdr2.RVSM; - data.verticalAct = Math.Abs(alt - alt2); - data.verticalSep = (alt > 45000 && alt < 60000) ? 4000 : alt > 60000 ? 5000 : (alt2 > 45000 && alt2 < 60000) ? 4000 : alt2 > 60000 ? 5000 : - (alt > FDP2.RVSM_BAND_LOWER && !isRvsm) || - (alt2 > FDP2.RVSM_BAND_LOWER && !isRvsm2) || (alt > FDP2.RVSM_BAND_UPPER || alt2 > FDP2.RVSM_BAND_UPPER) - ? 2000 - : 1000; - - if (data.verticalAct < data.verticalSep) + for (var i = 0; i < conDict.Count; i++) + foreach (var fdr2 in FDP2.GetFDRs) { - - //data.latSep = latSep1; - - if (fpap.rnp4 && fpap.pbcs && fpap.adsc && fpap.cpdlc) + if (fdr2 == null || fdr.Callsign == fdr2.Callsign || !MMI.IsMySectorConcerned(fdr2)) continue; + var data = new ConflictData(); + var rte = fdr.ParsedRoute; + var rte2 = fdr2.ParsedRoute; + var trk = Conversions.CalculateTrack(rte.First().Intersection.LatLong, + rte.Last().Intersection.LatLong); + var trk2 = Conversions.CalculateTrack(rte2.First().Intersection.LatLong, + rte2.Last().Intersection.LatLong); + data.trkAngle = Math.Abs(trk2 - trk); + var sameDir = data.trkAngle < 45; + var crossing = (data.trkAngle >= 45 && data.trkAngle <= 135) || + (data.trkAngle >= 315 && data.trkAngle <= 225); + var oppoDir = data.trkAngle > 135 && data.trkAngle < 225; + var cfl2 = fdr2.CFLUpper; + var rfl2 = fdr2.RFL; + var alt2 = cfl2 == -1 ? rfl2 : cfl2; + var isRvsm2 = fdr2.RVSM; + data.verticalAct = Math.Abs(alt - alt2); + data.verticalSep = alt > 45000 && alt < 60000 + ? 4000 + : alt > 60000 + ? 5000 + : alt2 > 45000 && alt2 < 60000 + ? 4000 + : alt2 > 60000 + ? 5000 + : (alt > FDP2.RVSM_BAND_LOWER && !isRvsm) || + (alt2 > FDP2.RVSM_BAND_LOWER && !isRvsm2) || alt > FDP2.RVSM_BAND_UPPER || + alt2 > FDP2.RVSM_BAND_UPPER + ? 2000 + : 1000; + + if (data.verticalAct < data.verticalSep) { - data.latSep = Math.Max(latSep, 23); - } + //data.latSep = latSep1; + if (fpap.rnp4 && fpap.pbcs && fpap.adsc && fpap.cpdlc) + data.latSep = Math.Max(latSep, 23); - else if (fpap.rnp10 || fpap.rnp4) - { - data.latSep = Math.Max(latSep, 50); - } - else if (!fpap.rnp10 && !fpap.rnp4) - { - data.latSep = Math.Max(latSep, 100); - } + else if (fpap.rnp10 || fpap.rnp4) + data.latSep = Math.Max(latSep, 50); - else if (data.latSep != 100 && data.latSep == 100); - { - data.latSep = (50 + 100) / 2; - } + else if (!fpap.rnp10 && !fpap.rnp4) + data.latSep = Math.Max(latSep, 100); - var cpar = new CPAR(fdr2, fdr, data.latSep); - var segments1 = cpar.Segments1; - var segments2 = cpar.Segments2; - - segments1.Sort((Comparison)((s, t) => s.startTime.CompareTo(t.startTime))); //sort by first conflict time - segments2.Sort((Comparison)((s, t) => s.startTime.CompareTo(t.startTime))); - - var firstConflictTime = segments1.FirstOrDefault(); - var firstConflictTime2 = segments2.FirstOrDefault(); - var failedLateral = segments1.Count > 0; - if (firstConflictTime == null || firstConflictTime2 == null) continue; - - data.mnt = sameDir && fpap.jet; - data.longTimesep = data.mnt ? (new TimeSpan(0, 0, 10, 0)) : (new TimeSpan(0, 0, 15, 0)); - data.longTimeact = (firstConflictTime2.startTime - firstConflictTime.startTime).Duration(); - data.longDistsep = fpap.jet && fpap.rnp4 && fpap.pbcs && fpap.cpdlc && fpap.adsc ? 30 : fpap.jet && fpap.rnp10 && fpap.pbcs && fpap.cpdlc && fpap.adsc ? 50 : default; - data.longDistact = Conversions.CalculateDistance(firstConflictTime.startLatlong, firstConflictTime2.startLatlong); - data.timeLongsame = sameDir && failedLateral && firstConflictTime.endTime > DateTime.UtcNow - && data.longTimeact < data.longTimesep;//check time based longitudinal for same direction - data.timeLongcross = crossing && failedLateral && firstConflictTime.endTime > DateTime.UtcNow - && (firstConflictTime2.startTime - firstConflictTime.startTime).Duration() < (new TimeSpan(0, 0, 15, 0)); - data.distLongsame = sameDir && failedLateral && firstConflictTime.endTime > DateTime.UtcNow - && data.longDistact < data.longDistsep; - - data.timeLongopposite = false; - data.top = null; - - if (failedLateral && oppoDir) - { - try + else if (data.latSep != 100 && data.latSep == 100) ; { - data.top = new TimeOfPassing(fdr, fdr2); + data.latSep = (50 + 100) / 2; } - catch (Exception e) + var cpar = new CPAR(fdr2, fdr, data.latSep); + var segments1 = cpar.Segments1; + var segments2 = cpar.Segments2; + + segments1.Sort((s, t) => s.startTime.CompareTo(t.startTime)); //sort by first conflict time + segments2.Sort((s, t) => s.startTime.CompareTo(t.startTime)); + + var firstConflictTime = segments1.FirstOrDefault(); + var firstConflictTime2 = segments2.FirstOrDefault(); + var failedLateral = segments1.Count > 0; + if (firstConflictTime == null || firstConflictTime2 == null) continue; + + data.mnt = sameDir && fpap.jet; + data.longTimesep = data.mnt ? new TimeSpan(0, 0, 10, 0) : new TimeSpan(0, 0, 15, 0); + data.longTimeact = (firstConflictTime2.startTime - firstConflictTime.startTime).Duration(); + data.longDistsep = fpap.jet && fpap.rnp4 && fpap.pbcs && fpap.cpdlc && fpap.adsc ? 30 : + fpap.jet && fpap.rnp10 && fpap.pbcs && fpap.cpdlc && fpap.adsc ? 50 : default; + data.longDistact = Conversions.CalculateDistance(firstConflictTime.startLatlong, + firstConflictTime2.startLatlong); + data.timeLongsame = sameDir && failedLateral && firstConflictTime.endTime > DateTime.UtcNow + && data.longTimeact < + data.longTimesep; //check time based longitudinal for same direction + data.timeLongcross = crossing && failedLateral && firstConflictTime.endTime > DateTime.UtcNow + && (firstConflictTime2.startTime - firstConflictTime.startTime) + .Duration() < new TimeSpan(0, 0, 15, 0); + data.distLongsame = sameDir && failedLateral && firstConflictTime.endTime > DateTime.UtcNow + && data.longDistact < data.longDistsep; + + data.timeLongopposite = false; + data.top = null; + + if (failedLateral && oppoDir) { - return; - } - data.timeLongopposite = data.top.Time > DateTime.UtcNow - && (data.top.Time.Add(new TimeSpan(0, 0, 10, 0)) > DateTime.UtcNow) && (data.top.Time.Subtract(new TimeSpan(0, 0, 10, 0)) < DateTime.UtcNow); - } - - data.longType = (fpap.adsc && fpap.cpdlc && (fpap.rnp4 || fpap.rnp10) && fpap.pbcs) ? data.distLongsame : data.timeLongsame; - - var lossOfSep = data.longType || data.timeLongcross || data.timeLongopposite; - data.conflictType = lossOfSep && sameDir ? "same" : lossOfSep && crossing ? "crossing" : lossOfSep && oppoDir ? "opposite" : null; - data.earliestLOS = (failedLateral && oppoDir ? data.top.Time.Subtract(new TimeSpan(0, 0, 10, 0)) - : (DateTime.Compare(firstConflictTime.startTime, firstConflictTime2.startTime) < 0 ? firstConflictTime.startTime : firstConflictTime2.startTime)); - - data.actualConflicts = (failedLateral && oppoDir && (data.verticalAct < data.verticalSep)) ? (new TimeSpan(0, 0, 1, 0, 0) >= data.earliestLOS.Subtract(DateTime.UtcNow).Duration()) - : (lossOfSep && new TimeSpan(0, 0, 1, 0, 0) >= data.earliestLOS.Subtract(DateTime.UtcNow).Duration()) || data.earliestLOS < DateTime.UtcNow; - - data.imminentConflicts = (failedLateral && oppoDir && (data.verticalAct < data.verticalSep)) ? (new TimeSpan(0, 0, 30, 0, 0) >= data.earliestLOS.Subtract(DateTime.UtcNow).Duration()) - : (lossOfSep && new TimeSpan(0, 0, 30, 0, 0) >= data.earliestLOS.Subtract(DateTime.UtcNow).Duration()); //check if timediff < 30 min - - data.advisoryConflicts = (failedLateral && oppoDir && (data.verticalAct < data.verticalSep)) ? (new TimeSpan(0, 2, 0, 0, 0) > data.earliestLOS.Subtract(DateTime.UtcNow).Duration()) - && (data.earliestLOS.Subtract(DateTime.UtcNow).Duration() >= new TimeSpan(0, 0, 30, 0, 0)) - : (lossOfSep && new TimeSpan(0, 2, 0, 0, 0) > data.earliestLOS.Subtract(DateTime.UtcNow).Duration()) - && (data.earliestLOS.Subtract(DateTime.UtcNow).Duration() >= new TimeSpan(0, 0, 30, 0, 0)); //check if 2 hours > timediff > 30 mins + try + { + data.top = new TimeOfPassing(fdr, fdr2); + } + catch (Exception e) + { + return; + } + data.timeLongopposite = data.top.Time > DateTime.UtcNow + && data.top.Time.Add(new TimeSpan(0, 0, 10, 0)) > DateTime.UtcNow && + data.top.Time.Subtract(new TimeSpan(0, 0, 10, 0)) < DateTime.UtcNow; + } - if (data.actualConflicts || data.imminentConflicts) - { - label.imminentConflict.AddOrUpdate(fdr.Callsign, new HashSet(new string[] { fdr2.Callsign }), - (k, v) => { v.Add(fdr2.Callsign); return v; }); + data.longType = fpap.adsc && fpap.cpdlc && (fpap.rnp4 || fpap.rnp10) && fpap.pbcs + ? data.distLongsame + : data.timeLongsame; + + var lossOfSep = data.longType || data.timeLongcross || data.timeLongopposite; + data.conflictType = lossOfSep && sameDir ? "same" : + lossOfSep && crossing ? "crossing" : + lossOfSep && oppoDir ? "opposite" : null; + data.earliestLOS = failedLateral && oppoDir + ? data.top.Time.Subtract(new TimeSpan(0, 0, 10, 0)) + : DateTime.Compare(firstConflictTime.startTime, firstConflictTime2.startTime) < 0 + ? firstConflictTime.startTime + : firstConflictTime2.startTime; + + data.actualConflicts = failedLateral && oppoDir && data.verticalAct < data.verticalSep + ? new TimeSpan(0, 0, 1, 0, 0) >= data.earliestLOS.Subtract(DateTime.UtcNow).Duration() + : (lossOfSep && new TimeSpan(0, 0, 1, 0, 0) >= + data.earliestLOS.Subtract(DateTime.UtcNow).Duration()) || + data.earliestLOS < DateTime.UtcNow; + + data.imminentConflicts = failedLateral && oppoDir && data.verticalAct < data.verticalSep + ? new TimeSpan(0, 0, 30, 0, 0) >= data.earliestLOS.Subtract(DateTime.UtcNow).Duration() + : lossOfSep && new TimeSpan(0, 0, 30, 0, 0) >= + data.earliestLOS.Subtract(DateTime.UtcNow).Duration(); //check if timediff < 30 min + + data.advisoryConflicts = failedLateral && oppoDir && data.verticalAct < data.verticalSep + ? new TimeSpan(0, 2, 0, 0, 0) > data.earliestLOS.Subtract(DateTime.UtcNow).Duration() + && data.earliestLOS.Subtract(DateTime.UtcNow).Duration() >= new TimeSpan(0, 0, 30, 0, 0) + : lossOfSep && new TimeSpan(0, 2, 0, 0, 0) > + data.earliestLOS.Subtract(DateTime.UtcNow).Duration() + && data.earliestLOS.Subtract(DateTime.UtcNow).Duration() >= + new TimeSpan(0, 0, 30, 0, 0); //check if 2 hours > timediff > 30 mins + + + if (data.actualConflicts || data.imminentConflicts) + { + label.imminentConflict.AddOrUpdate(fdr.Callsign, + new HashSet(new[] { fdr2.Callsign }), + (k, v) => + { + v.Add(fdr2.Callsign); + return v; + }); conDict.Add(data); - - } - else - { - HashSet maybeSet; - bool exists = label.imminentConflict.TryGetValue(fdr.Callsign, out maybeSet); - if (exists) - { - maybeSet.Clear(); } - - - var emptyImminentConflicts = label.imminentConflict.Where(pair => pair.Value.Count == 0) - .Select(pair => pair.Key) - .ToList(); - foreach (var callsign in emptyImminentConflicts) + else { - label.imminentConflict.TryRemove(callsign, out _); - } + HashSet maybeSet; + var exists = label.imminentConflict.TryGetValue(fdr.Callsign, out maybeSet); + if (exists) maybeSet.Clear(); + var emptyImminentConflicts = label.imminentConflict.Where(pair => pair.Value.Count == 0) + .Select(pair => pair.Key) + .ToList(); + foreach (var callsign in emptyImminentConflicts) + label.imminentConflict.TryRemove(callsign, out _); - if (data.advisoryConflicts) - { - label.advisoryConflict.AddOrUpdate(fdr.Callsign, new HashSet(new string[] { fdr2.Callsign }), - (k, v) => { v.Add(fdr2.Callsign); return v; }); - } - else - { - HashSet admaybeSet; - bool adexists = label.advisoryConflict.TryGetValue(fdr.Callsign, out admaybeSet); - if (adexists) + if (data.advisoryConflicts) { - admaybeSet.Clear(); + label.advisoryConflict.AddOrUpdate(fdr.Callsign, + new HashSet(new[] { fdr2.Callsign }), + (k, v) => + { + v.Add(fdr2.Callsign); + return v; + }); } - - var emptyAdvisoryConflicts = label.advisoryConflict.Where(pair => pair.Value.Count == 0) - .Select(pair => pair.Key) - .ToList(); - foreach (var callsign in emptyAdvisoryConflicts) + else { - label.advisoryConflict.TryRemove(callsign, out _); + HashSet admaybeSet; + var adexists = label.advisoryConflict.TryGetValue(fdr.Callsign, out admaybeSet); + if (adexists) admaybeSet.Clear(); + + var emptyAdvisoryConflicts = label.advisoryConflict.Where(pair => pair.Value.Count == 0) + .Select(pair => pair.Key) + .ToList(); + foreach (var callsign in emptyAdvisoryConflicts) + label.advisoryConflict.TryRemove(callsign, out _); } - } - } - } - else - { - HashSet maybeSet; // defines an uninitialized variable for the result of the below method to get placed in - HashSet admaybeSet; - bool adexists = label.advisoryConflict.TryGetValue(fdr.Callsign, out admaybeSet); - bool exists = label.imminentConflict.TryGetValue(fdr.Callsign, out maybeSet); // tries to get the set of conflicts corresponding to a callsign, places it in the `maybeSet` variable if it exists. The bool `exists` represents whether there was a set of conflicts for that callsign - if (exists) - { - maybeSet.Remove(fdr2.Callsign); // remove the fdr2 (which is the one we are currently evaluating for conflicts against fdr) from the set of conflicts - } - if (adexists) + else { - admaybeSet.Remove(fdr2.Callsign); // remove the fdr2 (which is the one we are currently evaluating for conflicts against fdr) from the set of conflicts - } + HashSet + maybeSet; // defines an uninitialized variable for the result of the below method to get placed in + HashSet admaybeSet; + var adexists = label.advisoryConflict.TryGetValue(fdr.Callsign, out admaybeSet); + var exists = + label.imminentConflict.TryGetValue(fdr.Callsign, + out maybeSet); // tries to get the set of conflicts corresponding to a callsign, places it in the `maybeSet` variable if it exists. The bool `exists` represents whether there was a set of conflicts for that callsign + if (exists) + maybeSet.Remove(fdr2 + .Callsign); // remove the fdr2 (which is the one we are currently evaluating for conflicts against fdr) from the set of conflicts + if (adexists) + admaybeSet.Remove(fdr2 + .Callsign); // remove the fdr2 (which is the one we are currently evaluating for conflicts against fdr) from the set of conflicts - var emptyAdvisoryConflicts = label.advisoryConflict.Where(pair => pair.Value.Count == 0) - .Select(pair => pair.Key) - .ToList(); - foreach (var callsign in emptyAdvisoryConflicts) - { - label.advisoryConflict.TryRemove(callsign, out _); - } - var emptyImminentConflicts = label.imminentConflict.Where(pair => pair.Value.Count == 0) - .Select(pair => pair.Key) - .ToList(); - foreach (var callsign in emptyImminentConflicts) - { - label.imminentConflict.TryRemove(callsign, out _); + var emptyAdvisoryConflicts = label.advisoryConflict.Where(pair => pair.Value.Count == 0) + .Select(pair => pair.Key) + .ToList(); + foreach (var callsign in emptyAdvisoryConflicts) + label.advisoryConflict.TryRemove(callsign, out _); + var emptyImminentConflicts = label.imminentConflict.Where(pair => pair.Value.Count == 0) + .Select(pair => pair.Key) + .ToList(); + foreach (var callsign in emptyImminentConflicts) + label.imminentConflict.TryRemove(callsign, out _); } } - } + } + + + public class Segment + { + public string callsign; + public Coordinate endLatlong; + public DateTime endTime = DateTime.MaxValue; + public FDP2.FDR.ExtractedRoute.Segment routeSegment; + public Coordinate startLatlong; + public DateTime startTime = DateTime.MaxValue; + } + + public class ConflictData + { + public bool actualConflicts; + public bool advisoryConflicts; + public string conflictType; + public bool distLongsame; + public DateTime earliestLOS; + public Segment endLatlong; + public Segment endTime; + public FDP2.FDR fdr; + public FDP2.FDR fdr2; + public bool imminentConflicts; + public int latAct; + public int latSep; + public double longDistact; + public double longDistsep; + public TimeSpan longTimeact; + public TimeSpan longTimesep; + public bool longType; + public bool mnt; + public Segment startLatlong; + public Segment startTime; + public bool timeLongcross; + public bool timeLongopposite; + public bool timeLongsame; + public TimeOfPassing top; + public double trkAngle; + public int verticalAct; + public int verticalSep; } } -} +} \ No newline at end of file diff --git a/ConflictSummaryWindw.Designer.cs b/ConflictSummaryWindw.Designer.cs deleted file mode 100644 index e796658..0000000 --- a/ConflictSummaryWindw.Designer.cs +++ /dev/null @@ -1,267 +0,0 @@ -namespace AuroraLabelItemsPlugin -{ - partial class Form1 - { - /// - /// Required designer variable. - /// - private System.ComponentModel.IContainer components = null; - - /// - /// Clean up any resources being used. - /// - /// true if managed resources should be disposed; otherwise, false. - protected override void Dispose(bool disposing) - { - if (disposing && (components != null)) - { - components.Dispose(); - } - base.Dispose(disposing); - } - - #region Windows Form Designer generated code - - /// - /// Required method for Designer support - do not modify - /// the contents of this method with the code editor. - /// - private void InitializeComponent() - { - System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(Form1)); - this.textBox1 = new System.Windows.Forms.TextBox(); - this.textBox2 = new System.Windows.Forms.TextBox(); - this.textBox3 = new System.Windows.Forms.TextBox(); - this.textBox4 = new System.Windows.Forms.TextBox(); - this.textBox5 = new System.Windows.Forms.TextBox(); - this.textBox6 = new System.Windows.Forms.TextBox(); - this.textBox7 = new System.Windows.Forms.TextBox(); - this.textBox8 = new System.Windows.Forms.TextBox(); - this.listView1 = new System.Windows.Forms.ListView(); - this.textBox9 = new System.Windows.Forms.TextBox(); - this.Intruder = ((System.Windows.Forms.ColumnHeader)(new System.Windows.Forms.ColumnHeader())); - this.Att = ((System.Windows.Forms.ColumnHeader)(new System.Windows.Forms.ColumnHeader())); - this.Active = ((System.Windows.Forms.ColumnHeader)(new System.Windows.Forms.ColumnHeader())); - this.Att2 = ((System.Windows.Forms.ColumnHeader)(new System.Windows.Forms.ColumnHeader())); - this.Ovrd = ((System.Windows.Forms.ColumnHeader)(new System.Windows.Forms.ColumnHeader())); - this.Type = ((System.Windows.Forms.ColumnHeader)(new System.Windows.Forms.ColumnHeader())); - this.StartTime = ((System.Windows.Forms.ColumnHeader)(new System.Windows.Forms.ColumnHeader())); - this.EndTime = ((System.Windows.Forms.ColumnHeader)(new System.Windows.Forms.ColumnHeader())); - this.SuspendLayout(); - // - // textBox1 - // - this.textBox1.BackColor = System.Drawing.SystemColors.Control; - this.textBox1.BorderStyle = System.Windows.Forms.BorderStyle.None; - this.textBox1.Cursor = System.Windows.Forms.Cursors.Default; - this.textBox1.Font = new System.Drawing.Font("Terminus (TTF)", 7.999999F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0))); - this.textBox1.Location = new System.Drawing.Point(17, 111); - this.textBox1.Name = "textBox1"; - this.textBox1.Size = new System.Drawing.Size(112, 18); - this.textBox1.TabIndex = 0; - this.textBox1.Text = "Intruder"; - // - // textBox2 - // - this.textBox2.BackColor = System.Drawing.SystemColors.Control; - this.textBox2.BorderStyle = System.Windows.Forms.BorderStyle.None; - this.textBox2.Cursor = System.Windows.Forms.Cursors.Default; - this.textBox2.Font = new System.Drawing.Font("Terminus (TTF)", 7.999999F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0))); - this.textBox2.Location = new System.Drawing.Point(146, 111); - this.textBox2.Name = "textBox2"; - this.textBox2.Size = new System.Drawing.Size(44, 18); - this.textBox2.TabIndex = 1; - this.textBox2.Text = "Att"; - // - // textBox3 - // - this.textBox3.BackColor = System.Drawing.SystemColors.Control; - this.textBox3.BorderStyle = System.Windows.Forms.BorderStyle.None; - this.textBox3.Cursor = System.Windows.Forms.Cursors.Default; - this.textBox3.Font = new System.Drawing.Font("Terminus (TTF)", 7.999999F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0))); - this.textBox3.Location = new System.Drawing.Point(317, 111); - this.textBox3.Name = "textBox3"; - this.textBox3.Size = new System.Drawing.Size(44, 18); - this.textBox3.TabIndex = 2; - this.textBox3.Text = "Att"; - // - // textBox4 - // - this.textBox4.BackColor = System.Drawing.SystemColors.Control; - this.textBox4.BorderStyle = System.Windows.Forms.BorderStyle.None; - this.textBox4.Cursor = System.Windows.Forms.Cursors.Default; - this.textBox4.Font = new System.Drawing.Font("Terminus (TTF)", 7.999999F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0))); - this.textBox4.Location = new System.Drawing.Point(215, 111); - this.textBox4.Name = "textBox4"; - this.textBox4.Size = new System.Drawing.Size(85, 18); - this.textBox4.TabIndex = 3; - this.textBox4.Text = "Active"; - // - // textBox5 - // - this.textBox5.BackColor = System.Drawing.SystemColors.Control; - this.textBox5.BorderStyle = System.Windows.Forms.BorderStyle.None; - this.textBox5.Cursor = System.Windows.Forms.Cursors.Default; - this.textBox5.Font = new System.Drawing.Font("Terminus (TTF)", 7.999999F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0))); - this.textBox5.Location = new System.Drawing.Point(378, 111); - this.textBox5.Name = "textBox5"; - this.textBox5.Size = new System.Drawing.Size(61, 18); - this.textBox5.TabIndex = 4; - this.textBox5.Text = "Ovrd"; - // - // textBox6 - // - this.textBox6.BackColor = System.Drawing.SystemColors.Control; - this.textBox6.BorderStyle = System.Windows.Forms.BorderStyle.None; - this.textBox6.Cursor = System.Windows.Forms.Cursors.Default; - this.textBox6.Font = new System.Drawing.Font("Terminus (TTF)", 7.999999F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0))); - this.textBox6.Location = new System.Drawing.Point(456, 111); - this.textBox6.Name = "textBox6"; - this.textBox6.Size = new System.Drawing.Size(61, 18); - this.textBox6.TabIndex = 5; - this.textBox6.Text = "Type"; - // - // textBox7 - // - this.textBox7.BackColor = System.Drawing.SystemColors.Control; - this.textBox7.BorderStyle = System.Windows.Forms.BorderStyle.None; - this.textBox7.Cursor = System.Windows.Forms.Cursors.Default; - this.textBox7.Font = new System.Drawing.Font("Terminus (TTF)", 7.999999F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0))); - this.textBox7.Location = new System.Drawing.Point(535, 111); - this.textBox7.Name = "textBox7"; - this.textBox7.Size = new System.Drawing.Size(121, 18); - this.textBox7.TabIndex = 6; - this.textBox7.Text = "StartTime"; - // - // textBox8 - // - this.textBox8.BackColor = System.Drawing.SystemColors.Control; - this.textBox8.BorderStyle = System.Windows.Forms.BorderStyle.None; - this.textBox8.Cursor = System.Windows.Forms.Cursors.Default; - this.textBox8.Font = new System.Drawing.Font("Terminus (TTF)", 7.999999F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0))); - this.textBox8.Location = new System.Drawing.Point(679, 111); - this.textBox8.Name = "textBox8"; - this.textBox8.Size = new System.Drawing.Size(94, 18); - this.textBox8.TabIndex = 7; - this.textBox8.Text = "EndTime"; - // - // listView1 - // - this.listView1.BackColor = System.Drawing.Color.Red; - this.listView1.Columns.AddRange(new System.Windows.Forms.ColumnHeader[] { - this.Intruder, - this.Att, - this.Active, - this.Att2, - this.Ovrd, - this.Type, - this.StartTime, - this.EndTime}); - this.listView1.ForeColor = System.Drawing.SystemColors.ButtonFace; - this.listView1.HideSelection = false; - this.listView1.Location = new System.Drawing.Point(29, 160); - this.listView1.Name = "listView1"; - this.listView1.Size = new System.Drawing.Size(744, 474); - this.listView1.TabIndex = 8; - this.listView1.UseCompatibleStateImageBehavior = false; - this.listView1.SelectedIndexChanged += new System.EventHandler(this.listView1_SelectedIndexChanged); - // - // textBox9 - // - this.textBox9.BackColor = System.Drawing.SystemColors.ButtonHighlight; - this.textBox9.Font = new System.Drawing.Font("Terminus (TTF)", 7.999999F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0))); - this.textBox9.Location = new System.Drawing.Point(6, 12); - this.textBox9.Name = "textBox9"; - this.textBox9.Size = new System.Drawing.Size(782, 25); - this.textBox9.TabIndex = 9; - this.textBox9.Text = "CONFLICT SUMMARY"; - this.textBox9.TextAlign = System.Windows.Forms.HorizontalAlignment.Center; - // - // Intruder - // - this.Intruder.Width = 8; - // - // Att - // - this.Att.TextAlign = System.Windows.Forms.HorizontalAlignment.Center; - this.Att.Width = 1; - // - // Active - // - this.Active.TextAlign = System.Windows.Forms.HorizontalAlignment.Center; - this.Active.Width = 8; - // - // Att2 - // - this.Att2.TextAlign = System.Windows.Forms.HorizontalAlignment.Center; - this.Att2.Width = 1; - // - // Ovrd - // - this.Ovrd.TextAlign = System.Windows.Forms.HorizontalAlignment.Center; - this.Ovrd.Width = 1; - // - // Type - // - this.Type.TextAlign = System.Windows.Forms.HorizontalAlignment.Center; - this.Type.Width = 3; - // - // StartTime - // - this.StartTime.TextAlign = System.Windows.Forms.HorizontalAlignment.Center; - this.StartTime.Width = 4; - // - // EndTime - // - this.EndTime.TextAlign = System.Windows.Forms.HorizontalAlignment.Center; - this.EndTime.Width = 4; - // - // Form1 - // - this.AutoScaleDimensions = new System.Drawing.SizeF(9F, 20F); - this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; - this.BackColor = System.Drawing.SystemColors.Control; - this.ClientSize = new System.Drawing.Size(800, 664); - this.Controls.Add(this.textBox9); - this.Controls.Add(this.listView1); - this.Controls.Add(this.textBox8); - this.Controls.Add(this.textBox7); - this.Controls.Add(this.textBox6); - this.Controls.Add(this.textBox5); - this.Controls.Add(this.textBox4); - this.Controls.Add(this.textBox3); - this.Controls.Add(this.textBox2); - this.Controls.Add(this.textBox1); - this.ForeColor = System.Drawing.SystemColors.ControlDark; - this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.None; - this.Icon = ((System.Drawing.Icon)(resources.GetObject("$this.Icon"))); - this.Name = "Form1"; - this.RightToLeft = System.Windows.Forms.RightToLeft.No; - this.Text = "CONFLICT SUMMARY"; - this.ResumeLayout(false); - this.PerformLayout(); - - } - - #endregion - - private System.Windows.Forms.TextBox textBox1; - private System.Windows.Forms.TextBox textBox2; - private System.Windows.Forms.TextBox textBox3; - private System.Windows.Forms.TextBox textBox4; - private System.Windows.Forms.TextBox textBox5; - private System.Windows.Forms.TextBox textBox6; - private System.Windows.Forms.TextBox textBox7; - private System.Windows.Forms.TextBox textBox8; - private System.Windows.Forms.ListView listView1; - private System.Windows.Forms.TextBox textBox9; - private System.Windows.Forms.ColumnHeader Intruder; - private System.Windows.Forms.ColumnHeader Att; - private System.Windows.Forms.ColumnHeader Active; - private System.Windows.Forms.ColumnHeader Att2; - private System.Windows.Forms.ColumnHeader Ovrd; - private System.Windows.Forms.ColumnHeader Type; - private System.Windows.Forms.ColumnHeader StartTime; - private System.Windows.Forms.ColumnHeader EndTime; - } -} \ No newline at end of file diff --git a/ConflictSummaryWindw.cs b/ConflictSummaryWindw.cs deleted file mode 100644 index ff18f61..0000000 --- a/ConflictSummaryWindw.cs +++ /dev/null @@ -1,34 +0,0 @@ -using System; -using System.Collections.Generic; -using System.ComponentModel; -using System.Data; -using System.Drawing; -using System.Linq; -using System.Text; -using System.Threading.Tasks; -using System.Windows.Forms; -using vatsys; - -namespace AuroraLabelItemsPlugin -{ - public partial class Form1 : Form - { - AuroraLabelItemsPlugin type = new AuroraLabelItemsPlugin(); - CPAR conflicts = new CPAR(); - public Form1() - { - foreach (var segment in conflicts.Segments1) - { - segment.callsign.ToString(); - segment.startTime.ToString(); - segment.endTime.ToString(); - } - InitializeComponent(); - } - - private void listView1_SelectedIndexChanged(object sender, EventArgs e) - { - - } - } -} diff --git a/ConflictSummaryWindw.resx b/ConflictSummaryWindw.resx deleted file mode 100644 index 692ee50..0000000 --- a/ConflictSummaryWindw.resx +++ /dev/null @@ -1,4632 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - text/microsoft-resx - - - 2.0 - - - System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - - - AAABAAEAAAAAAAEAIAAoIAQAFgAAACgAAAAAAQAAAAIAAAEAIAAAAAAAACAEABMLAAATCwAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD//wAI//8An///AP///wD///8A//// - AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A//// - AP///wD///8A////AP///wD///8Ax///ADAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD//wBA//8A2f//AP///wD///8A//// - AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A//// - AP///wD///8A////AP///wD///8A////AP///wD///8AagAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD//wB6//8A////AP///wD///8A//// - AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A//// - AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wB6AAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD//wB6//8A////AP///wD///8A//// - AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A//// - AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AHoAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD//wB6//8A////AP///wD///8A//// - AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A//// - AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8AegAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD//wB6//8A////AP///wD///8A//// - AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A//// - AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A//// - AP///wB6AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD//wB6//8A////AP///wD///8A//// - AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A//// - AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A//// - AP///wD///8A////AHoAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD//wB6//8A////AP///wD///8A//// - AP///wD///8A////AP///wD///8A////AP///wD///8A////AP/i4gn/oaEf/2pqKv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/1paLf+HhyX/w8MV////AP///wD///8A////AP///wD///8A////AP///wD///8A//// - AP///wD///8A////AP///wD///8AegAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD//wB6//8A////AP///wD///8A//// - AP///wD///8A////AP///wD///8A////AP///wD///8A/+zsBf95eSj/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv9aWi3/zs4S////AP///wD///8A////AP///wD///8A//// - AP///wD///8A////AP///wD///8A////AP///wB6AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD//wB6//8A////AP///wD///8A//// - AP///wD///8A////AP///wD///8A////AP///wD///8A/8PDFf9HRzD/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv/DwxX///8A////AP///wD///8A//// - AP///wD///8A////AP///wD///8A////AP///wD///8A////AHoAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD//wB6//8A////AP///wD///8A//// - AP///wD///8A////AP///wD///8A////AP///wD///8A/8PDFf8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/8PDFf///wD///8A//// - AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8AegAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD//wB6//8A////AP///wD///8A//// - AP///wD///8A////AP///wD///8A////AP///wD///8A/8PDFf8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/w8MV//// - AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wB6AAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD//wB6//8A////AP///wD///8A//// - AP///wD///8A////AP///wD///8A////AP///wD///8A/8PDFf8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv/DwxX///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A//// - AHoAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD//wB6//8A////AP///wD///8A//// - AP///wD///8A////AP///wD///8A////AP///wD///8A/8PDFf8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/8PDFf///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A//// - AP///wD///8AegAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD//wB6//8A////AP///wD///8A//// - AP///wD///8A////AP///wD///8A////AP///wD///8A/8PDFf8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/w8MV////AP///wD///8A////AP///wD///8A////AP///wD///8A//// - AP///wD///8A////AP///wB6AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD//wB6//8A////AP///wD///8A//// - AP///wD///8A////AP///wD///8A////AP///wD///8A/8PDFf8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv/DwxX///8A////AP///wD///8A////AP///wD///8A//// - AP///wD///8A////AP///wD///8A////AHoAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD//wB6//8A////AP///wD///8A//// - AP///wD///8A////AP///wD///8A////AP///wD///8A/8PDFf8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/8PDFf///wD///8A////AP///wD///8A//// - AP///wD///8A////AP///wD///8A////AP///wD///8AegAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD//wB6//8A////AP///wD///8A//// - AP///wD///8A////AP///wD///8A////AP///wD///8A/8PDFf8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/w8MV////AP///wD///8A//// - AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wB6AAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD//wB6//8A////AP///wD///8A//// - AP///wD///8A////AP///wD///8A////AP///wD///8A/8PDFf8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv/DwxX///8A//// - AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AHoAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD//wB6//8A////AP///wD///8A//// - AP///wD///8A////AP///wD///8A////AP///wD///8A/8PDFf8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/8PD - Ff///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8AegAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD//wB6//8A////AP///wD///8A//// - AP///wD///8A////AP///wD///8A////AP///wD///8A/8PDFf8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/w8MV////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A//// - AP///wB6AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD//wB6//8A////AP///wD///8A//// - AP///wD///8A////AP///wD///8A////AP///wD///8A/8PDFf8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv/DwxX///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A//// - AP///wD///8A////AHoAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD//wB6//8A////AP///wD///8A//// - AP///wD///8A////AP///wD///8A////AP///wD///8A/8PDFf8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/8PDFf///wD///8A////AP///wD///8A////AP///wD///8A//// - AP///wD///8A////AP///wD///8AegAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD//wB6//8A////AP///wD///8A//// - AP///wD///8A////AP///wD///8A////AP///wD///8A/8PDFf8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/w8MV////AP///wD///8A////AP///wD///8A//// - AP///wD///8A////AP///wD///8A////AP///wB6AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD//wB6//8A////AP///wD///8A//// - AP///wD///8A////AP///wD///8A////AP///wD///8A/8PDFf8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv/DwxX///8A////AP///wD///8A//// - AP///wD///8A////AP///wD///8A////AP///wD///8A////AHoAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD//wB6//8A////AP///wD///8A//// - AP///wD///8A////AP///wD///8A////AP///wD///8A/8PDFf8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/8PDFf///wD///8A//// - AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8AigAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD//wB6//8A////AP///wD///8A//// - AP///wD///8A////AP///wD///8A////AP///wD///8A/8PDFf8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/w8MV//// - AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wC5AAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD//wB6//8A////AP///wD///8A//// - AP///wD///8A////AP///wD///8A////AP///wD///8A/8PDFf8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv/DwxX///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A//// - ALkAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD//wB6//8A////AP///wD///8A//// - AP///wD///8A////AP///wD///8A////AP///wD///8A/8PDFf8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/8PDFf///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A//// - AP///wD///8AuQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD//wB6//8A////AP///wD///8A//// - AP///wD///8A////AP///wD///8A////AP///wD///8A/8PDFf8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/w8MV////AP///wD///8A////AP///wD///8A////AP///wD///8A//// - AP///wD///8A////AP///wC5AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD//wB6//8A////AP///wD///8A//// - AP///wD///8A////AP///wD///8A////AP///wD///8A/8PDFf8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv/DwxX///8A////AP///wD///8A////AP///wD///8A//// - AP///wD///8A////AP///wD///8A////ALkAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD//wB6//8A////AP///wD///8A//// - AP///wD///8A////AP///wD///8A////AP///wD///8A/8PDFf8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/8PDFf///wD///8A////AP///wD///8A//// - AP///wD///8A////AP///wD///8A////AP///wD///8AuQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD//wB6//8A////AP///wD///8A//// - AP///wD///8A////AP///wD///8A////AP///wD///8A/8PDFf8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/uLgZ////AP///wD///8A//// - AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wC5AAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD//wB6//8A////AP///wD///8A//// - AP///wD///8A////AP///wD///8A////AP///wD///8A/8PDFf8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv+VlSL///8A//// - AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////ALkAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD//wB6//8A////AP///wD///8A//// - AP///wD///8A////AP///wD///8A////AP///wD///8A/8PDFf8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/5WV - Iv///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8AuQAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD//wB6//8A////AP///wD///8A//// - AP///wD///8A////AP///wD///8A////AP///wD///8A/8PDFf8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/lZUi////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A//// - AP///wC5AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD//wB6//8A////AP///wD///8A//// - AP///wD///8A////AP///wD///8A////AP///wD///8A/8PDFf8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv+VlSL///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A//// - AP///wD///8A////ALkAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD//wB6//8A////AP///wD///8A//// - AP///wD///8A////AP///wD///8A////AP///wD///8A/8PDFf8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/5WVIv///wD///8A////AP///wD///8A////AP///wD///8A//// - AP///wD///8A////AP///wD///8AuQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD//wB6//8A////AP///wD///8A//// - AP///wD///8A////AP///wD///8A////AP///wD///8A/8PDFf8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/lZUi////AP///wD///8A////AP///wD///8A//// - AP///wD///8A////AP///wD///8A////AP///wC5AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD//wB6//8A////AP///wD///8A//// - AP///wD///8A////AP///wD///8A////AP///wD///8A/8PDFf8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv+VlSL///8A////AP///wD///8A//// - AP///wD///8A////AP///wD///8A////AP///wD///8A////ALkAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD//wB///8A////AP///wD///8A//// - AP///wD///8A////AP///wD///8A////AP///wD///8A/8PDFf8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/5WVIv///wD///8A//// - AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8AuQAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD//wC5//8A////AP///wD///8A//// - AP///wD///8A////AP///wD///8A////AP///wD///8A/8PDFf8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/lZUi//// - AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wC5AAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD//wC5//8A////AP///wD///8A//// - AP///wD///8A////AP///wD///8A////AP///wD///8A/8PDFf8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv+VlSL///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A//// - ALkAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD//wC5//8A////AP///wD///8A//// - AP///wD///8A////AP///wD///8A////AP///wD///8A/8PDFf8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/5WVIv///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A//// - AP///wD///8AuQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD//wC5//8A////AP///wD///8A//// - AP///wD///8A////AP///wD///8A////AP///wD///8A/8PDFf8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/lZUi////AP///wD///8A////AP///wD///8A////AP///wD///8A//// - AP///wD///8A////AP///wC5AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD//wC5//8A////AP///wD///8A//// - AP///wD///8A////AP///wD///8A////AP///wD///8A/8PDFf8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv+VlSL///8A////AP///wD///8A////AP///wD///8A//// - AP///wD///8A////AP///wD///8A////ALkAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD//wC5//8A////AP///wD///8A//// - AP///wD///8A////AP///wD///8A////AP///wD///8A/8PDFf8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/5WVIv///wD///8A////AP///wD///8A//// - AP///wD///8A////AP///wD///8A////AP///wD///8AuQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD//wC5//8A////AP///wD///8A//// - AP///wD///8A////AP///wD///8A////AP///wD///8A/8PDFf8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/lZUi////AP///wD///8A//// - AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wC5AAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD//wC5//8A////AP///wD///8A//// - AP///wD///8A////AP///wD///8A////AP///wD///8A/5WVIv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv+VlSL///8A//// - AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////ALkAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD//wC5//8A////AP///wD///8A//// - AP///wD///8A////AP///wD///8A////AP///wD///8A/5WVIv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/5WV - Iv///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8AuQAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD//wC5//8A////AP///wD///8A//// - AP///wD///8A////AP///wD///8A////AP///wD///8A/5WVIv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/lZUi////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A//// - AP///wC5AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD//wC5//8A////AP///wD///8A//// - AP///wD///8A////AP///wD///8A////AP///wD///8A/5WVIv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv+VlSL///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A//// - AP///wD///8A////ALkAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD//wC5//8A////AP///wD///8A//// - AP///wD///8A////AP///wD///8A////AP///wD///8A/5WVIv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/5WVIv///wD///8A////AP///wD///8A////AP///wD///8A//// - AP///wD///8A////AP///wD///8AuQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD//wC5//8A////AP///wD///8A//// - AP///wD///8A////AP///wD///8A////AP///wD///8A/5WVIv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/lZUi////AP///wD///8A////AP///wD///8A//// - AP///wD///8A////AP///wD///8A////AP///wC5AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD//wC5//8A////AP///wD///8A//// - AP///wD///8A////AP///wD///8A////AP///wD///8A/5WVIv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv+VlSL///8A////AP///wD///8A//// - AP///wD///8A////AP///wD///8A////AP///wD///8A////ALkAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD//wC5//8A////AP///wD///8A//// - AP///wD///8A////AP///wD///8A////AP///wD///8A/5WVIv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/5WVIv///wD///8A//// - AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8AuQAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD//wC5//8A////AP///wD///8A//// - AP///wD///8A////AP///wD///8A////AP///wD///8A/5WVIv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/lZUi//// - AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wC5AAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD//wC5//8A////AP///wD///8A//// - AP///wD///8A////AP///wD///8A////AP///wD///8A/5WVIv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv+VlSL///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A//// - ALkAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD//wC5//8A////AP///wD///8A//// - AP///wD///8A////AP///wD///8A////AP///wD///8A/5WVIv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/5WVIv///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A//// - AP///wD///8AuQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD//wC5//8A////AP///wD///8A//// - AP///wD///8A////AP///wD///8A////AP///wD///8A/5WVIv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/lZUi////AP///wD///8A////AP///wD///8A////AP///wD///8A//// - AP///wD///8A////AP///wC5AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD//wC5//8A////AP///wD///8A//// - AP///wD///8A////AP///wD///8A////AP///wD///8A/5WVIv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv+VlSL///8A////AP///wD///8A////AP///wD///8A//// - AP///wD///8A////AP///wD///8A////ALkAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD//wC5//8A////AP///wD///8A//// - AP///wD///8A////AP///wD///8A////AP///wD///8A/5WVIv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/5WVIv///wD///8A////AP///wD///8A//// - AP///wD///8A////AP///wD///8A////AP///wD///8AuQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD//wC5//8A////AP///wD///8A//// - AP///wD///8A////AP///wD///8A////AP///wD///8A/5WVIv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/lZUi////AP///wD///8A//// - AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wC5AAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD//wC5//8A////AP///wD///8A//// - AP///wD///8A////AP///wD///8A////AP///wD///8A/5WVIv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv+VlSL///8A//// - AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////ALkAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD//wC5//8A////AP///wD///8A//// - AP///wD///8A////AP///wD///8A////AP///wD///8A/5WVIv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/5WV - Iv///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8AuQAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD//wC5//8A////AP///wD///8A//// - AP///wD///8A////AP///wD///8A////AP///wD///8A/5WVIv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/lZUi////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A//// - AP///wC5AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD//wC5//8A////AP///wD///8A//// - AP///wD///8A////AP///wD///8A////AP///wD///8A/5WVIv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv+VlSL///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A//// - AP///wD///8A////ALkAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD//wC5//8A////AP///wD///8A//// - AP///wD///8A////AP///wD///8A////AP///wD///8A/5WVIv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/3l5 - KP8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/5WVIv///wD///8A////AP///wD///8A////AP///wD///8A//// - AP///wD///8A////AP///wD///8AuQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD//wC5//8A////AP///wD///8A//// - AP///wD///8A////AP///wD///8A////AP///wD///8A/5WVIv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/5WV - Iv///wD/w8MV/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/lZUi////AP///wD///8A////AP///wD///8A//// - AP///wD///8A////AP///wD///8A////AP///wC5AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD//wC5//8A////AP///wD///8A//// - AP///wD///8A////AP///wD///8A////AP///wD///8A/5WVIv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/5WV - Iv///wD///8A////AP/DwxX/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv+VlSL///8A////AP///wD///8A//// - AP///wD///8A////AP///wD///8A////AP///wD///8A////ALkAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD//wC5//8A////AP///wD///8A//// - AP///wD///8A////AP///wD///8A////AP///wD///8A/5WVIv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/5WV - Iv///wD///8A////AP///wD///8A/8PDFf8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/5WVIv///wD///8A//// - AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8AuQAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD//wC5//8A////AP///wD///8A//// - AP///wD///8A////AP///wD///8A////AP///wD///8A/5WVIv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/5WV - Iv///wD///8A////AP///wD///8A////AP///wD/w8MV/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/lZUi//// - AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wC5AAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD//wC5//8A////AP///wD///8A//// - AP///wD///8A////AP///wD///8A////AP///wD///8A/5WVIv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/5WV - Iv///wD///8A////AP///wD///8A////AP///wD///8A////AP/DwxX/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv+VlSL///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A//// - ALkAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD//wC5//8A////AP///wD///8A//// - AP///wD///8A////AP///wD///8A////AP///wD///8A/5WVIv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/5WV - Iv///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A/8PDFf8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/5WVIv///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A//// - AP///wD///8AuQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD//wC5//8A////AP///wD///8A//// - AP///wD///8A////AP///wD///8A////AP///wD///8A/5WVIv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/5WV - Iv///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD/w8MV/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/lZUi////AP///wD///8A////AP///wD///8A////AP///wD///8A//// - AP///wD///8A////AP///wC5AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD//wC5//8A////AP///wD///8A//// - AP///wD///8A////AP///wD///8A////AP///wD///8A/5WVIv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/5WV - Iv///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A//// - AP/DwxX/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv+VlSL///8A////AP///wD///8A////AP///wD///8A//// - AP///wD///8A////AP///wD///8A////ALn//wAYAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD//wC5//8A////AP///wD///8A//// - AP///wD///8A////AP///wD///8A////AP///wD///8A/5WVIv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/5WV - Iv///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A//// - AP///wD///8A/8PDFf8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/5WVIv///wD///8A////AP///wD///8A//// - AP///wD///8A////AP///wD///8A////AP///wD///8A6f//ACoAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD//wC5//8A////AP///wD///8A//// - AP///wD///8A////AP///wD///8A////AP///wD///8A/5WVIv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/5WV - Iv///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A//// - AP///wD///8A////AP///wD/w8MV/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/lZUi////AP///wD///8A//// - AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wDp//8AKgAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD//wC5//8A////AP///wD///8A//// - AP///wD///8A////AP///wD///8A////AP///wD///8A/5WVIv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/5WV - Iv///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A//// - AP///wD///8A////AP///wD///8A////AP/DwxX/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv+VlSL///8A//// - AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AOn//wAqAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD//wC5//8A////AP///wD///8A//// - AP///wD///8A////AP///wD///8A////AP///wD///8A/5WVIv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/5WV - Iv///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A//// - AP///wD///8A////AP///wD///8A////AP///wD///8A/8PDFf8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/5WV - Iv///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A6f// - ACoAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD//wC5//8A////AP///wD///8A//// - AP///wD///8A////AP///wD///8A////AP///wD///8A/5WVIv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/5WV - Iv///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A//// - AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD/w8MV/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/lZUi////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A//// - AP///wDp//8AKgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD//wC5//8A////AP///wD///8A//// - AP///wD///8A////AP///wD///8A////AP///wD///8A/5WVIv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/5WV - Iv///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8Auf// - AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP/DwxX/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv+VlSL///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A//// - AP///wD///8A////AOn//wAqAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD//wC5//8A////AP///wD///8A//// - AP///wD///8A////AP///wD///8A////AP///wD///8A/5WVIv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/5WV - Iv///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8AuQAA - AAD//wB6//8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A/8PD - Ff8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/5WVIv///wD///8A////AP///wD///8A////AP///wD///8A//// - AP///wD///8A////AP///wD///8A6f//ACoAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD//wC5//8A////AP///wD///8A//// - AP///wD///8A////AP///wD///8A////AP///wD///8A/5WVIv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/5WV - Iv///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8AuQAA - AAAAAAAAAAAAAP//AHr//wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A//// - AP///wD/w8MV/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/amoq//b2Av///wD///8A////AP///wD///8A//// - AP///wD///8A////AP///wD///8A////AP///wDp//8AKgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD//wC5//8A////AP///wD///8A//// - AP///wD///8A////AP///wD///8A////AP///wD///8A/5WVIv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/5WV - Iv///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8AuQAA - AAAAAAAAAAAAAAAAAAAAAAAA//8Aev//AP///wD///8A////AP///wD///8A////AP///wD///8A//// - AP///wD///8A////AP/DwxX/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv9qair/9vYC////AP///wD///8A//// - AP///wD///8A////AP///wD///8A////AP///wD///8A////AOn//wAqAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD//wC5//8A////AP///wD///8A//// - AP///wD///8A////AP///wD///8A////AP///wD///8A/5WVIv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/5WV - Iv///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8AuQAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD//wB6//8A////AP///wD///8A////AP///wD///8A//// - AP///wD///8A////AP///wD///8A/8PDFf8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/2pqKv/29gL///8A//// - AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A6f//ACoAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD//wC5//8A////AP///wD///8A//// - AP///wD///8A////AP///wD///8A////AP///wD///8A/5WVIv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/5WV - Iv///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8AuQAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP//AHr//wD///8A////AP///wD///8A//// - AP///wD///8A////AP///wD///8A////AP///wD/w8MV/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/amoq//b2 - Av///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wDp//8AKgAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD//wC5//8A////AP///wD///8A//// - AP///wD///8A////AP///wD///8A////AP///wD///8A/5WVIv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/5WV - Iv///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8AuQAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA//8Aev//AP///wD///8A//// - AP///wD///8A////AP///wD///8A////AP///wD///8A////AP/DwxX/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv9qair/9vYC////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A//// - AOn//wAqAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD//wC5//8A////AP///wD///8A//// - AP///wD///8A////AP///wD///8A////AP///wD///8A/5WVIv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/5WV - Iv///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8AuQAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD//wB6//8A//// - AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A/8PDFf8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/2pqKv/29gL///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A//// - AP///wD///8A6f//ACoAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD//wC5//8A////AP///wD///8A//// - AP///wD///8A////AP///wD///8A////AP///wD///8A/5WVIv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/6Gh - H////wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8AuQAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP// - AHr//wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD/w8MV/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/amoq//b2Av///wD///8A////AP///wD///8A////AP///wD///8A//// - AP///wD///8A////AP///wDp//8AKgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD//wC5//8A////AP///wD///8A//// - AP///wD///8A////AP///wD///8A////AP///wD///8A/5WVIv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/8PD - Ff///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8AuQAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAA//8Aev//AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A//// - AP/DwxX/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv9qair/9vYC////AP///wD///8A////AP///wD///8A//// - AP///wD///8A////AP///wD///8A////AOn//wAqAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP//ACr//wDJ//8A////AP///wD///8A//// - AP///wD///8A////AP///wD///8A////AP///wD///8A/5WVIv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/8PD - Ff///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8AuQAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAD//wB6//8A////AP///wD///8A////AP///wD///8A////AP///wD///8A//// - AP///wD///8A/8PDFf8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/2pqKv/29gL///8A////AP///wD///8A//// - AP///wD///8A////AP///wD///8A////AP///wD///8A6f//ACoAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP//ACr//wDp//8A////AP///wD///8A//// - AP///wD///8A////AP///wD///8A////AP///wD///8A/5WVIv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/8PD - Ff///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8AuQAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAP//AHr//wD///8A////AP///wD///8A////AP///wD///8A//// - AP///wD///8A////AP///wD/w8MV/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/amoq//b2Av///wD///8A//// - AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wDp//8AKgAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP//ACr//wDp//8A////AP///wD///8A//// - AP///wD///8A////AP///wD///8A////AP///wD///8A/5WVIv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/8PD - Ff///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8AuQAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA//8Aev//AP///wD///8A////AP///wD///8A//// - AP///wD///8A////AP///wD///8A////AP/DwxX/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv9qair/9vYC//// - AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AOn//wAqAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP//ACr//wDp//8A////AP///wD///8A//// - AP///wD///8A////AP///wD///8A////AP///wD///8A/5WVIv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/8PD - Ff///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8AuQAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD//wB6//8A////AP///wD///8A//// - AP///wD///8A////AP///wD///8A////AP///wD///8A/+LiCf9HRzD/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/2pq - Kv/29gL///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A6f// - ACoAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP//ACr//wDp//8A////AP///wD///8A//// - AP///wD///8A////AP///wD///8A////AP///wD///8A/5WVIv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/8PD - Ff///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8AuQAA - AAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP//AHr//wD///8A//// - AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD/4uIJ/0dHMP8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/amoq//b2Av///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A//// - AP///wDp//8AKgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP//ACr//wDp//8A////AP///wD///8A//// - AP///wD///8A////AP///wD///8A////AP///wD///8A/5WVIv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/8PD - Ff///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD//PwAqwAA - AAQAAAACAAAAAQAAAAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA//8Aev// - AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP/i4gn/R0cw/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv9qair/9vYC////AP///wD///8A////AP///wD///8A////AP///wD///8A//// - AP///wD///8A////AOn//wAqAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP//ACr//wDp//8A////AP///wD///8A//// - AP///wD///8A////AP///wD///8A////AP///wD///8A/5WVIv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/8PD - Ff///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD/7e0AgwAA - AAwAAAAIAAAABQAAAAMAAAABAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAD//wB6//8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A/+Li - Cf9HRzD/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/2pqKv/29gL///8A////AP///wD///8A////AP///wD///8A//// - AP///wD///8A////AP///wD///8A6f//ACoAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP//ACr//wDp//8A////AP///wD///8A//// - AP///wD///8A////AP///wD///8A////AP///wD/9vYC/4eHJf8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/8PD - Ff///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD/3d0AjQAA - ABwAAAAVAAAADgAAAAoAAAAGAAAAAwAAAAEAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAP//AHr//wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A//// - AP///wD/4uIJ/0dHMP8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/amoq//b2Av///wD///8A////AP///wD///8A//// - AP///wD///8A////AP///wD///8A////AP///wDp//8AKgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP//ACr//wDp//8A////AP///wD///8A//// - AP///wD///8A////AP///wD///8A////AP///wD/9vYC/2pqKv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/8PD - Ff///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD/yckAmwAA - ADUAAAArAAAAIAAAABcAAAAQAAAACgAAAAYAAAADAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAA//8Aev//AP///wD///8A////AP///wD///8A////AP///wD///8A//// - AP///wD///8A////AP/i4gn/R0cw/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv9qair/9vYC////AP///wD///8A//// - AP///wD///8A////AP///wD///8A////AP///wD///8A////AOn//wAqAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP//ACr//wDp//8A////AP///wD///8A//// - AP///wD///8A////AP///wD///8A////AP///wD/9vYC/2pqKv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/8PD - Ff///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD/tbUArAAA - AFUAAABJAAAAOwAAAC4AAAAiAAAAGAAAABAAAAAKAAAABQAAAAIAAAABAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD//wB6//8A////AP///wD///8A////AP///wD///8A//// - AP///wD///8A////AP///wD///8A/+LiCf9HRzD/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/2pqKv/29gL///8A//// - AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A6f//ACoAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP//ACr//wDp//8A////AP///wD///8A//// - AP///wD///8A////AP///wD///8A////AP///wD/9vYC/2pqKv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/8PD - Ff///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD/paUAvQAA - AHYAAABqAAAAXQAAAE8AAAA/AAAAMAAAACIAAAAXAAAADgAAAAgAAAAEAAAAAQAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP//AEr//wD///8A////AP///wD///8A//// - AP///wD///8A////AP///wD///8A////AP///wD/4uIJ/0dHMP8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/amoq//b2 - Av///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wDp//8AKgAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP//ACr//wDp//8A////AP///wD///8A//// - AP///wD///8A////AP///wD///8A////AP///wD/9vYC/2pqKv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/8PD - Ff///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD/mpoAygAA - AJQAAACLAAAAfwAAAHEAAABhAAAAUAAAAD8AAAAuAAAAIAAAABUAAAAMAAAABgAAAAMAAAABAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA//8ASv//AP///wD///8A//// - AP///wD///8A////AP///wD///8A////AP///wD///8A////AP/i4gn/R0cw/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv9qair/9vYC////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A//// - AOn//wAqAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP//ACr//wDp//8A////AP///wD///8A//// - AP///wD///8A////AP///wD///8A////AP///wD/9vYC/2pqKv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/8PD - Ff///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD/k5MA1AAA - AKkAAACjAAAAnAAAAJEAAACDAAAAcwAAAGEAAABPAAAAPAAAACsAAAAcAAAAEQAAAAkAAAAEAAAAAQAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD//wBK//8A//// - AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A/+LiCf9HRzD/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/2pqKv/29gL///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A//// - AP///wD///8A6f//ACoAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP//ACr//wDp//8A////AP///wD///8A//// - AP///wD///8A////AP///wD///8A////AP///wD/9vYC/2pqKv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/8PD - Ff///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD/j48A2gAA - ALYAAAC0AAAArwAAAKkAAACgAAAAkwAAAIMAAABxAAAAXQAAAEkAAAA1AAAAJAAAABcAAAANAAAABgAA - AAIAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP// - AEr//wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD/4uIJ/0dH - MP8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/amoq//b2Av///wD///8A////AP///wD///8A////AP///wD///8A//// - AP///wD///8A////AP///wDp//8AKgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP//ACr//wDp//8A////AP///wD///8A//// - AP///wD///8A////AP///wD///8A////AP///wD/9vYC/2pqKv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/8PD - Ff///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD/jY0A3QAA - AL0AAAC8AAAAuwAAALgAAACzAAAAqwAAAKAAAACRAAAAfwAAAGsAAABVAAAAQAAAACwAAAAcAAAAEQAA - AAgAAAADAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAA//8ASv//AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A//// - AP/i4gn/R0cw/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv9qair/9vYC////AP///wD///8A////AP///wD///8A//// - AP///wD///8A////AP///wD///8A////AOn//wAqAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP//ACr//wDp//8A////AP///wD///8A//// - AP///wD///8A////AP///wD///8A////AP///wD/9vYC/2pqKv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/8PD - Ff///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD/jIwA3gAA - AL8AAAC/AAAAvgAAAL4AAAC8AAAAuQAAALMAAACpAAAAnAAAAIsAAAB3AAAAYQAAAEkAAAA0AAAAIgAA - ABUAAAALAAAABAAAAAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAD//wBK//8A////AP///wD///8A////AP///wD///8A////AP///wD///8A//// - AP///wD///8A/+LiCf9HRzD/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/2pqKv/29gL///8A////AP///wD///8A//// - AP///wD///8A////AP///wD///8A////AP///wD///8A6f//ACoAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP//ACr//wDp//8A////AP///wD///8A//// - AP///wD///8A////AP///wD///8A////AP///wD/9vYC/2pqKv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/8PD - Ff///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD/jIwA3gAA - AL8AAAC/AAAAvwAAAL8AAAC/AAAAvgAAALwAAAC4AAAArwAAAKMAAACUAAAAgAAAAGoAAABSAAAAOwAA - ACgAAAAZAAAADQAAAAYAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAP//AEr//wD///8A////AP///wD///8A////AP///wD///8A//// - AP///wD///8A////AP///wD/4uIJ/0dHMP8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/amoq//b2Av///wD///8A//// - AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wDp//8AKgAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP//ACr//wDp//8A////AP///wD///8A//// - AP///wD///8A////AP///wD///8A////AP///wD/9vYC/2pqKv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/8PD - Ff///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD/jIwA3gAA - AL8AAAC/AAAAvwAAAL8AAAC/AAAAvwAAAL8AAAC+AAAAuwAAALQAAACpAAAAmgAAAIgAAAByAAAAWQAA - AEEAAAAtAAAAHAAAABAAAAAHAAAAAgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA//8ASv//AP///wD///8A////AP///wD///8A//// - AP///wD///8A////AP///wD///8A////AP/i4gn/R0cw/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv9qair/9vYC//// - AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AOn//wAqAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP//AAj//wDZ//8A////AP///wD///8A//// - AP///wD///8A////AP///wD///8A////AP///wD/9vYC/2pqKv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/8PD - Ff///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD/jIwA3gAA - AL8AAAC/AAAAvwAAAL8AAAC/AAAAvwAAAL8AAAC/AAAAvgAAALwAAAC2AAAArAAAAJ8AAACNAAAAdwAA - AF8AAABGAAAAMQAAAB8AAAARAAAACAAAAAIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD//wBK//8A////AP///wD///8A//// - AP///wD///8A////AP///wD///8A////AP///wD///8A/+LiCf9HRzD/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/2pq - Kv/29gL///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A6f// - ACoAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD//wCf//8A////AP///wD///8A//// - AP///wD///8A////AP///wD///8A////AP///wD/9vYC/2pqKv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/8PD - Ff///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD/jIwA3gAA - AL8AAAC/AAAAvwAAAL8AAAC/AAAAvwAAAL8AAAC/AAAAvwAAAL8AAAC+AAAAuAAAAK8AAAChAAAAkAAA - AHsAAABiAAAASQAAADMAAAAhAAAAEwAAAAkAAAACAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP//AEr//wD///8A//// - AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD/4uIJ/0dHMP8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/amoq//b2Av///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A//// - AP///wDZ//8ACAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD//wBk//8A////AP///wD///8A//// - AP///wD///8A////AP///wD///8A////AP///wD/9vYC/2pqKv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/8PD - Ff///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD/zexU/Kfo - rP+e3KP6ir+O8WGHZN8aJBvHAAAAvwAAAL8AAAC/AAAAvwAAAL8AAAC/AAAAvgAAALgAAACvAAAAogAA - AJEAAAB8AAAAYwAAAEkAAAA0AAAAIgAAABMAAAAJAAAAAgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA//8ASv// - AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP/i4gn/R0cw/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv9qair/9vYC////AP///wD///8A////AP///wD///8A////AP///wD///8A//// - AP///wD///8A////AJ8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD//wAV//8A5///AP///wD///8A//// - AP///wD///8A////AP///wD///8A////AP///wD/9vYC/2pqKv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/8PD - Ff///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD/0fNa/6fo - rP+n6Kz/p+is/6forP+n6Kz/peWq/muVb+QJDAnCAAAAvwAAAL8AAAC/AAAAvwAAAL4AAAC4AAAArwAA - AKEAAACQAAAAewAAAGIAAABJAAAAMwAAACEAAAATAAAACQAAAAIAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAD//wBK//8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A/+Li - Cf9HRzD/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/2pqKv/29gL///8A////AP///wD///8A////AP///wD///8A//// - AP///wD///8A////AP///wD///8AZAAAAAAAAAAAAAAAAAAAAAAAAAAA//8AlP//AP///wD///8A//// - AP///wD///8A////AP///wD///8A////AP///wD/9vYC/2pqKv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/8PD - Ff///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD/0fNa/6fo - rP+n6Kz/p+is/6forP+n6Kz/p+is/6forP+n6Kz/j8eU9BQcFcUAAAC/AAAAvwAAAL4AAAC8AAAAtgAA - AKwAAACfAAAAjQAAAHcAAABfAAAARgAAADEAAAAfAAAAEgAAAAgAAAACAAAAAAAAAAAAAAAAAAAAAQAA - AAEAAAABAAAAAQAAAAIAAAACAAAAAwAAAAMAAAADAAAABAAAAAQAAAADAAAAAwAAAAMAAAACAAAAAgAA - AAEAAAABAAAAAQAAAAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAP//AEr//wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A//// - AP///wD/4uIJ/0dHMP8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/amoq//b2Av///wD///8A////AP///wD///8A//// - AP///wD///8A////AP///wD///8A////ANf//wAFAAAAAAAAAAAAAAAA//8AH///AP///wD///8A//// - AP///wD///8A////AP///wD///8A////AP///wD/9vYC/2pqKv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/8PD - Ff///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD/0fNa/6fo - rP+n6Kz/p+is/6forP+n6Kz/p+is/6forP+n6Kz/p+is/6forP+Px5TzCQwJwgAAAL8AAAC+AAAAuwAA - ALQAAACpAAAAmgAAAIgAAAByAAAAWgAAAEEAAAAtAAAAHAAAABAAAAAHAAAAAwAAAAEAAAABAAAAAgAA - AAQAAAAEAAAABQAAAAcAAAAHAAAACQAAAAoAAAAKAAAACgAAAAoAAAAKAAAACgAAAAoAAAAKAAAACQAA - AAcAAAAHAAAABQAAAAQAAAAEAAAAAgAAAAEAAAABAAAAAQAAAAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAA//8ASv//AP///wD///8A////AP///wD///8A////AP///wD///8A//// - AP///wD///8A////AP/i4gn/R0cw/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv9qair/9vYC////AP///wD///8A//// - AP///wD///8A////AP///wD///8A////AP///wD///8AhAAAAAAAAAAAAAAAAP//AG///wD///8A//// - AP///wD///8A////AP///wD///8A////AP///wD/9vYC/2pqKv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/8PD - Ff///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD/0fNa/6fo - rP+n6Kz/p+is/6forP+n6Kz/p+is/6forP+n6Kz/p+is/6forP+n6Kz/p+is/26ZceUAAAC+AAAAvAAA - ALgAAACvAAAAowAAAJQAAACBAAAAagAAAFIAAAA7AAAAKAAAABkAAAAPAAAACAAAAAQAAAAEAAAABgAA - AAgAAAAKAAAADAAAAA0AAAAQAAAAEQAAABMAAAAUAAAAFQAAABYAAAAWAAAAFgAAABYAAAAVAAAAFAAA - ABMAAAARAAAAEAAAAA0AAAAMAAAACgAAAAgAAAAGAAAABAAAAAMAAAACAAAAAQAAAAEAAAABAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD//wBK//8A////AP///wD///8A////AP///wD///8A//// - AP///wD///8A////AP///wD///8A/+LiCf9HRzD/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/2pqKv/29gL///8A//// - AP///wD///8A////AP///wD///8A////AP///wD///8A////AO4AAAAAAAAAAAAAAAD//wDO//8A//// - AP///wD///8A////AP///wD///8A////AP///wD///8A/3l5KP8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/8PD - Ff///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD/0fNa/6fo - rP+n6Kz/p+is/6forP+n6Kz/p+is/6forP+n6Kz/p+is/6forP+n6Kz/p+is/6forP+m5qv+HysgxQAA - ALkAAACzAAAAqQAAAJwAAACLAAAAdwAAAGEAAABKAAAANQAAACUAAAAYAAAAEAAAAAsAAAAKAAAADAAA - AA4AAAARAAAAFAAAABcAAAAaAAAAHAAAAB8AAAAhAAAAIgAAACQAAAAlAAAAJQAAACUAAAAlAAAAJAAA - ACIAAAAhAAAAHwAAABwAAAAaAAAAFwAAABQAAAARAAAADgAAAAsAAAAJAAAABwAAAAQAAAADAAAAAgAA - AAEAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP//AEr//wD///8A////AP///wD///8A//// - AP///wD///8A////AP///wD///8A////AP///wD/4uIJ/0dHMP8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/amoq//b2 - Av///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8APwAAAAD//wAP//8A//// - AP///wD///8A////AP///wD///8A////AP///wD///8A/7i4Gf8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/8PD - Ff///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD/0fNa/6fo - rP+n6Kz/p+is/6forP+n6Kz/p+is/6forP+n6Kz/p+is/6forP+n6Kz/p+is/6forP+n6Kz/p+is/2aN - ad0AAACzAAAAqwAAAKAAAACRAAAAfwAAAGwAAABWAAAAQgAAADAAAAAiAAAAGQAAABQAAAASAAAAEwAA - ABYAAAAaAAAAHwAAACIAAAAmAAAAKgAAAC4AAAAwAAAAMwAAADUAAAA3AAAANwAAADgAAAA4AAAANwAA - ADcAAAA1AAAAMwAAADAAAAAtAAAAKgAAACYAAAAiAAAAHwAAABoAAAAWAAAAEwAAAA8AAAALAAAACAAA - AAYAAAAEAAAAAgAAAAEAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA//8ASv//AP///wD///8A//// - AP///wD///8A////AP///wD///8A////AP///wD///8A////AP/i4gn/R0cw/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv95eSj///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AI4AAAAA//8AT/// - AP///wD///8A////AP///wD///8A////AP///wD///8A//b2Av9HRzD/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/8PD - Ff///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD/0fNa/6fo - rP+n6Kz/p+is/6forP+n6Kz/p+is/6forP+n6Kz/p+is/6forP+n6Kz/p+is/6forP+n6Kz/p+is/6fo - rP+NxJHuAAAAqQAAAKAAAACTAAAAhAAAAHMAAABgAAAATQAAADsAAAAuAAAAJAAAAB4AAAAcAAAAHAAA - ACAAAAAlAAAAKwAAADAAAAA0AAAAOgAAAD4AAABCAAAARgAAAEkAAABLAAAATQAAAE8AAABPAAAATwAA - AE8AAABNAAAASwAAAEkAAABGAAAAQgAAAD4AAAA6AAAANAAAAC8AAAArAAAAJQAAAB8AAAAaAAAAFgAA - ABEAAAANAAAACgAAAAcAAAAEAAAAAgAAAAEAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAD//wBK//8A//// - AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A/+LiCf9HRzD/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/8PDFf///wD///8A////AP///wD///8A////AP///wD///8A////AP///wDOAAAAAP// - AIv//wD///8A////AP///wD///8A////AP///wD///8A////AP/DwxX/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/8PD - Ff///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD/0vNX+afo - rP+n6Kz/p+is/6forP+n6Kz/p+is/6forP+n6Kz/p+is/6forP+n6Kz/p+is/6forP+n6Kz/p+is/6fo - rP+n6Kz/ouGn+wAAAJwAAACRAAAAhQAAAHYAAABlAAAAVQAAAEUAAAA4AAAALgAAACgAAAAnAAAAKAAA - ACsAAAAxAAAANwAAAD4AAABFAAAASwAAAFEAAABWAAAAWwAAAF8AAABiAAAAZQAAAGcAAABpAAAAagAA - AGoAAABpAAAAZwAAAGUAAABiAAAAXgAAAFsAAABVAAAAUAAAAEsAAABEAAAAPgAAADcAAAAxAAAAKgAA - ACQAAAAdAAAAFwAAABIAAAANAAAACgAAAAYAAAAEAAAAAgAAAAEAAAABAAAAAAAAAAAAAAAAAAAAAP// - AEr//wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD/4uIJ/0dH - MP8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv9aWi3///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A//// - AAv//wDH//8A////AP///wD///8A////AP///wD///8A////AP///wD/eXko/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/8PD - Ff///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD/+fkAfafo - rP+n6Kz/p+is/6forP+n6Kz/p+is/6forP+n6Kz/p+is/6forP+n6Kz/p+is/6forP+n6Kz/p+is/6fo - rP+n6Kz/p+is/6forP8AAACLAAAAgQAAAHQAAABnAAAAWQAAAEwAAABAAAAAOAAAADQAAAAyAAAANAAA - ADgAAAA/AAAARgAAAE4AAABVAAAAXQAAAGQAAABqAAAAbwAAAHQAAAB4AAAAewAAAH4AAACAAAAAgQAA - AIIAAACCAAAAgQAAAIAAAAB+AAAAewAAAHgAAAB0AAAAbwAAAGoAAABkAAAAXQAAAFUAAABOAAAARgAA - AD4AAAA2AAAALgAAACUAAAAfAAAAGAAAABIAAAANAAAACQAAAAUAAAADAAAAAQAAAAEAAAAAAAAAAAAA - AAAAAAAA//8ASv//AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A//// - AP/i4gn/R0cw/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/+LiCf///wD///8A////AP///wD///8A////AP///wD///8A//// - AP///wBH//8A////AP///wD///8A////AP///wD///8A////AP///wD///8A/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/8PD - Ff///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD//f0AewAA - AASn6Kzyp+is/6forP+n6Kz/p+is/6forP+n6Kz/p+is/6forP+n6Kz/p+is/6forP+n6Kz/p+is/6fo - rP+n6Kz/p+is/6forP+j46j6AAAAeQAAAG8AAABkAAAAWgAAAE8AAABGAAAAQAAAAD0AAAA9AAAAQAAA - AEYAAABMAAAAVQAAAF4AAABmAAAAbgAAAHYAAAB8AAAAgQAAAIYAAACKAAAAjgAAAJEAAACSAAAAlAAA - AJUAAACWAAAAlgAAAJUAAACUAAAAkgAAAJAAAACOAAAAigAAAIYAAACBAAAAfAAAAHUAAABuAAAAZgAA - AF4AAABVAAAASwAAAEEAAAA4AAAALgAAACUAAAAeAAAAFgAAABAAAAALAAAABwAAAAQAAAACAAAAAQAA - AAEAAAAAAAAAAAAAAAD//wBK//8A////AP///wD///8A////AP///wD///8A////AP///wD///8A//// - AP///wD///8A/+LiCf9aWi3/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv+trRz///8A////AP///wD///8A////AP///wD///8A//// - AP///wD///8AhP//AP///wD///8A////AP///wD///8A////AP///wD///8A/9jYDv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/8PD - Ff///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8AegAA - AAEAAAACpueryqforP+n6Kz/p+is/6forP+n6Kz/p+is/6forP+n6Kz/p+is/6forP+n6Kz/p+is/6fo - rP+n6Kz/p+is/6forP+n6Kz/l9Gb4QAAAGYAAABeAAAAVgAAAE8AAABJAAAARgAAAEUAAABHAAAATAAA - AFIAAABbAAAAYwAAAG0AAAB2AAAAfQAAAIUAAACLAAAAkQAAAJUAAACZAAAAnQAAAJ8AAAChAAAAowAA - AKUAAACmAAAApgAAAKYAAACmAAAApAAAAKMAAAChAAAAnwAAAJ0AAACZAAAAlQAAAJEAAACLAAAAhQAA - AH0AAAB1AAAAbAAAAGIAAABYAAAATQAAAEMAAAA3AAAALQAAACQAAAAbAAAAEwAAAA0AAAAJAAAABQAA - AAMAAAABAAAAAQAAAAAAAAAAAAAAAP//AEr//wD///8A////AP///wD///8A////AP///wD///8A//// - AP///wD///8A////AP///wD/9vYC/2pqKv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/eXko////AP///wD///8A////AP///wD///8A//// - AP///wD///8A////AMD//wD///8A////AP///wD///8A////AP///wD///8A////AP/Y2A7/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/8PD - Ff///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8AegAA - AAAAAAAAAAAAAabmq4Sn6Kz/p+is/6forP+n6Kz/p+is/6forP+n6Kz/p+is/6forP+n6Kz/p+is/6fo - rP+n6Kz/p+is/6forP+n6Kz/p+is/3+xg7AAAABUAAAATwAAAEwAAABKAAAASQAAAEwAAABPAAAAVgAA - AF4AAABnAAAAcAAAAHkAAACCAAAAiwAAAJEAAACYAAAAnQAAAKEAAAClAAAAqQAAAKsAAACtAAAArwAA - ALAAAACxAAAAsgAAALIAAACyAAAAsgAAALEAAACwAAAArwAAAK0AAACrAAAAqAAAAKUAAAChAAAAnQAA - AJcAAACRAAAAiwAAAIIAAAB5AAAAbwAAAGQAAABYAAAATAAAAEAAAAA0AAAAKQAAAB8AAAAXAAAAEAAA - AAoAAAAGAAAABAAAAAEAAAABAAAAAAAAAAAAAAAA//8ASv//AP///wD///8A////AP///wD///8A//// - AP///wD///8A////AP///wD///8A////AP/29gL/amoq/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/3l5KP///wD///8A////AP///wD///8A//// - AP///wD///8A////AP///wDA//8A////AP///wD///8A////AP///wD///8A////AP///wD/2NgO/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/8PD - Ff///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8AegAA - AAAAAAAAAAAAAAAAAAGi4qcjp+is+6forP+n6Kz/p+is/6forP+n6Kz/p+is/6forP+n6Kz/p+is/6fo - rP+n6Kz/p+is/6forP+n6Kz/p+is/6bnq/0/V0FgAAAARgAAAEYAAABHAAAASwAAAE8AAABWAAAAXgAA - AGgAAAByAAAAfAAAAIUAAACOAAAAlgAAAJ0AAACiAAAApwAAAKsAAACvAAAAsQAAALQAAAC1AAAAtwAA - ALgAAAC5AAAAugAAALoAAAC7AAAAuwAAALoAAAC6AAAAuQAAALgAAAC3AAAAtQAAALMAAACxAAAArwAA - AKsAAACnAAAAogAAAJ0AAACWAAAAjgAAAIUAAAB6AAAAbwAAAGIAAABVAAAASAAAADsAAAAuAAAAIwAA - ABkAAAASAAAADAAAAAcAAAAEAAAAAgAAAAEAAAAAAAAAAAAAAAD//wBK//8A////AP///wD///8A//// - AP///wD///8A////AP///wD///8A////AP///wD///8A//b2Av9qair/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv95eSj///8A////AP///wD///8A//// - AP///wD///8A////AP///wD///8AwP//AP///wD///8A////AP///wD///8A////AP///wD///8A/9jY - Dv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/8PD - Ff///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8AegAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAaforJGn6Kz/p+is/6forP+n6Kz/p+is/6forP+n6Kz/p+is/6fo - rP+n6Kz/p+is/6forP+n6Kz/p+is/6forP+RyZWtAAAAOwAAAD8AAABDAAAASgAAAFIAAABbAAAAZQAA - AHAAAAB6AAAAhQAAAI4AAACXAAAAnwAAAKUAAACqAAAArwAAALIAAAC1AAAAuAAAALkAAAC7AAAAvAAA - AL0AAAC+AAAAvgAAAL4AAAC+AAAAvgAAAL4AAAC+AAAAvgAAAL4AAAC+AAAAvQAAALwAAAC7AAAAuQAA - ALgAAAC1AAAAsgAAAK8AAACqAAAApQAAAJ8AAACXAAAAjgAAAIQAAAB4AAAAagAAAF0AAABPAAAAQAAA - ADMAAAAnAAAAHAAAABMAAAANAAAABwAAAAQAAAACAAAAAQAAAAAAAAAAAAAAAP//AEr//wD///8A//// - AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD/9vYC/2pqKv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/eXko////AP///wD///8A//// - AP///wD///8A////AP///wD///8A////AMD//wD///8A////AP///wD///8A////AP///wD///8A//// - AP/Y2A7/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/8PD - Ff///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8AegAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACY05wLp+is0aforP+n6Kz/p+is/6forP+n6Kz/p+is/6fo - rP+n6Kz/p+is/6forP+n6Kz/p+is/6forP+h4KbaHSkeOQAAADcAAAA+AAAARwAAAFIAAABeAAAAagAA - AHYAAACCAAAAjAAAAJYAAACfAAAApgAAAKwAAACxAAAAtQAAALgAAAC6AAAAuwAAAL0AAAC+AAAAvgAA - AL4AAAC/AAAAvwAAAL8AAAC/AAAAvwAAAL8AAAC/AAAAvwAAAL8AAAC/AAAAvwAAAL8AAAC+AAAAvgAA - AL4AAAC9AAAAuwAAALoAAAC4AAAAtQAAALEAAACsAAAApgAAAJ8AAACWAAAAiwAAAH8AAAByAAAAZAAA - AFUAAABFAAAANwAAACkAAAAeAAAAFAAAAA0AAAAHAAAABAAAAAIAAAABAAAAAAAAAAAAAAAA//8ASv// - AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP/29gL/amoq/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/3l5KP///wD///8A//// - AP///wD///8A////AP///wD///8A////AP///wDA//8A////AP///wD///8A////AP///wD///8A//// - AP///wD/2NgO/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/8PD - Ff///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8AegAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAKforBen6KzRp+is/6forP+n6Kz/p+is/6fo - rP+n6Kz/p+is/6forP+n6Kz/p+is/6forP+i4qfYRWBHOgAAAC4AAAA5AAAARAAAAFEAAABfAAAAbQAA - AHoAAACHAAAAkgAAAJ0AAAClAAAArAAAALEAAAC1AAAAuAAAALsAAAC8AAAAvgAAAL4AAAC+AAAAvwAA - AL8AAAC/AAAAvwAAAL8AAAC/AAAAvwAAAL8AAAC/AAAAvwAAAL8AAAC/AAAAvwAAAL8AAAC/AAAAvwAA - AL8AAAC/AAAAvgAAAL4AAAC+AAAAvAAAALsAAAC4AAAAtQAAALEAAACsAAAApQAAAJwAAACSAAAAhQAA - AHgAAABpAAAAWAAAAEkAAAA5AAAAKwAAAB8AAAAVAAAADQAAAAcAAAAEAAAAAgAAAAEAAAAAAAAAAAAA - AAD//wBK//8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A//b2 - Av9qair/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv95eSj///8A//// - AP///wD///8A////AP///wD///8A////AP///wD///8AwP//AP///wD///8A////AP///wD///8A//// - AP///wD///8A/9jYDv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/8PD - Ff///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8AegAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAp+isCqforJKn6Kz7p+is/6fo - rP+n6Kz/p+is/6forP+n6Kz/p+is/6forPud2qKaKzssJwAAACgAAAAzAAAAQAAAAE8AAABfAAAAbwAA - AH0AAACLAAAAlwAAAKEAAACpAAAAsAAAALUAAAC4AAAAuwAAAL0AAAC+AAAAvgAAAL8AAAC/AAAAvwAA - AL8AAAC/AAAAvwAAAL8AAAC/AAAAvwAAAL8AAAC/AAAAvwAAAL8AAAC/AAAAvwAAAL8AAAC/AAAAvwAA - AL8AAAC/AAAAvwAAAL8AAAC/AAAAvwAAAL4AAAC+AAAAvQAAALsAAAC4AAAAtQAAALAAAACpAAAAoQAA - AJcAAACLAAAAfAAAAG0AAABbAAAASwAAADoAAAAsAAAAHwAAABUAAAANAAAABwAAAAQAAAABAAAAAQAA - AAAAAAAAAAAAAP//AEr//wD5//8A////AP///wD///8A////AP///wD///8A////AP///wD///8A//// - AP///wD/9vYC/2pqKv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/eXko//// - AP///wD///8A////AP///wD///8A////AP///wD///8A////AMD//wD///8A////AP///wD///8A//// - AP///wD///8A////AP/Y2A7/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/8PD - Ff///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8AegAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAp+isIKfo - rIKn6KzHp+is7qforP+n6KzvpueryqDfpYZ5p3wvAAAAFwAAACIAAAAuAAAAPQAAAE4AAABeAAAAcAAA - AH8AAACOAAAAmgAAAKUAAACsAAAAswAAALcAAAC7AAAAvAAAAL4AAAC+AAAAvwAAAL8AAAC/AAAAvwAA - AL8AAAC/AAAAvwAAAL8AAAC/AAAAvwAAAL8AAAC/AAAAvwAAAL8AAAC/AAAAvwAAAL8AAAC/AAAAvwAA - AL8AAAC/AAAAvwAAAL8AAAC/AAAAvwAAAL8AAAC/AAAAvwAAAL4AAAC+AAAAvAAAALsAAAC4AAAAswAA - AKwAAAClAAAAmgAAAI4AAAB/AAAAbwAAAF4AAABMAAAAOwAAACwAAAAfAAAAFAAAAA0AAAAHAAAABAAA - AAEAAAABAAAAAAAAAAAAAAAA//8AKv//AOn//wD///8A////AP///wD///8A////AP///wD///8A//// - AP///wD///8A////AP/29gL/amoq/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/3l5 - KP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wDA//8A////AP///wD///8A//// - AP///wD///8A////AP///wD/2NgO/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/8PD - Ff///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8AegAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAABAAAAAwAAAAYAAAAMAAAAEwAAAB4AAAArAAAAOwAAAEwAAABeAAAAcAAA - AIEAAACQAAAAnQAAAKcAAACvAAAAtQAAALkAAAC7AAAAvgAAAL4AAAC/AAAAvwAAAL8AAAC/AAAAvwAA - AL8AAAC/AAAAvwAAAL8AAAC/AAAAvwAAAL8AAAC/AAAAvwAAAL8AAAC/AAAAvwAAAL8AAAC/AAAAvwAA - AL8AAAC/AAAAvwAAAL8AAAC/AAAAvwAAAL8AAAC/AAAAvwAAAL8AAAC/AAAAvwAAAL4AAAC+AAAAuwAA - ALkAAAC1AAAArwAAAKcAAACdAAAAkAAAAIEAAABwAAAAXgAAAEwAAAA6AAAAKwAAAB4AAAATAAAACwAA - AAYAAAADAAAAAQAAAAAAAAAAAAAAAAAAAAD//wAq//8A6f//AP///wD///8A////AP///wD///8A//// - AP///wD///8A////AP///wD///8A//b2Av9qair/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv95eSj///8A////AP///wD///8A////AP///wD///8A////AP///wD///8AwP//AP///wD///8A//// - AP///wD///8A////AP///wD///8A/9jYDv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/8PD - Ff///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8AegAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAABAAAAAgAAAAUAAAAKAAAAEgAAABwAAAAqAAAAOgAAAEsAAABeAAAAcAAA - AIIAAACRAAAAngAAAKkAAACxAAAAtgAAALoAAAC8AAAAvgAAAL4AAAC/AAAAvwAAAL8FBwXBKzsszE5s - UNhtl3Dkf7GD7I/HlPSd2aH6oN6l+6forP+n6Kz/oeCm/JvYoPmPx5T0gLKE7GqTbeNQb1LYKTgqygMF - A78AAAC/AAAAvwAAAL8AAAC/AAAAvwAAAL8AAAC/AAAAvwAAAL8AAAC/AAAAvwAAAL8AAAC/AAAAvgAA - AL4AAAC8AAAAugAAALYAAACxAAAAqQAAAJ4AAACRAAAAggAAAHAAAABeAAAASwAAADkAAAApAAAAHAAA - ABIAAAAKAAAABQAAAAIAAAABAAAAAAAAAAAAAAAAAAAAAP//ACr//wDp//8A////AP///wD///8A//// - AP///wD///8A////AP///wD///8A////AP///wD/9vYC/2pqKv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/eXko////AP///wD///8A////AP///wD///8A////AP///wD///8A////AMD//wD///8A//// - AP///wD///8A////AP///wD///8A////AP/Y2A7/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/8PD - Ff///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8AegAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAABAAAAAQAAAAQAAAAJAAAAEAAAABoAAAAnAAAANwAAAEkAAABcAAAAbwAA - AIEAAACRAAAAnwAAAKkAAACyAAAAtwAAALsAAAC9AAAAvgAAAL8AAAC/GCEYxlV2WNuAsoTtouGn/Kfo - rP+n6Kz/p+is/6forP+n6Kz/p+is/6forP+n6Kz/p+is/6forP+n6Kz/p+is/6forP+n6Kz/p+is/6fo - rP+i4af8gLKE7FR0VtgXIBjEAAAAvgAAAL4AAAC+AAAAvwAAAL8AAAC/AAAAvwAAAL8AAAC/AAAAvwAA - AL8AAAC/AAAAvgAAAL0AAAC7AAAAtwAAALIAAACpAAAAnwAAAJEAAACBAAAAbwAAAFsAAABJAAAANwAA - ACcAAAAZAAAAEAAAAAkAAAAEAAAAAQAAAAEAAAAAAAAAAAAAAAAAAAAA//8AKv//AOn//wD///8A//// - AP///wD///8A////AP///wD///8A////AP///wD///8A////AP/29gL/amoq/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/3l5KP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wDA//8A//// - AP///wD///8A////AP///wD///8A////AP///wD/2NgO/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/8PD - Ff///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8AegAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAQAAAAMAAAAHAAAADQAAABcAAAAjAAAAMwAAAEYAAABZAAAAbQAA - AH8AAACQAAAAngAAAKkAAACyAAAAuAAAALsAAAC9AAAAvgYIBsFJZUvXh7uL8Kbnq/6n6Kz/p+is/6fo - rP+n6Kz/p+is/6forP+n6Kz/p+is/6forP+n6Kz/p+is/6forP+n6Kz/p+is/6forP+n6Kz/p+is/6fo - rP+n6Kz/p+is/6forP+n6Kz/puer/oe7i+5JZUvUBggGvwAAAL4AAAC+AAAAvgAAAL8AAAC/AAAAvwAA - AL8AAAC/AAAAvwAAAL8AAAC+AAAAvQAAALsAAAC4AAAAsgAAAKkAAACeAAAAkAAAAH8AAABsAAAAWAAA - AEUAAAAzAAAAIwAAABYAAAANAAAABwAAAAMAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAD//wAq//8A6f// - AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A//b2Av9qair/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv95eSj///8A////AP///wD///8A////AP///wD///8A////AP///wD///8AwP// - AP///wD///8A////AP///wD///8A////AP///wD///8A/9jYDv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/8PD - Ff///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8AegAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAQAAAAIAAAAFAAAACwAAABMAAAAfAAAALgAAAEAAAABVAAAAaQAA - AHwAAACOAAAAnQAAAKkAAACyAAAAuAAAALsAAAC9DBAMwl6DYd+c2aH5p+is/6forP+n6Kz/p+is/6fo - rP+n6Kz/p+is/6forP+n6Kz/p+is/6forP+n6Kz/p+is/6forP+n6Kz/p+is/6forP+n6Kz/p+is/6fo - rP+n6Kz/p+is/6forP+n6Kz/p+is/6forP+n6Kz/p+is/53aovldgWDbDRINwAAAAL0AAAC+AAAAvgAA - AL8AAAC/AAAAvwAAAL8AAAC/AAAAvwAAAL4AAAC9AAAAuwAAALgAAACyAAAAqQAAAJ0AAACOAAAAfAAA - AGgAAABUAAAAQAAAAC4AAAAfAAAAEwAAAAsAAAAFAAAAAgAAAAEAAAAAAAAAAAAAAAAAAAAAAAAAAP// - ACr//wDp//8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD/9vYC/2pq - Kv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/eXko////AP///wD///8A////AP///wD///8A////AP///wD///8A//// - AMD//wD///8A////AP///wD///8A////AP///wD///8A////AP/Y2A7/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/8PD - Ff///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8AegAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEAAAAEAAAACQAAABAAAAAbAAAAKQAAADsAAABPAAAAZAAA - AHgAAACLAAAAmgAAAKcAAACxAAAAtwAAALsFBwW/WHpa253aovqn6Kz/p+is/6forP+n6Kz/p+is/6fo - rP+n6Kz/p+is/6forP+n6Kz/p+is/6forP+n6Kz/p+is/6forP+n6Kz/p+is/6forP+n6Kz/p+is/6fo - rP+n6Kz/p+is/6forP+n6Kz/p+is/6forP+n6Kz/p+is/6forP+n6Kz/p+is/5/dpPtYe1vZBQcFvgAA - AL4AAAC+AAAAvwAAAL8AAAC/AAAAvwAAAL8AAAC/AAAAvgAAAL0AAAC7AAAAtwAAALAAAACnAAAAmgAA - AIoAAAB3AAAAYwAAAE4AAAA6AAAAKQAAABsAAAAQAAAACAAAAAQAAAABAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAA//8AKv//AOn//wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A//// - AP/29gL/amoq/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/3l5KP///wD///8A////AP///wD///8A////AP///wD///8A//// - AP///wDA//8A////AP///wD///8A////AP///wD///8A////AP///wD/2NgO/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/8PD - Ff///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8AegAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEAAAACAAAABgAAAA0AAAAWAAAAJAAAADQAAABIAAAAXQAA - AHIAAACFAAAAlwAAAKUAAACvAAAAtgAAALsyRTPNk8yX9aforP+n6Kz/p+is/6forP+n6Kz/p+is/6fo - rP+n6Kz/p+is/6forP+n6Kz/p+is/6forP+n6Kz/p+is/6forP+n6Kz/p+is/6forP+n6Kz/p+is/6fo - rP+n6Kz/p+is/6forP+n6Kz/p+is/6forP+n6Kz/p+is/6forP+n6Kz/p+is/6forP+n6Kz/p+is/5XP - mfQ0STbMAAAAvQAAAL4AAAC+AAAAvwAAAL8AAAC/AAAAvwAAAL8AAAC+AAAAvQAAALsAAAC2AAAArwAA - AKQAAACXAAAAhQAAAHIAAABcAAAARwAAADQAAAAjAAAAFgAAAA0AAAAGAAAAAgAAAAEAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAD//wAq//8A6f//AP///wD///8A////AP///wD///8A////AP///wD///8A//// - AP///wD///8A//b2Av9qair/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv95eSj///8A////AP///wD///8A////AP///wD///8A//// - AP///wD///8AwP//AP///wD///8A////AP///wD///8A////AP///wD///8A/9jYDv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/8PD - Ff///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8AegAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABAAAABAAAAAoAAAASAAAAHgAAAC0AAABAAAAAVQAA - AGsAAAB/AAAAkgAAAKEAAACtAAAAtQcKB7xtmHHkpuer/6forP+n6Kz/p+is/6forP+n6Kz/p+is/6fo - rP+n6Kz/p+is/6forP+n6Kz/p+is/6forP+n6Kz/p+is/6forP+n6Kz/p+is/6forP+n6Kz/p+is/6fo - rP+n6Kz/p+is/6forP+n6Kz/p+is/6forP+n6Kz/p+is/6forP+n6Kz/p+is/6forP+n6Kz/p+is/6fo - rP+n6Kz/puer/2+acuMICwi+AAAAvgAAAL4AAAC/AAAAvwAAAL8AAAC/AAAAvwAAAL4AAAC9AAAAugAA - ALUAAACsAAAAoQAAAJEAAAB/AAAAagAAAFUAAABAAAAALQAAAB0AAAASAAAACgAAAAQAAAABAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAP//ACr//wDp//8A////AP///wD///8A////AP///wD///8A//// - AP///wD///8A////AP///wD/9vYC/2pqKv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/eXko////AP///wD///8A////AP///wD///8A//// - AP///wD///8A////AMD//wD///8A////AP///wD///8A////AP///wD///8A////AP/Y2A7/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8AegAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABAAAAAgAAAAcAAAANAAAAGAAAACUAAAA3AAAATAAA - AGIAAAB4AAAAiwAAAJwAAACpAAAAsyEuIsSRyZXzp+is/6forP+n6Kz/p+is/6forP+n6Kz/p+is/6fo - rP+n6Kz/p+is/6forP+n6Kz/p+is/6forP+n6Kz/p+is/6forP+n6Kz/p+is/6forP+n6Kz/p+is/6fo - rP+n6Kz/p+is/6forP+n6Kz/p+is/6forP+n6Kz/p+is/6forP+n6Kz/p+is/6forP+n6Kz/p+is/6fo - rP+n6Kz/p+is/6forP+n6Kz/kcmV8yEtIsYAAAC+AAAAvgAAAL8AAAC/AAAAvwAAAL8AAAC/AAAAvgAA - ALwAAAC5AAAAsgAAAKkAAACcAAAAiwAAAHcAAABiAAAATAAAADcAAAAlAAAAFwAAAA0AAAAHAAAAAgAA - AAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA//8AKv//AOn//wD///8A////AP///wD///8A//// - AP///wD///8A////AP///wD///8A////AP+trRz/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/3l5KP///wD///8A////AP///wD///8A//// - AP///wD///8A////AP///wDA//8A////AP///wD///8A////AP///wD///8A////AP///wD/2NgO/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8AegAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQAAAAQAAAAKAAAAEgAAAB8AAAAuAAAAQwAA - AFgAAABvAAAAhAAAAJYAAAClAAAAsDpQO8ug3qX7p+is/6forP+n6Kz/p+is/6forP+n6Kz/p+is/6fo - rP+n6Kz/p+is/6forP+n6Kz/p+is/6forP+n6Kz/p+is/6forP+n6Kz/p+is/6forP+n6Kz/p+is/6fo - rP+n6Kz/p+is/6forP+n6Kz/p+is/6forP+n6Kz/p+is/6forP+n6Kz/p+is/6forP+n6Kz/p+is/6fo - rP+n6Kz/p+is/6forP+n6Kz/p+is/6forP+f3aT7OU87zwAAAL4AAAC+AAAAvwAAAL8AAAC/AAAAvwAA - AL8AAAC+AAAAuwAAALcAAACvAAAApQAAAJYAAACDAAAAbgAAAFgAAABCAAAALgAAAB4AAAASAAAACQAA - AAQAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD//wAq//8A6f//AP///wD///8A//// - AP///wD///8A////AP///wD///8A////AP///wD/ra0c/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv95eSj///8A////AP///wD///8A//// - AP///wD///8A////AP///wD///8AwP//AP///wD///8A////AP///wD///8A////AP///wD///8A/9jY - Dv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8AegAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQAAAAIAAAAGAAAADQAAABcAAAAlAAAAOAAA - AE0AAABkAAAAegAAAI4AAACfAAAArEtoTdCm5qv+p+is/6forP+n6Kz/p+is/6forP+n6Kz/p+is/6fo - rP+n6Kz/p+is/6forP+n6Kz/p+is/6forP+n6Kz/p+is/6forP+n6Kz/p+is/6forP+n6Kz/p+is/6fo - rP+n6Kz/p+is/6forP+n6Kz/p+is/6forP+n6Kz/p+is/6forP+n6Kz/p+is/6forP+n6Kz/p+is/6fo - rP+n6Kz/p+is/6forP+n6Kz/p+is/6forP+n6Kz/p+is/6Xlqv5HY0rUAAAAvgAAAL4AAAC/AAAAvwAA - AL8AAAC/AAAAvgAAAL0AAAC7AAAAtQAAAKwAAACeAAAAjgAAAHoAAABkAAAATQAAADcAAAAlAAAAFwAA - AA0AAAAGAAAAAgAAAAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP//ACr//wDp//8A//// - AP///wD///8A////AP///wD///8A////AP///wD///8A/62tHP8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/eXko////AP///wD///8A//// - AP///wD///8A////AP///wD///8A////AMD//wD///8A////AP///wD///8A////AP///wD///8A//// - AP/Y2A7/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8AegAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEAAAADAAAACAAAABEAAAAdAAAALgAA - AEEAAABYAAAAbwAAAIUAAACXAAAAplR0VtGm56v/p+is/6forP+n6Kz/p+is/6forP+n6Kz/p+is/6fo - rP+n6Kz/p+is/6forP+n6Kz/p+is/6forP+n6Kz/p+is/6forP+n6Kz/p+is/6forP+n6Kz/p+is/6fo - rP+n6Kz/p+is/6forP+n6Kz/p+is/6forP+n6Kz/p+is/6forP+n6Kz/p+is/6forP+n6Kz/p+is/6fo - rP+n6Kz/p+is/6forP+n6Kz/p+is/6forP+n6Kz/p+is/6forP+n6Kz/puer/09tUdcAAAC+AAAAvwAA - AL8AAAC/AAAAvwAAAL8AAAC+AAAAvAAAALgAAACxAAAApgAAAJcAAACEAAAAbwAAAFgAAABBAAAALQAA - AB0AAAARAAAACAAAAAMAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA//8AKv// - AOn//wD///8A////AP///wD///8A////AP///wD///8A////AP+trRz/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/3l5KP///wD///8A//// - AP///wD///8A////AP///wD///8A////AP///wDA//8A////AP///wD///8A////AP///wD///8A//// - AP///wD/2NgO/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A//// - AAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABAAAABAAAAAsAAAAWAAAAJAAA - ADYAAABLAAAAYgAAAHkAAACOAAAAn01rUMum56v/p+is/6forP+n6Kz/p+is/6forP+n6Kz/p+is/6fo - rP+n6Kz/p+is/6forP+n6Kz/p+is/6forP+n6Kz/p+is/6forP+n6Kz/p+is/6forP+n6Kz/p+is/6fo - rP+n6Kz/p+is/6forP+n6Kz/p+is/6forP+n6Kz/p+is/6forP+n6Kz/p+is/6forP+n6Kz/p+is/6fo - rP+n6Kz/p+is/6forP+n6Kz/p+is/6forP+n6Kz/p+is/6forP+n6Kz/p+is/6forP+m56v+R2NK1QAA - AL4AAAC/AAAAvwAAAL8AAAC/AAAAvwAAAL4AAAC7AAAAtQAAAKwAAACfAAAAjgAAAHkAAABiAAAASwAA - ADUAAAAjAAAAFgAAAAsAAAAEAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAD//wCA//8A////AP///wD///8A////AP///wD///8A////AP///wD/ra0c/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv95eSj///8A//// - AP///wD///8A////AP///wD///8A////AP///wD///8AwP//AP///wD///8A////AP///wD///8A//// - AP///wD///8A/9jYDv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy////AP///wD///8A////AP///wD///8A////AP///wD///8A//// - AP///wABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABAAAAAgAAAAcAAAAPAAAAGgAA - ACoAAAA9AAAAVQAAAGwAAACCAAAAlkBYQb+m5qv+p+is/6forP+n6Kz/p+is/6forP+n6Kz/p+is/6fo - rP+n6Kz/p+is/6forP+n6Kz/p+is/6forP+n6Kz/p+is/6forP+n6Kz/p+is/6forP+n6Kz/p+is/5nU - nfeGuorte6t/5nShd913pXrXgrSG15DIlNyg3qXvp+is/6forP+n6Kz/p+is/6forP+n6Kz/p+is/6fo - rP+n6Kz/p+is/6forP+n6Kz/p+is/6forP+n6Kz/p+is/6forP+n6Kz/p+is/6forP+n6Kz/p+is/6Xl - qv41SjfPAAAAvgAAAL8AAAC/AAAAvwAAAL8AAAC+AAAAvQAAALgAAACxAAAApQAAAJUAAACCAAAAbAAA - AFQAAAA9AAAAKgAAABoAAAAPAAAABwAAAAIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAA//8AgP//AP///wD///8A////AP///wD///8A////AP///wD///8A/62tHP8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/eXko//// - AP///wD///8A////AP///wD///8A////AP///wD///8A////AMD//wD///8A////AP///wD///8A//// - AP///wD///8A////AP/Y2A7/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv///wD///8A////AP///wD///8A////AP///wD///8A//// - AP///wD///8AAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQAAAAMAAAAJAAAAEwAA - AB8AAAAxAAAARgAAAF4AAAB1AAAAiyc2KKyg36X6p+is/6forP+n6Kz/p+is/6forP+n6Kz/p+is/6fo - rP+n6Kz/p+is/6forP+n6Kz/p+is/6forP+n6Kz/p+is/6forP+n6Kz/p+is/6forP+n6Kz/p+is/6fo - rP9mjWndAAAAswAAAKsAAACgAAAAkQAAAH8AAABrAAAAVSk4Kk5zn3ZmmdWenKbmq9+n6Kz/p+is/6fo - rP+n6Kz/p+is/6forP+n6Kz/p+is/6forP+n6Kz/p+is/6forP+n6Kz/p+is/6forP+n6Kz/p+is/6fo - rP+n6Kz/ntyj+x4qH8cAAAC/AAAAvwAAAL8AAAC/AAAAvwAAAL4AAAC7AAAAtQAAAKoAAACcAAAAiwAA - AHUAAABdAAAARgAAADEAAAAfAAAAEgAAAAkAAAADAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAP//AID//wD///8A////AP///wD///8A////AP///wD///8A////AP+trRz/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/3l5 - KP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wDA//8A////AP///wD///8A//// - AP///wD///8A////AP///wD/2NgO/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL///8A////AP///wD///8A////AP///wD///8A//// - AP///wD///8A////AAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEAAAAEAAAACwAA - ABYAAAAlAAAANwAAAE4AAABmAAAAfQwRDZaVz5nwp+is/6forP+n6Kz/p+is/6forP+n6Kz/p+is/6fo - rP+n6Kz/p+is/6forP+n6Kz/p+is/6forP+n6Kz/p+is/6forP+n6Kz/p+is/6forP+n6Kz/p+is/6fo - rP+n6Kz/jsWS7wAAAKkAAACgAAAAkwAAAIMAAABxAAAAXgAAAEkAAAA1AAAAJAAAABcAAAANmdSdOqbm - q6Cn6Kz5p+is/6forP+n6Kz/p+is/6forP+n6Kz/p+is/6forP+n6Kz/p+is/6forP+n6Kz/p+is/6fo - rP+n6Kz/p+is/6forP+OxZLyBggGwAAAAL8AAAC/AAAAvwAAAL8AAAC+AAAAvAAAALgAAACvAAAAogAA - AJEAAAB9AAAAZgAAAE4AAAA3AAAAJQAAABYAAAALAAAABAAAAAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAD//wCA//8A////AP///wD///8A////AP///wD///8A////AP///wD/ra0c/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv95eSj///8A////AP///wD///8A////AP///wD///8A////AP///wD///8AwP//AP///wD///8A//// - AP///wD///8A////AP///wD///8A/9jYDv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy////AP///wD///8A////AP///wD///8A//// - AP///wD///8A////AP///wABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABAAAABgAA - AA4AAAAaAAAAKgAAAD4AAABVAAAAbgAAAIV3pnvVp+is/6forP+n6Kz/p+is/6forP+n6Kz/p+is/6fo - rP+n6Kz/p+is/6forP+n6Kz/p+is/6forP+n6Kz/p+is/6forP+n6Kz/p+is/6forP+n6Kz/p+is/6fo - rP+n6Kz/p+is/6PjqPsAAACcAAAAkQAAAIMAAABzAAAAYQAAAE8AAAA8AAAAKwAAABwAAAARAAAACgAA - AAQAAAABouGnIKforJ+n6Kz9p+is/6forP+n6Kz/p+is/6forP+n6Kz/p+is/6forP+n6Kz/p+is/6fo - rP+n6Kz/p+is/6forP+n6Kz/p+is/2uUbuMAAAC/AAAAvwAAAL8AAAC/AAAAvwAAAL4AAAC6AAAAsgAA - AKcAAACXAAAAhQAAAG0AAABVAAAAPgAAACoAAAAaAAAADgAAAAYAAAABAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAA//8AgP//AP///wD///8A////AP///wD///8A////AP///wD///8A/62t - HP8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/eXko////AP///wD///8A////AP///wD///8A////AP///wD///8A////AMD//wD///8A//// - AP///wD///8A////AP///wD///8A////AP/Y2A7/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv///wD///8A////AP///wD///8A//// - AP///wD///8A////AP///wD///8AAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAgAA - AAgAAAARAAAAHwAAAC8AAABEAAAAXQAAAHVAWUKppuer/6forP+n6Kz/p+is/6forP+n6Kz/p+is/6fo - rP+n6Kz/p+is/6forP+n6Kz/p+is/6forP+n6Kz/p+is/6forP+n6Kz/p+is/6forP+n6Kz/p+is/6fo - rP+n6Kz/p+is/6forP+n6Kz/AQIBiwAAAH8AAABxAAAAYQAAAFEAAABAAAAALwAAACEAAAAWAAAADQAA - AAcAAAAEAAAAAQAAAAEAAAABpOSpPaforNqn6Kz/p+is/6forP+n6Kz/p+is/6forP+n6Kz/p+is/6fo - rP+n6Kz/p+is/6forP+n6Kz/p+is/6forP+m56v+L0IxzgAAAL8AAAC/AAAAvwAAAL8AAAC+AAAAuwAA - ALUAAACrAAAAnQAAAIsAAAB1AAAAXQAAAEQAAAAvAAAAHgAAABEAAAAIAAAAAgAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAP//AID//wD///8A////AP///wD///8A////AP///wD///8A//// - AP+trRz/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/3l5KP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wDA//8A//// - AP///wD///8A////AP///wD///8A////AP///wD/2NgO/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL///8A////AP///wD///8A//// - AP///wD///8A////AP///wD///8A////AAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQAA - AAQAAAAKAAAAFAAAACIAAAA0AAAASwAAAGQJDQmAmNOc76forP+n6Kz/p+is/6forP+n6Kz/p+is/6fo - rP+n6Kz/p+is/6forP+n6Kz/p+is/6forP+n6Kz/p+is/6forP+n6Kz/p+is/6forP+n6Kz/p+is/6fo - rP+n6Kz/p+is/6forP+n6Kz/pOOp+wAAAHYAAABrAAAAXQAAAE8AAABAAAAAMQAAACUAAAAZAAAAEgAA - AAwAAAAIAAAABgAAAAQAAAAEAAAAAwAAAAKc2aEPpuersKforP+n6Kz/p+is/6forP+n6Kz/p+is/6fo - rP+n6Kz/p+is/6forP+n6Kz/p+is/6forP+n6Kz/p+is/5HJlfQFBgXAAAAAvwAAAL8AAAC/AAAAvgAA - AL0AAAC4AAAArwAAAKEAAACQAAAAfAAAAGMAAABKAAAANAAAACIAAAAUAAAACgAAAAQAAAABAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD//wCA//8A////AP///wD///8A////AP///wD///8A//// - AP///wD/ra0c/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv95eSj///8A////AP///wD///8A////AP///wD///8A////AP///wD///8AwP// - AP///wD///8A////AP///wD///8A////AP///wD///8A/9jYDv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy////AP///wD///8A//// - AP///wD///8A////AP///wD///8A////AP///wABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAEAAAAEAAAADAAAABcAAAAmAAAAOgAAAFAAAABqaZJtu6forP+n6Kz/p+is/6forP+n6Kz/p+is/6fo - rP+n6Kz/p+is/6forP+n6Kz/p+is/6forP+n6Kz/p+is/6forP+n6Kz/p+is/6forP+n6Kz/p+is/6fo - rP+n6Kz/p+is/6forP+n6Kz/p+is/5fRm+EAAABhAAAAVQAAAEkAAAA9AAAAMQAAACYAAAAdAAAAFgAA - ABIAAAAPAAAADQAAAAsAAAAKAAAACQAAAAcAAAAFAAAABDhNOQOm5quAp+is/6forP+n6Kz/p+is/6fo - rP+n6Kz/p+is/6forP+n6Kz/p+is/6forP+n6Kz/p+is/6forP+n6Kz/VHRW2gAAAL8AAAC/AAAAvwAA - AL8AAAC+AAAAuQAAALEAAAClAAAAlQAAAIEAAABqAAAAUAAAADkAAAAmAAAAFwAAAAwAAAAEAAAAAQAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA//8AgP//AP///wD///8A////AP///wD///8A//// - AP///wD///8A/62tHP8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/eXko////AP///wD///8A////AP///wD///8A////AP///wD///8A//// - AMD//wD///8A////AP///wD///8A////AP///wD///8A////AP/Y2A7/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv///wD///8A//// - AP///wD///8A////AP///wD///8A////AP///wD///8AAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAABAAAABQAAAA0AAAAaAAAAKgAAAD4AAABVFh8XeKHgpven6Kz/p+is/6forP+n6Kz/p+is/6fo - rP+n6Kz/p+is/6forP+n6Kz/p+is/6forP+n6Kz/p+is/6forP+n6Kz/p+is/6forP+n6Kz/p+is/6fo - rP+n6Kz/p+is/6forP+n6Kz/p+is/6forP+CtIatAAAASQAAAEAAAAA2AAAALQAAACUAAAAfAAAAGgAA - ABcAAAAWAAAAFgAAABYAAAAVAAAAEwAAABEAAAAOAAAACgAAAAcAAAAEAAAAA6bmq3un6Kz/p+is/6fo - rP+n6Kz/p+is/6forP+n6Kz/p+is/6forP+n6Kz/p+is/6forP+n6Kz/p+is/5zZofkJDQnCAAAAvwAA - AL8AAAC/AAAAvgAAALsAAACzAAAAqAAAAJkAAACFAAAAbwAAAFUAAAA9AAAAKgAAABkAAAANAAAABQAA - AAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP//AID//wD///8A////AP///wD///8A//// - AP///wD///8A////AP+trRz/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/3l5KP///wD///8A////AP///wD///8A////AP///wD///8A//// - AP///wDA//8A////AP///wD///8A////AP///wD///8A////AP///wD/2NgO/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL///8A//// - AP///wD///8A////AP///wD///8A////AP///wD///8A////AAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAQAAAAcAAAAQAAAAHAAAAC0AAABCAAAAW2+bc7en6Kz/p+is/6forP+n6Kz/p+is/6fo - rP+n6Kz/p+is/6forP+n6Kz/p+is/6forP+n6Kz/p+is/6forP+n6Kz/p+is/6forP+n6Kz/p+is/6fo - rP+n6Kz/p+is/6forP+n6Kz/p+is/6forP+m56v9RWBHVwAAADUAAAAuAAAAKAAAACIAAAAfAAAAHAAA - ABwAAAAeAAAAIAAAACIAAAAjAAAAIgAAACAAAAAcAAAAFwAAABIAAAANAAAACAAAAAQAAAADpuargqfo - rP+n6Kz/p+is/6forP+n6Kz/p+is/6forP+n6Kz/p+is/6forP+n6Kz/p+is/6forP+n6Kz/XH9e3QAA - AL8AAAC/AAAAvwAAAL4AAAC8AAAAtQAAAKsAAACcAAAAigAAAHMAAABaAAAAQgAAAC0AAAAcAAAAEAAA - AAcAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD//wCA//8A////AP///wD///8A//// - AP///wD///8A////AP///wD/ra0c/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv95eSj///8A////AP///wD///8A////AP///wD///8A//// - AP///wD///8AwP//AP///wD///8A////AP///wD///8A////AP///wD///8A/9jYDv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy//// - AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wABAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAIAAAAHAAAAEQAAAB8AAAAwAAAARgwQDGKh4Kb0p+is/6forP+n6Kz/p+is/6fo - rP+n6Kz/p+is/6forP+n6Kz/p+is/6forP+n6Kz/p+is/6forP+n6Kz/p+is/6forP+n6Kz/p+is/6fo - rP+n6Kz/p+is/6forP+n6Kz/p+is/6forP+n6Kz/lM6YqQAAACkAAAAlAAAAIQAAAB4AAAAdAAAAHQAA - ACAAAAAkAAAAKQAAAC4AAAAyAAAANAAAADQAAAAxAAAAKwAAACQAAAAcAAAAFAAAAA0AAAAIAAAABCo6 - KwSm56u0p+is/6forP+n6Kz/p+is/6forP+n6Kz/p+is/6forP+n6Kz/p+is/6forP+n6Kz/p+is/5vX - n/kFBgXAAAAAvwAAAL8AAAC/AAAAvQAAALcAAACsAAAAnwAAAI0AAAB3AAAAXgAAAEUAAAAwAAAAHwAA - ABEAAAAHAAAAAgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA//8AgP//AP///wD///8A//// - AP///wD///8A////AP///wD///8A/62tHP8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/eXko////AP///wD///8A////AP///wD///8A//// - AP///wD///8A////AMD//wD///8A////AP///wD///8A////AP///wD///8A////AP/Y2A7/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8AAQAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAACAAAACQAAABMAAAAhAAAAMwAAAEljiWaap+is/6forP+n6Kz/p+is/6fo - rP+n6Kz/p+is/6forP+n6Kz/p+is/6forP+n6Kz/p+is/6PjqP2n6Kz/p+is/6forP+n6Kz/p+is/6fo - rP+n6Kz/p+is/6forP+n6Kz/p+is/6forP+n6Kz/o+Oo1zJGNCgAAAAbAAAAGQAAABkAAAAaAAAAHQAA - ACIAAAAoAAAAMQAAADoAAABBAAAARwAAAEoAAABJAAAARQAAAD0AAAA0AAAAKAAAAB4AAAAUAAAADQAA - AAcAAAAEi8KQEqbnq96n6Kz/p+is/6forP+n6Kz/p+is/6forP+n6Kz/p+is/6forP+n6Kz/p+is/6fo - rP+n6Kz/Q15F1QAAAL8AAAC/AAAAvwAAAL4AAAC4AAAArwAAAKEAAACQAAAAewAAAGIAAABIAAAAMgAA - ACAAAAATAAAACAAAAAIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP//AID//wD///8A//// - AP///wD///8A////AP///wD///8A////AP+trRz/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/3l5KP///wD///8A////AP///wD///8A//// - AP///wD///8A////AP///wDA//8A////AP///wD///8A////AP///wD///8A////AP///wD/2NgO/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AAEAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAwAAAAoAAAAUAAAAIgAAADUAAABLlM6Y2aforP+n6Kz/p+is/6fo - rP+n6Kz/p+is/6forP+n6Kz/p+is/6forP+n6Kz/p+is/6forP9BW0PLj8aT7aforP+n6Kz/p+is/6fo - rP+n6Kz/p+is/6forP+n6Kz/p+is/6forP+n6Kz/pOSp1WaNaSkAAAASAAAAEgAAABMAAAAWAAAAGwAA - ACIAAAArAAAANwAAAEIAAABNAAAAVwAAAF4AAABhAAAAYQAAAFsAAABSAAAARgAAADgAAAAqAAAAHQAA - ABMAAAALAAAABgAAAASd2qJFp+is/qforP+n6Kz/p+is/6forP+n6Kz/p+is/6forP+n6Kz/p+is/6fo - rP+n6Kz/p+is/4S3iO4AAAC/AAAAvwAAAL8AAAC+AAAAuQAAALAAAACjAAAAkgAAAH0AAABlAAAASwAA - ADQAAAAiAAAAEwAAAAkAAAADAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD//wCA//8A//// - AP///wD///8A////AP///wD///8A////AP///wD/ra0c/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv95eSj///8A////AP///wD///8A//// - AP///wD///8A////AP///wD///8AwP//AP///wD///8A////AP///wD///8A////AP///wD///8A/9jY - Dv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wABAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAMAAAAKAAAAFQAAACQAAAA3LkAvX6bnq/6n6Kz/p+is/6fo - rP+n6Kz/p+is/6forP+n6Kz/p+is/6forP+n6Kz/p+is/6forP94pnvnAAAAsggLCKlvm3PQpeWq/afo - rP+n6Kz/p+is/6forP+n6Kz/p+is/6forP+n6Kz7ouKnmFx/XhQAAAAKAAAACgAAAA0AAAARAAAAGAAA - ACEAAAAtAAAAOgAAAEcAAABVAAAAYwAAAG0AAAB2AAAAeQAAAHcAAABxAAAAZwAAAFgAAABIAAAANwAA - ACgAAAAbAAAAEAAAAAkAAAAFAAAABqLip6qn6Kz/p+is/6forP+n6Kz/p+is/6forP+n6Kz/p+is/6fo - rP+n6Kz/p+is/6forP+m5qv+FBwVxQAAAL8AAAC/AAAAvgAAALkAAACxAAAApAAAAJQAAAB/AAAAZwAA - AEwAAAA2AAAAIwAAABUAAAAKAAAAAwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA//8AgP// - AP///wD///8A////AP///wD///8A////AP///wD///8A/62tHP8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/eXko////AP///wD///8A//// - AP///wD///8A////AP///wD///8A////AMD//wD///8A////AP///wD///8A////AP///wD///8A//// - AP/Y2A7/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8AAQAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADAAAACgAAABYAAAAlAAAAN3akeZqn6Kz/p+is/6fo - rP+n6Kz/p+is/6forP+n6Kz/p+is/6forP+n6Kz/p+is/6forP+k5Kn9GiMawgAAALIAAAClAAAAlRok - G4xvmnKrmdWe1qTkqfGn6Kz/puar8KTkqcij46iEmdWeJQAAAAIAAAADAAAABAAAAAcAAAAMAAAAEwAA - AB0AAAArAAAAOgAAAEkAAABaAAAAagAAAHcAAACCAAAAigAAAI0AAACLAAAAhQAAAHkAAABqAAAAWAAA - AEYAAAA0AAAAJQAAABgAAAAOAAAABwAAAAeCtIYtp+is+qforP+n6Kz/p+is/6forP+n6Kz/p+is/6fo - rP+n6Kz/p+is/6forP+n6Kz/p+is/1FxVNoAAAC/AAAAvwAAAL4AAAC6AAAAsgAAAKUAAACVAAAAgQAA - AGgAAABOAAAANwAAACQAAAAWAAAACgAAAAMAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP// - AID//wD///8A////AP///wD///8A////AP///wD///8A////AP+trRz/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/3l5KP///wD///8A//// - AP///wD///8A////AP///wD///8A////AP///wDA//8A////AP///wD///8A////AP///wD///8A//// - AP///wD/2NgO/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A//// - AAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABAAAAAoAAAAWAAAAJQAAADiUzpjLp+is/6fo - rP+n6Kz/p+is/6forP+n6Kz/p+is/6forP+n6Kz/p+is/6forP+n6Kz/c5925gAAALkAAACxAAAApAAA - AJQAAAB/AAAAZwAAAE0AAAA3AAAAJAAAABUAAAAKAAAAAwAAAAAAAAAAAAAAAQAAAAMAAAAHAAAADgAA - ABgAAAAlAAAANQAAAEcAAABaAAAAawAAAHwAAACKAAAAlQAAAJwAAACeAAAAnAAAAJUAAACKAAAAewAA - AGkAAABVAAAAQgAAADAAAAAgAAAAFAAAAAwAAAAJAAAADZ/dpKmn6Kz/p+is/6forP+n6Kz/p+is/6fo - rP+n6Kz/p+is/6forP+n6Kz/p+is/6forP9+r4LrAAAAvwAAAL8AAAC+AAAAugAAALIAAACmAAAAlQAA - AIEAAABpAAAATwAAADcAAAAlAAAAFgAAAAoAAAADAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAD//wCA//8A////AP///wD///8A////AP///wD///8A////AP///wD/ra0c/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv95eSj///8A//// - AP///wD///8A////AP///wD///8A////AP///wD///8AwP//AP///wD///8A////AP///wD///8A//// - AP///wD///8A/9jYDv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy////AP///wD///8A////AP///wD///8A////AP///wD///8A//// - AP///wABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQAAAAKAAAAFgAAACULDws7pOSp96fo - rP+n6Kz/p+is/6forP+n6Kz/p+is/6forP+n6Kz/p+is/6forP+n6Kz/p+is/ys7LMsAAAC5AAAAsQAA - AKQAAACUAAAAfwAAAGcAAABNAAAANwAAACQAAAAVAAAACgAAAAMAAAAAAAAAAAAAAAEAAAAEAAAACQAA - ABIAAAAdAAAALAAAAD8AAABTAAAAZwAAAHoAAACLAAAAmQAAAKMAAACpAAAArAAAAKkAAACjAAAAmQAA - AIsAAAB5AAAAZQAAAFAAAAA9AAAAKwAAABwAAAARAAAADQAAAA98rYBHp+is/6forP+n6Kz/p+is/6fo - rP+n6Kz/p+is/6forP+n6Kz/p+is/6forP+n6Kz/oN6l+wMEA8AAAAC/AAAAvgAAALoAAACyAAAApgAA - AJUAAACBAAAAaQAAAE8AAAA3AAAAJQAAABYAAAAKAAAAAwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAA//8AgP//AP///wD///8A////AP///wD///8A////AP///wD///8A/62tHP8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/eXko//// - AP///wD///8A////AP///wD///8A////AP///wD///8A////AMD//wD///8A////AP///wD///8A//// - AP///wD///8A////AP/Y2A7/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv///wD///8A////AP///wD///8A////AP///wD///8A//// - AP///wD///8AAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADAAAACgAAABYAAAAlWXxcXqfo - rP+n6Kz/p+is/6forP+n6Kz/p+is/6forP+n6Kz/p+is/6forP+n6Kz/p+is/5PMl/UAAAC+AAAAugAA - ALIAAAClAAAAlQAAAIEAAABpAAAATwAAADgAAAAlAAAAFgAAAAoAAAAEAAAAAAAAAAAAAAABAAAABAAA - AAoAAAAUAAAAIQAAADEAAABGAAAAXAAAAHIAAACFAAAAlgAAAKMAAACuAAAAswAAALUAAACzAAAArgAA - AKUAAACXAAAAhwAAAHMAAABfAAAASgAAADcAAAAmAAAAGQAAABIAAAATAAAAGaPjqOCn6Kz/p+is/6fo - rP+n6Kz/p+is/6forP+n6Kz/p+is/6forP+n6Kz/p+is/6forP8nNyjLAAAAvwAAAL4AAAC6AAAAsgAA - AKUAAACUAAAAgQAAAGgAAABOAAAANwAAACQAAAAWAAAACgAAAAMAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAP//AID//wD///8A////AP///wD///8A////AP///wD///8A////AP+trRz/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/3l5 - KP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wDA//8A////AP///wD///8A//// - AP///wD///8A////AP///wD/2NgO/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL///8A////AP///wD///8A////AP///wD///8A//// - AP///wD///8A////AAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAwAAAAoAAAAVAAAAJH6v - goan6Kz/p+is/6forP+n6Kz/p+is/6forP+n6Kz/p+is/6forP+n6Kz/p+is/6forP9ki2fhAAAAvgAA - ALoAAACyAAAApgAAAJcAAACDAAAAawAAAFEAAAA6AAAAJwAAABcAAAAMAAAABAAAAAEAAAAAAAAAAQAA - AAQAAAALAAAAFQAAACMAAAA0AAAASgAAAGEAAAB4AAAAiwAAAJ0AAACqAAAAswAAALgAAAC7AAAAuQAA - ALUAAACtAAAAogAAAJQAAACCAAAAbQAAAFgAAABDAAAAMQAAACIAAAAZAAAAGAAAAB2TzJecp+is/6fo - rP+n6Kz/p+is/6forP+n6Kz/p+is/6forP+n6Kz/p+is/6forP+n6Kz/S2hN1wAAAL8AAAC+AAAAuQAA - ALEAAACkAAAAlAAAAH8AAABnAAAATAAAADYAAAAjAAAAFQAAAAoAAAADAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAD//wCA//8A////AP///wD///8A////AP///wD///8A////AP///wD/ra0c/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv95eSj///8A////AP///wD///8A////AP///wD///8A////AP///wD///8AwP//AP///wD///8A//// - AP///wD///8A////AP///wD///8A/9jYDv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy////AP///wD///8A////AP///wD///8A//// - AP///wD///8A////AP///wABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAMAAAAKAAAAFAAA - ACKQyJSnp+is/6forP+n6Kz/p+is/6forP+n6Kz/p+is/6forP+n6Kz/p+is/6forP+n6Kz/Nks30AAA - AL4AAAC7AAAAswAAAKgAAACZAAAAhgAAAG8AAABVAAAAPQAAACoAAAAZAAAADQAAAAUAAAABAAAAAAAA - AAEAAAAEAAAACgAAABUAAAAiAAAANAAAAEoAAABhAAAAeQAAAI0AAACeAAAArAAAALUAAAC7AAAAvAAA - ALwAAAC5AAAAswAAAKoAAACeAAAAjgAAAHwAAABnAAAAUgAAAD0AAAAtAAAAIgAAAB8AAAAjcZ11Z6fo - rP+n6Kz/p+is/6forP+n6Kz/p+is/6forP+n6Kz/p+is/6forP+n6Kz/p+is/2mSbOMAAAC/AAAAvgAA - ALkAAACwAAAAowAAAJIAAAB9AAAAZAAAAEsAAAA0AAAAIgAAABMAAAAJAAAAAwAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAA//8AgP//AP///wD///8A////AP///wD///8A////AP///wD///8A/62t - HP8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/eXko////AP///wD///8A////AP///wD///8A////AP///wD///8A////AMD//wD///8A//// - AP///wD///8A////AP///wD///8A////AP/Y2A7/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv///wD///8A////AP///wD///8A//// - AP///wD///8A////AP///wD///8AAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACAAAACQAA - ABMAAAAhmtafxKforP+n6Kz/p+is/6forP+n6Kz/p+is/6forP+n6Kz/p+is/6forP+n6Kz/puer/goP - C8IAAAC+AAAAuwAAALUAAACqAAAAnAAAAIoAAABzAAAAWgAAAEMAAAAuAAAAHQAAABAAAAAHAAAAAgAA - AAEAAAABAAAABAAAAAoAAAATAAAAIAAAADEAAABGAAAAXgAAAHUAAACJAAAAmwAAAKkAAACzAAAAugAA - AL0AAAC9AAAAuwAAALgAAACxAAAApgAAAJkAAACIAAAAdQAAAGAAAABMAAAAOgAAAC4AAAApAAAALCY1 - J0Kn6Kz/p+is/6forP+n6Kz/p+is/6forP+n6Kz/p+is/6forP+n6Kz/p+is/6forP98rYDrAAAAvwAA - AL4AAAC4AAAArwAAAKEAAACQAAAAewAAAGIAAABIAAAAMgAAACAAAAATAAAACAAAAAIAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAP//AID//wD///8A////AP///wD///8A////AP///wD///8A//// - AP+trRz/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/3l5KP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wDA//8A//// - AP///wD///8A////AP///wD///8A////AP///wD/2NgO/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL///8A////AP///wD///8A//// - AP///wD///8A////AP///wD///8A////AAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAgAA - AAcAAAARAAAAH6Hgptqn6Kz/p+is/6forP+n6Kz/p+is/6forP+n6Kz/p+is/6forP+n6Kz/p+is/5bQ - mvcAAAC/AAAAvwAAALwAAAC3AAAArQAAAKAAAACOAAAAeQAAAGEAAABJAAAAMwAAACIAAAATAAAACgAA - AAQAAAABAAAAAQAAAAMAAAAIAAAAEAAAABwAAAAsAAAAQAAAAFYAAABtAAAAggAAAJQAAACkAAAArwAA - ALcAAAC7AAAAvQAAAL0AAAC7AAAAtQAAAK4AAACjAAAAlAAAAIIAAABvAAAAWwAAAEkAAAA8AAAANgAA - ADcAAABAoN6l6qforP+n6Kz/p+is/6forP+n6Kz/p+is/6forP+n6Kz/p+is/6forP+n6Kz/jMOQ8gAA - AL8AAAC9AAAAtwAAAKwAAACfAAAAjQAAAHcAAABeAAAARQAAADAAAAAfAAAAEQAAAAcAAAACAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD//wCA//8A////AP///wD///8A////AP///wD///8A//// - AP///wD/ra0c/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv95eSj///8A////AP///wD///8A////AP///wD///8A////AP///wD///8AwP// - AP///wD///8A////AP///wD///8A////AP///wD///8A/9jYDv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy////AP///wD///8A//// - AP///wD///8A////AP///wD///8A////AP///wABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAEAAAAHAAAAEAAAAByk5Knsp+is/6forP+n6Kz/p+is/6forP+n6Kz/p+is/6forP+n6Kz/p+is/6fo - rP+FuYnvAAAAvwAAAL8AAAC9AAAAuAAAALAAAACkAAAAlAAAAIAAAABoAAAAUAAAADoAAAAoAAAAGAAA - AA0AAAAGAAAAAgAAAAEAAAACAAAABwAAAA0AAAAXAAAAJQAAADcAAABMAAAAYgAAAHcAAACLAAAAnAAA - AKkAAACyAAAAuAAAALwAAAC9AAAAvAAAALkAAAC0AAAAqwAAAJ8AAACPAAAAfQAAAGoAAABYAAAATAAA - AEQAAABEAAAATJbQmtan6Kz/p+is/6forP+n6Kz/p+is/6forP+n6Kz/p+is/6forP+n6Kz/p+is/5jT - nPgAAAC+AAAAvAAAALUAAACrAAAAnAAAAIoAAABzAAAAWgAAAEIAAAAtAAAAHAAAABAAAAAHAAAAAQAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA//8AgP//AP///wD///8A////AP///wD///8A//// - AP///wD///8A/62tHP8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/eXko////AP///wD///8A////AP///wD///8A////AP///wD///8A//// - AMD//wD///8A////AP///wD///8A////AP///wD///8A////AP/Y2A7/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv///wD///8A//// - AP///wD///8A////AP///wD///8A////AP///wD///8AAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAABAAAABQAAAA0AAAAapuar8qforP+n6Kz/p+is/6forP+n6Kz/p+is/6forP+n6Kz/p+is/6fo - rP+n6Kz/fK2A6wAAAL8AAAC/AAAAvgAAALoAAACzAAAAqAAAAJoAAACHAAAAcQAAAFkAAABDAAAALwAA - AB8AAAASAAAACQAAAAQAAAABAAAAAgAAAAQAAAAKAAAAEgAAAB4AAAAuAAAAQAAAAFVghmOgir+O2QMF - A5IAAAChAAAArAAAALUAAAC6AAAAvQAAAL0AAAC7AAAAuAAAALEAAACnAAAAmgAAAIsAAAB5AAAAaQAA - AFwAAABVAAAAVAAAAFqKwI7Lp+is/6forP+n6Kz/p+is/6forP+n6Kz/p+is/6forP+n6Kz/p+is/6fo - rP+g3qX7AAAAvgAAALsAAACzAAAAqAAAAJkAAACFAAAAbwAAAFUAAAA9AAAAKgAAABkAAAANAAAABQAA - AAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP//AID//wD///8A////AP///wD///8A//// - AP///wD///8A////AP+trRz/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/3l5KP///wD///8A////AP///wD///8A////AP///wD///8A//// - AP///wDA//8A////AP///wD///8A////AP///wD///8A////AP///wD/2NgO/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL///8A//// - AP///wD///8A////AP///wD///8A////AP///wD///8A////AAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAQAAAAQAAAAMAAAAF6forP6n6Kz/p+is/6forP+n6Kz/p+is/6forP+n6Kz/p+is/6fo - rP+n6Kz/p+is/3Shd+cAAAC/AAAAvwAAAL4AAAC7AAAAtQAAAKwAAACgAAAAjwAAAHoAAABkAAAATQAA - ADgAAAAmAAAAGAAAAA0AAAAHAAAAAwAAAAIAAAADAAAABwAAAA0AAAAWAAAAJDRJNkaTzZjEp+is/6fo - rP9qk22/AAAAlwAAAKUAAACvAAAAtwAAALsAAAC9AAAAvQAAALsAAAC2AAAArwAAAKQAAACXAAAAiAAA - AHkAAABuAAAAZwAAAGUAAABqhLeIzKforP+n6Kz/p+is/6forP+n6Kz/p+is/6forP+n6Kz/p+is/6fo - rP+n6Kz/o+Oo/QAAAL4AAAC5AAAAsQAAAKUAAACVAAAAgQAAAGoAAABQAAAAOQAAACYAAAAXAAAADAAA - AAQAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD//wCA//8A////AP///wD///8A//// - AP///wD///8A////AP///wD/ra0c/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv95eSj///8A////AP///wD///8A////AP///wD///8A//// - AP///wD///8AwP//AP///wD///8A////AP///wD///8A////AP///wD///8A/9jYDv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy//// - AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wABAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAEAAAAEAAAACgAAABSn6Kz8p+is/6forP+n6Kz/p+is/6forP+n6Kz/p+is/6fo - rP+n6Kz/p+is/6forP9xnXXmAAAAvwAAAL8AAAC+AAAAvQAAALgAAACxAAAApgAAAJcAAACEAAAAbwAA - AFgAAABDAAAAMAAAACAAAAATAAAACwAAAAYAAAADAAAAAwAAAAQAAAAJAAAAEIm+jWSk5Kntp+is/6fo - rP+n6Kz/peWq/DFEM6AAAACcAAAAqQAAALIAAAC4AAAAuwAAAL0AAAC8AAAAuQAAALQAAACsAAAAoQAA - AJUAAACJAAAAfwAAAHkAAAB2AAAAeoK0htKn6Kz/p+is/6forP+n6Kz/p+is/6forP+n6Kz/p+is/6fo - rP+n6Kz/p+is/6PjqP0AAAC9AAAAuAAAAK8AAAChAAAAkAAAAHsAAABjAAAASgAAADQAAAAiAAAAFAAA - AAoAAAAEAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA//8AgP//AP///wD///8A//// - AP///wD///8A////AP///wD///8A/62tHP8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/eXko////AP///wD///8A////AP///wD///8A//// - AP///wD///8A////AMD//wD///8A////AP///wD///8A////AP///wD///8A////AP/Y2A7/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8AAQAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAgAAAAgAAAARpuar8qforP+n6Kz/p+is/6forP+n6Kz/p+is/6fo - rP+n6Kz/p+is/6forP+n6Kz/eKZ76QAAAL8AAAC/AAAAvwAAAL4AAAC6AAAAtQAAAKsAAACfAAAAjgAA - AHsAAABlAAAAUAAAADwAAAArAAAAHAAAABEAAAAKAAAABQAAAAQAAAAEe6t/F6PjqKen6Kz/p+is/6fo - rP+n6Kz/p+is/6forP+X0pzpCAsIlAAAAKAAAACsAAAAtAAAALkAAAC8AAAAvQAAALsAAAC4AAAAsgAA - AKkAAACgAAAAlwAAAJAAAACKAAAAiAAAAIuGuorep+is/6forP+n6Kz/p+is/6forP+n6Kz/p+is/6fo - rP+n6Kz/p+is/6forP+g3qX7AAAAuwAAALUAAACrAAAAnQAAAIsAAAB1AAAAXAAAAEQAAAAvAAAAHgAA - ABEAAAAIAAAAAgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP//AID//wD///8A//// - AP///wD///8A////AP///wD///8A////AP+trRz/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/3l5KP///wD///8A////AP///wD///8A//// - AP///wD///8A////AP///wDA//8A////AP///wD///8A////AP///wD///8A////AP///wD/2NgO/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AAEAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEAAAAGAAAADqbmq+mn6Kz/p+is/6forP+n6Kz/p+is/6fo - rP+n6Kz/p+is/6forP+n6Kz/p+is/4W5ie8AAAC/AAAAvwAAAL8AAAC+AAAAvAAAALgAAACwAAAApgAA - AJgAAACHAAAAcwAAAF4AAABKAAAANwAAACgAAAAaAAAAEAAAAAoAAAAGAAAABKbnq8Kn6Kz/p+is/6fo - rP+n6Kz/p+is/6forP+n6Kz/p+is/3WieMcAAACWAAAApAAAAK8AAAC2AAAAuwAAAL0AAAC9AAAAuwAA - ALcAAACxAAAAqgAAAKMAAACdAAAAmgAAAJcAAACajMOQ6KforP+n6Kz/p+is/6forP+n6Kz/p+is/6fo - rP+n6Kz/p+is/6forP+n6Kz/mNOc+AAAALoAAACyAAAApwAAAJcAAACFAAAAbQAAAFUAAAA+AAAAKgAA - ABoAAAAOAAAABgAAAAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD//wCA//8A//// - AP///wD///8A////AP///wD///8A////AP///wD/ra0c/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv95eSj///8A////AP///wD///8A//// - AP///wD///8A////AP///wD///8AwP//AP///wD///8A////AP///wD///8A////AP///wD///8A/9jY - Dv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wABAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABAAAABAAAAAyk46nTp+is/6forP+n6Kz/p+is/6fo - rP+n6Kz/p+is/6forP+n6Kz/p+is/6forP+W0Jr2AAAAvwAAAL8AAAC/AAAAvgAAAL0AAAC6AAAAtQAA - AKwAAAChAAAAkgAAAIEAAABtAAAAWgAAAEYAAAA1AAAAJgAAABoAAAARAAAACwAAAAec2aE7p+is/Kfo - rP+n6Kz/p+is/6forP+n6Kz/p+is/6forP+m56v+PlZApgAAAJoAAACnAAAAsQAAALgAAAC7AAAAvQAA - AL0AAAC6AAAAtgAAALIAAACtAAAAqQAAAKYAAACkAAAApprWn/Wn6Kz/p+is/6forP+n6Kz/p+is/6fo - rP+n6Kz/p+is/6forP+n6Kz/p+is/43EkfEAAAC4AAAArwAAAKIAAACRAAAAfQAAAGYAAABOAAAANwAA - ACUAAAAWAAAACwAAAAQAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA//8AgP// - AP///wD///8A////AP///wD///8A////AP///wD///8A/62tHP8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/eXko////AP///wD///8A//// - AP///wD///8A////AP///wD///8A////AMD//wD///8A////AP///wD///8A////AP///wD///8A//// - AP/Y2A7/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8AAQAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQAAAAMAAAAJouGnuaforP+n6Kz/p+is/6fo - rP+n6Kz/p+is/6forP+n6Kz/p+is/6forP+n6Kz/puer/gsPC8IAAAC/AAAAvwAAAL8AAAC+AAAAvAAA - ALgAAACyAAAAqQAAAJ0AAACOAAAAfQAAAGoAAABYAAAARgAAADUAAAAoAAAAHAAAABMAAAANAAAACqPj - qIan6Kz/p+is/6forP+n6Kz/p+is/6forP+n6Kz/p+is/5zZoe8OFA+VAAAAnwAAAKsAAAC0AAAAuQAA - ALwAAAC9AAAAvAAAALoAAAC3AAAAtQAAALIAAACvAAAArw4TDrSm56v/p+is/6forP+n6Kz/p+is/6fo - rP+n6Kz/p+is/6forP+n6Kz/p+is/6forP9+sILqAAAAtQAAAKoAAACdAAAAiwAAAHUAAABeAAAARgAA - ADEAAAAfAAAAEgAAAAkAAAADAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP// - AID//wD///8A////AP///wD///8A////AP///wD///8A////AP+trRz/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/3l5KP///wD///8A//// - AP///wD///8A////AP///wD///8A////AP///wDA//8A////AP///wD///8A////AP///wD///8A//// - AP///wD/2NgO/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A//// - AAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEAAAACAAAAB6DfpZmn6Kz/p+is/6fo - rP+n6Kz/p+is/6forP+n6Kz/p+is/6forP+n6Kz/p+is/6forP81SjfQAAAAvwAAAL8AAAC/AAAAvgAA - AL4AAAC7AAAAtwAAALAAAACmAAAAmgAAAIsAAAB7AAAAaQAAAFgAAABGAAAANwAAACsAAAAgAAAAGAAA - ABIuQTASpuarz6forP+n6Kz/p+is/6forP+n6Kz/p+is/6forP+n6Kz/fq+C0AAAAJcAAAClAAAArwAA - ALcAAAC7AAAAvgAAAL4AAAC8AAAAuwAAALkAAAC4AAAAtwAAALY6UDvKp+is/6forP+n6Kz/p+is/6fo - rP+n6Kz/p+is/6forP+n6Kz/p+is/6forP+n6Kz/aJFr3gAAALEAAAClAAAAlgAAAIIAAABsAAAAVAAA - AD0AAAAqAAAAGgAAAA8AAAAHAAAAAgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAD//wCA//8A////AP///wD///8A////AP///wD///8A////AP///wD/ra0c/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv95eSj///8A//// - AP///wD///8A////AP///wD///8A////AP///wD///8AwP//AP///wD///8A////AP///wD///8A//// - AP///wD///8A/9jYDv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy////AP///wD///8A////AP///wD///8A////AP///wD///8A//// - AP///wABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQAAAASc2aFqp+is/6fo - rP+n6Kz/p+is/6forP+n6Kz/p+is/6forP+n6Kz/p+is/6forP+n6Kz/Y4lm4AAAAL8AAAC/AAAAvwAA - AL8AAAC+AAAAvQAAALoAAAC1AAAArwAAAKUAAACZAAAAiwAAAHsAAABqAAAAWgAAAEoAAAA8AAAAMAAA - ACYAAAAeAAAAGXWjeTym56v4p+is/6forP+n6Kz/p+is/6forP+n6Kz/p+is/6forP9KZ0yyAAAAoAAA - AKwAAAC1AAAAugAAAL0AAAC+AAAAvgAAAL0AAAC8AAAAvAAAALsAAAC7Z49q4KforP+n6Kz/p+is/6fo - rP+n6Kz/p+is/6forP+n6Kz/p+is/6forP+n6Kz/p+is/09tUdEAAACsAAAAnwAAAI4AAAB5AAAAYgAA - AEsAAAA1AAAAIwAAABYAAAALAAAABAAAAAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAA//8AgP//AP///wD///8A////AP///wD///8A////AP///wD///8A/62tHP8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/eXko//// - AP///wD///8A////AP///wD///8A////AP///wD///8A////AMD//wD///8A////AP///wD///8A//// - AP///wD///8A////AP/Y2A7/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv///wD///8A////AP///wD///8A////AP///wD///8A//// - AP///wD///8AAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEAAAADltCaOqfo - rP+n6Kz/p+is/6forP+n6Kz/p+is/6forP+n6Kz/p+is/6forP+n6Kz/p+is/5bQmvYBAQG/AAAAvwAA - AL8AAAC/AAAAvwAAAL4AAAC8AAAAuQAAALUAAACuAAAApAAAAJkAAACLAAAAfQAAAG0AAABeAAAATwAA - AEMAAAA3AAAALgAAACcAAAAikcqWgqforP+n6Kz/p+is/6forP+n6Kz/p+is/6forP+n6Kz/ntuj9RYf - F6QAAACpAAAAsgAAALgAAAC9AAAAvgAAAL4AAAC+AAAAvgAAAL4AAAC+AAAAvpTOmPan6Kz/p+is/6fo - rP+n6Kz/p+is/6forP+n6Kz/p+is/6forP+n6Kz/p+is/6forP8nNyi/AAAApgAAAJcAAACFAAAAbwAA - AFgAAABBAAAALgAAAB0AAAARAAAACAAAAAMAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAP//AID//wD///8A////AP///wD///8A////AP///wD///8A////AP+trRz/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/3l5 - KP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wDA//8A////AP///wD///8A//// - AP///wD///8A////AP///wD/2NgO/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL///8A////AP///wD///8A////AP///wD///8A//// - AP///wD///8A////AAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABAAAAAkxq - Tgum56v0p+is/6forP+n6Kz/p+is/6forP+n6Kz/p+is/6forP+n6Kz/p+is/6forP+n6Kz/Nkw4zwAA - AL8AAAC/AAAAvwAAAL8AAAC+AAAAvgAAALwAAAC5AAAAtQAAAK4AAAClAAAAmgAAAI4AAACBAAAAcwAA - AGUAAABYAAAATAAAAEIAAAA6AAAAMwMFAy+e26PJp+is/6forP+n6Kz/p+is/6forP+n6Kz/p+is/6fo - rP+DtoffAAAApgAAALEAAAC4AAAAvAAAAL4AAAC/AAAAvwAAAL8AAAC/AAAAvy0/L8yn6Kz/p+is/6fo - rP+n6Kz/p+is/6forP+n6Kz/p+is/6forP+n6Kz/p+is/6forP+h4Kb7AwQDrQAAAJ8AAACOAAAAegAA - AGQAAABNAAAANwAAACUAAAAXAAAADQAAAAYAAAACAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAD//wCA//8A////AP///wD///8A////AP///wD///8A////AP///wD/ra0c/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv95eSj///8A////AP///wD///8A////AP///wD///8A////AP///wD///8AwP//AP///wD///8A//// - AP///wD///8A////AP///wD///8A/9jYDv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy////AP///wD///8A////AP///wD///8A//// - AP///wD///8A////AP///wABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAEAAAAEpOSpt6forP+n6Kz/p+is/6forP+n6Kz/p+is/6forP+n6Kz/p+is/6forP+n6Kz/p+is/3em - e+gAAAC/AAAAvwAAAL8AAAC/AAAAvwAAAL4AAAC+AAAAvAAAALkAAAC1AAAArwAAAKYAAACdAAAAkgAA - AIYAAAB6AAAAbgAAAGMAAABYAAAATwAAAEgAAABDPFQ+VqTkqfSn6Kz/p+is/6forP+n6Kz/p+is/6fo - rP+n6Kz/p+is/1FxVMgAAACwAAAAtwAAALsAAAC+AAAAvwAAAL8AAAC/AAAAvwAAAL91onjnp+is/6fo - rP+n6Kz/p+is/6forP+n6Kz/p+is/6forP+n6Kz/p+is/6forP+n6Kz/gLGE5wAAAKUAAACWAAAAgwAA - AG4AAABYAAAAQgAAAC4AAAAeAAAAEgAAAAkAAAAEAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAA//8AgP//AP///wD///8A////AP///wD///8A////AP///wD///8A/62t - HP8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/eXko////AP///wD///8A////AP///wD///8A////AP///wD///8A////AMD//wD///8A//// - AP///wD///8A////AP///wD///8A////AP/Y2A7/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv///wD///8A////AP///wD///8A//// - AP///wD///8A////AP///wD///8AAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAABAAAAAqHgpnKn6Kz/p+is/6forP+n6Kz/p+is/6forP+n6Kz/p+is/6forP+n6Kz/p+is/6fo - rP+k5Kn9GiQbxgAAAL8AAAC/AAAAvwAAAL8AAAC/AAAAvgAAAL4AAAC8AAAAuQAAALUAAACwAAAAqQAA - AKEAAACXAAAAjgAAAIQAAAB5AAAAcAAAAGcAAABgAAAAWgAAAFVslm+Tp+is/6forP+n6Kz/p+is/6fo - rP+n6Kz/p+is/6forP+h4Kb6HSgeuwAAALgAAAC7AAAAvgAAAL8AAAC/AAAAvwAAAL8bJRzHpOSp/qfo - rP+n6Kz/p+is/6forP+n6Kz/p+is/6forP+n6Kz/p+is/6forP+n6Kz/p+is/1Z3WMwAAACcAAAAiwAA - AHgAAABiAAAATAAAADcAAAAlAAAAGAAAAA0AAAAHAAAAAgAAAAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAP//AID//wD///8A////AP///wD///8A////AP///wD///8A//// - AP+trRz/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/3l5KP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wDA//8A//// - AP///wD///8A////AP///wD///8A////AP///wD/2NgO/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL///8A////AP///wD///8A//// - AP///wD///8A////AP///wD///8A////AAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAGRyZUep+is/aforP+n6Kz/p+is/6forP+n6Kz/p+is/6forP+n6Kz/p+is/6fo - rP+n6Kz/p+is/3Shd+YAAAC+AAAAvwAAAL8AAAC/AAAAvwAAAL8AAAC+AAAAvgAAALwAAAC6AAAAtwAA - ALIAAACsAAAApgAAAJ4AAACXAAAAjgAAAIYAAAB/AAAAeQAAAHMAAABvAAAAbIvCkM+n6Kz/p+is/6fo - rP+n6Kz/p+is/6forP+n6Kz/p+is/4e7i+wCAwK5AAAAvAAAAL4AAAC/AAAAvwAAAL8AAAC/eah96qfo - rP+n6Kz/p+is/6forP+n6Kz/p+is/6forP+n6Kz/p+is/6forP+n6Kz/p+is/6bmq/4YIRiqAAAAkQAA - AH8AAABqAAAAVQAAAEAAAAAtAAAAHQAAABIAAAAKAAAABAAAAAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD//wCA//8A////AP///wD///8A////AP///wD///8A//// - AP///wD/ra0c/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv95eSj///8A////AP///wD///8A////AP///wD///8A////AP///wD///8AwP// - AP///wD///8A////AP///wD///8A////AP///wD///8A/9jYDv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy////AP///wD///8A//// - AP///wD///8A////AP///wD///8A////AP///wABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAABAAAAAqXlqsGn6Kz/p+is/6forP+n6Kz/p+is/6forP+n6Kz/p+is/6fo - rP+n6Kz/p+is/6forP+m56v/MkUzzQAAAL4AAAC/AAAAvwAAAL8AAAC/AAAAvwAAAL4AAAC+AAAAvQAA - ALsAAAC4AAAAtQAAALAAAACrAAAApQAAAJ8AAACZAAAAlAAAAI4AAACJAAAAhQAAAIMZIxqMntyj86fo - rP+n6Kz/p+is/6forP+n6Kz/p+is/6forP+n6Kz/WHtb2QAAAL0AAAC+AAAAvwAAAL8AAAC/NUo30Kfo - rP+n6Kz/p+is/6forP+n6Kz/p+is/6forP+n6Kz/p+is/6forP+n6Kz/p+is/6forP+IvYznAAAAlwAA - AIUAAAByAAAAXQAAAEgAAAA0AAAAIwAAABYAAAANAAAABgAAAAIAAAABAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA//8AgP//AP///wD///8A////AP///wD///8A//// - AP///wD///8A/62tHP8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/eXko////AP///wD///8A////AP///wD///8A////AP///wD///8A//// - AMD//wD///8A////AP///wD///8A////AP///wD///8A////AP/Y2A7/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv///wD///8A//// - AP///wD///8A////AP///wD///8A////AP///wD///8AAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAGi4adhp+is/6forP+n6Kz/p+is/6forP+n6Kz/p+is/6fo - rP+n6Kz/p+is/6forP+n6Kz/p+is/5XPmfUNEg3BAAAAvgAAAL8AAAC/AAAAvwAAAL8AAAC/AAAAvwAA - AL4AAAC+AAAAvAAAALoAAAC4AAAAtAAAALAAAACsAAAAqAAAAKMAAACgAAAAnAAAAJkAAACXAAAAlUdi - Sban6Kz/p+is/6forP+n6Kz/p+is/6forP+n6Kz/p+is/6PjqP0lMybJAAAAvgAAAL8AAAC/DRINw5XP - mvan6Kz/p+is/6forP+n6Kz/p+is/6forP+n6Kz/p+is/6forP+n6Kz/p+is/6forP+n6Kz/TWtQvgAA - AIsAAAB4AAAAZAAAAE8AAAA7AAAAKQAAABsAAAAQAAAACQAAAAQAAAABAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP//AID//wD///8A////AP///wD///8A//// - AP///wD///8A////AP+trRz/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/3l5KP///wD///8A////AP///wD///8A////AP///wD///8A//// - AP///wDA//8A////AP///wD///8A////AP///wD///8A////AP///wD/2NgO/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL///8A//// - AP///wD///8A////AP///wD///8A////AP///wD///8A////AAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABfa6BCKforOan6Kz/p+is/6forP+n6Kz/p+is/6fo - rP+n6Kz/p+is/6forP+n6Kz/p+is/6forP+n6Kz/fKx/6QEBAb0AAAC+AAAAvwAAAL8AAAC/AAAAvwAA - AL8AAAC/AAAAvgAAAL4AAAC9AAAAvAAAALoAAAC4AAAAtQAAALIAAACvAAAArQAAAKoAAACoAAAApgAA - AKUAAACldqR53KforP+n6Kz/p+is/6forP+n6Kz/p+is/6forP+n6Kz/jcWS8wUHBcAAAAC/AQEBv3ys - f+un6Kz/p+is/6forP+n6Kz/p+is/6forP+n6Kz/p+is/6forP+n6Kz/p+is/6forP+n6Kz/ndmh9gcJ - B5QAAAB/AAAAagAAAFUAAABBAAAALwAAAB8AAAATAAAACwAAAAUAAAACAAAAAQAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD//wCA//8A////AP///wD///8A//// - AP///wD///8A////AP///wD/ra0c/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv95eSj///8A////AP///wD///8A////AP///wD///8A//// - AP///wD///8AwP//AP///wD///8A////AP///wD///8A////AP///wD///8A/9jYDv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy//// - AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wABAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAGk5Kl9p+is/6forP+n6Kz/p+is/6fo - rP+n6Kz/p+is/6forP+n6Kz/p+is/6forP+n6Kz/p+is/6forP9fhGLcAAAAvQAAAL4AAAC/AAAAvwAA - AL8AAAC/AAAAvwAAAL8AAAC/AAAAvgAAAL4AAAC+AAAAvAAAALsAAAC6AAAAuAAAALYAAAC1AAAAswAA - ALIAAACyAAAAsQwQDLaX0Zv1p+is/6forP+n6Kz/p+is/6forP+n6Kz/p+is/6forP9jiWbgAAAAv16D - Yd+n6Kz/p+is/6forP+n6Kz/p+is/6forP+n6Kz/p+is/6forP+n6Kz/p+is/6forP+n6Kz/p+is/2SK - Z8gAAACHAAAAcwAAAF4AAABJAAAANQAAACUAAAAXAAAADQAAAAcAAAADAAAAAQAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA//8AgP//AP///wD///8A//// - AP///wD///8A////AP///wD///8A/62tHP8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/eXko////AP///wD///8A////AP///wD///8A//// - AP///wD///8A////AMD//wD///8A////AP///wD///8A////AP///wD///8A////AP/Y2A7/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8AAQAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABnNmhD6forOun6Kz/p+is/6fo - rP+n6Kz/p+is/6forP+n6Kz/p+is/6forP+n6Kz/p+is/6forP+n6Kz/p+is/1p+XdoAAAC9AAAAvgAA - AL8AAAC/AAAAvwAAAL8AAAC/AAAAvwAAAL8AAAC/AAAAvwAAAL4AAAC+AAAAvgAAAL0AAAC8AAAAuwAA - ALsAAAC6AAAAugAAALoAAAC6MkY0y6bmq/6n6Kz/p+is/6forP+n6Kz/p+is/6forP+n6Kz/puar/m6Z - ceWn6Kz/p+is/6forP+n6Kz/p+is/6forP+n6Kz/p+is/6forP+n6Kz/p+is/6forP+n6Kz/p+is/5/d - pPgQFhCXAAAAfQAAAGgAAABSAAAAPQAAACsAAAAcAAAAEAAAAAkAAAAEAAAAAQAAAAEAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP//AID//wD///8A//// - AP///wD///8A////AP///wD///8A////AP+trRz/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/3l5KP///wD///8A////AP///wD///8A//// - AP///wD///8A////AP///wDA//8A////AP///wD///8A////AP///wD///8A////AP///wD/2NgO/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AAEAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAGm5qtzp+is/6fo - rP+n6Kz/p+is/6forP+n6Kz/p+is/6forP+n6Kz/p+is/6forP+n6Kz/p+is/6forP+n6Kz/XoJg2wEB - AbwAAAC+AAAAvgAAAL8AAAC/AAAAvwAAAL8AAAC/AAAAvwAAAL8AAAC/AAAAvwAAAL8AAAC/AAAAvwAA - AL4AAAC+AAAAvgAAAL4AAAC+AAAAvgAAAL5mjWnhp+is/6forP+n6Kz/p+is/6forP+n6Kz/p+is/6fo - rP+n6Kz/p+is/6forP+n6Kz/p+is/6forP+n6Kz/p+is/6forP+n6Kz/p+is/6forP+n6Kz/p+is/6fo - rP9egmDIAAAAiwAAAHYAAABgAAAASQAAADUAAAAkAAAAFgAAAAwAAAAGAAAAAgAAAAEAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD//wCA//8A//// - AP///wD///8A////AP///wD///8A////AP///wD/ra0c/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv95eSj///8A////AP///wD///8A//// - AP///wD///8A////AP///wD///8AwP//AP///wD///8A////AP///wD///8A////AP///wD///8A/9jY - Dv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wABAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAksuWCKfo - rNan6Kz/p+is/6forP+n6Kz/p+is/6forP+n6Kz/p+is/6forP+n6Kz/p+is/6forP+n6Kz/p+is/6fo - rP97q3/oDBENvwAAAL4AAAC+AAAAvwAAAL8AAAC/AAAAvwAAAL8AAAC/AAAAvwAAAL8AAAC/AAAAvwAA - AL8AAAC/AAAAvwAAAL8AAAC/AAAAvwAAAL8AAAC/BggGwY/HlPOn6Kz/p+is/6forP+n6Kz/p+is/6fo - rP+n6Kz/p+is/6forP+n6Kz/p+is/6forP+n6Kz/p+is/6forP+n6Kz/p+is/6forP+n6Kz/p+is/6fo - rP+W0JryBwkHnAAAAIgAAAByAAAAWwAAAEUAAAAxAAAAHwAAABMAAAAKAAAABAAAAAEAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA//8AgP// - AP///wD///8A////AP///wD///8A////AP///wD///8A/62tHP8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/eXko////AP///wD///8A//// - AP///wD///8A////AP///wD///8A////AMD//wD///8A////AP///wD///8A////AP///wD///8A//// - AP/Y2A7/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8AAQAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAGk5Kk+p+is/qforP+n6Kz/p+is/6forP+n6Kz/p+is/6forP+n6Kz/p+is/6forP+n6Kz/p+is/6fo - rP+n6Kz/p+is/5PNmPQwQjHKAAAAvAAAAL4AAAC+AAAAvwAAAL8AAAC/AAAAvwAAAL8AAAC/AAAAvwAA - AL8AAAC/AAAAvwAAAL8AAAC/AAAAvwAAAL8AAAC/AAAAvwAAAL8mNSfLpOSp/aforP+n6Kz/p+is/6fo - rP+n6Kz/p+is/6forP+n6Kz/p+is/6forP+n6Kz/p+is/6forP+n6Kz/p+is/6forP+n6Kz/p+is/6fo - rP+m56v/Nkw4vgAAAJoAAACIAAAAcwAAAFsAAABFAAAAMQAAAB8AAAATAAAACgAAAAQAAAABAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP// - AID//wD///8A////AP///wD///8A////AP///wD///8A////AP+trRz/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/3l5KP///wD///8A//// - AP///wD///8A////AP///wD///8A////AP///wDA//8A////AP///wD///8A////AP///wD///8A//// - AP///wD/2NgO/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A//// - AAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAaforJWn6Kz/p+is/6forP+n6Kz/p+is/6forP+n6Kz/p+is/6forP+n6Kz/p+is/6fo - rP+n6Kz/p+is/6forP+n6Kz/puer/nOgd+QYIhnCAAAAvQAAAL4AAAC+AAAAvwAAAL8AAAC/AAAAvwAA - AL8AAAC/AAAAvwAAAL8AAAC/AAAAvwAAAL8AAAC/AAAAvwAAAL8AAAC/AAAAv1l8XN2n6Kz/p+is/6fo - rP+n6Kz/p+is/6forP+n6Kz/p+is/6forP+n6Kz/p+is/6forP+n6Kz/p+is/6forP+n6Kz/p+is/6fo - rP+n6Kz/bplx4AAAAKoAAACdAAAAiwAAAHYAAABfAAAASQAAADQAAAAjAAAAFQAAAAsAAAAFAAAAAgAA - AAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAD//wCA//8A////AP///wD///8A////AP///wD///8A////AP///wD/ra0c/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv95eSj///8A//// - AP///wD///8A////AP///wD///8A////AP///wD///8AwP//AP///wD///8A////AP///wD///8A//// - AP///wD///8A/9jYDv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy////AP///wD///8A////AP///wD///8A////AP///wD///8A//// - AP///wABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAACX0ZsKp+is0qforP+n6Kz/p+is/6forP+n6Kz/p+is/6forP+n6Kz/p+is/6fo - rP+n6Kz/p+is/6forP+n6Kz/p+is/6forP+n6Kz/pOSp/XOgd+QrOyzJAAAAvAAAAL4AAAC+AAAAvgAA - AL8AAAC/AAAAvwAAAL8AAAC/AAAAvwAAAL8AAAC/AAAAvwAAAL8AAAC/AAAAvys7LMx0oXfnpuer/6fo - rP+n6Kz/p+is/6forP+n6Kz/p+is/6forP+n6Kz/p+is/6forP+n6Kz/p+is/6forP+n6Kz/p+is/6fo - rP+n6Kz/kMiU8wcKB7cAAACtAAAAoAAAAJEAAAB9AAAAZwAAAFEAAAA8AAAAKQAAABsAAAAQAAAACAAA - AAQAAAABAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAA//8AgP//AP///wD///8A////AP///wD///8A////AP///wD///8A/62tHP8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/eXko//// - AP///wD///8A////AP///wD///8A////AP///wD///8A////AMD//wD///8A////AP///wD///8A//// - AP///wD///8A////AP/Y2A7/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv///wD///8A////AP///wD///8A////AP///wD///8A//// - AP///wD///8AAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAKPjqCmn6Kzwp+is/6forP+n6Kz/p+is/6forP+n6Kz/p+is/6fo - rP+n6Kz/p+is/6forP+n6Kz/p+is/6forP+n6Kz/p+is/6forP+n6Kz/p+is/5XPmvVokWvgOE05zRAW - EMIAAAC+AAAAvgAAAL4AAAC/AAAAvwAAAL8AAAC/AAAAvwoPC8I2SzfQZIpn4ZPMl/Wn6Kz/p+is/6fo - rP+n6Kz/p+is/6forP+n6Kz/p+is/6forP+n6Kz/p+is/6forP+n6Kz/p+is/6forP+n6Kz/p+is/6fo - rP+n6Kz/oN6l+x8sIMYAAAC4AAAAsAAAAKYAAACXAAAAhQAAAHEAAABbAAAARgAAADMAAAAiAAAAFgAA - AA0AAAAHAAAAAwAAAAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAP//AID//wD///8A////AP///wD///8A////AP///wD///8A////AP+trRz/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/3l5 - KP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wDA//8A////AP///wD///8A//// - AP///wD///8A////AP///wD/2NgO/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL///8A////AP///wD///8A////AP///wD///8A//// - AP///wD///8A////AAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAApOSpR6forPyn6Kz/p+is/6forP+n6Kz/p+is/6fo - rP+n6Kz/p+is/6forP+n6Kz/p+is/6forP+n6Kz/p+is/6forP+n6Kz/p+is/6forP+n6Kz/p+is/6fo - rP+n6Kz/mdWe94a6iu58rYDqc6B35m+bc+V5p3zphrqK7pXPmvam56v/p+is/6forP+n6Kz/p+is/6fo - rP+n6Kz/p+is/6forP+n6Kz/p+is/6forP+n6Kz/p+is/6forP+n6Kz/p+is/6forP+n6Kz/p+is/6fo - rP+n6Kz/peWq/jhNOdAAAAC9AAAAugAAALQAAACsAAAAoAAAAJAAAAB9AAAAaAAAAFMAAAA/AAAALQAA - AB4AAAATAAAACgAAAAUAAAACAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAD//wCA//8A////AP///wD///8A////AP///wD///8A////AP///wD/ra0c/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv95eSj///8A////AP///wD///8A////AP///wD///8A////AP///wD///8AwP//AP///wD///8A//// - AP///wD///8A////AP///wD///8A/9jYDv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy////AP///wD///8A////AP///wD///8A//// - AP///wD///8A////AP///wABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACl5apgp+is/qforP+n6Kz/p+is/6fo - rP+n6Kz/p+is/6forP+n6Kz/p+is/6forP+n6Kz/p+is/6forP+n6Kz/p+is/6forP+n6Kz/p+is/6fo - rP+n6Kz/p+is/6forP+n6Kz/p+is/6forP+n6Kz/p+is/6forP+n6Kz/p+is/6forP+n6Kz/p+is/6fo - rP+n6Kz/p+is/6forP+n6Kz/p+is/6forP+n6Kz/p+is/6forP+n6Kz/p+is/6forP+n6Kz/p+is/6fo - rP+n6Kz/puer/0hkStMAAAC9AAAAvQAAALsAAAC4AAAAsQAAAKcAAACaAAAAiQAAAHYAAABhAAAATAAA - ADkAAAAoAAAAGgAAABAAAAAIAAAABAAAAAEAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAA//8AgP//AP///wD///8A////AP///wD///8A////AP///wD///8A/62t - HP8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/eXko////AP///wD///8A////AP///wD///8A////AP///wD///8A////AMD//wD///8A//// - AP///wD///8A////AP///wD///8A////AP/Y2A7/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv///wD///8A////AP///wD///8A//// - AP///wD///8A////AP///wD///8AAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAKbmq2un6Kz+p+is/6fo - rP+n6Kz/p+is/6forP+n6Kz/p+is/6forP+n6Kz/p+is/6forP+n6Kz/p+is/6forP+n6Kz/p+is/6fo - rP+n6Kz/p+is/6forP+n6Kz/p+is/6forP+n6Kz/p+is/6forP+n6Kz/p+is/6forP+n6Kz/p+is/6fo - rP+n6Kz/p+is/6forP+n6Kz/p+is/6forP+n6Kz/p+is/6forP+n6Kz/p+is/6forP+n6Kz/p+is/6fo - rP+n6Kz/puer/lFwU9EAAAC4AAAAuwAAAL0AAAC9AAAAuwAAALYAAACvAAAAowAAAJUAAACEAAAAcAAA - AFsAAABGAAAANAAAACMAAAAWAAAADQAAAAcAAAADAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAP//AID//wD///8A////AP///wD///8A////AP///wD///8A//// - AP+trRz/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/3l5KP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wDA//8A//// - AP///wD///8A////AP///wD///8A////AP///wD/2NgO/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL///8A////AP///wD///8A//// - AP///wD///8A////AP///wD///8A////AAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAApeWqYKfo - rPyn6Kz/p+is/6forP+n6Kz/p+is/6forP+n6Kz/p+is/6forP+n6Kz/p+is/6forP+n6Kz/p+is/6fo - rP+n6Kz/p+is/6forP+n6Kz/p+is/6forP+n6Kz/p+is/6forP+n6Kz/p+is/6forP+n6Kz/p+is/6fo - rP+n6Kz/p+is/6forP+n6Kz/p+is/6forP+n6Kz/p+is/6forP+n6Kz/p+is/6forP+n6Kz/p+is/6fo - rP+n6Kz/puar/k1rUMQAAACsAAAAswAAALgAAAC8AAAAvQAAALwAAAC5AAAAtAAAAKwAAACgAAAAkAAA - AH4AAABqAAAAVQAAAEAAAAAuAAAAHwAAABMAAAALAAAABQAAAAIAAAABAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD//wCA//8A////AP///wD///8A////AP///wD///8A//// - AP///wD/ra0c/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv95eSj///8A////AP///wD///8A////AP///wD///8A////AP///wD///8AwP// - AP///wD///8A////AP///wD///8A////AP///wD///8A/9jYDv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy////AP///wD///8A//// - AP///wD///8A////AP///wD///8A////AP///wABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AACl5apKp+is8KforP+n6Kz/p+is/6forP+n6Kz/p+is/6forP+n6Kz/p+is/6forP+n6Kz/p+is/6fo - rP+n6Kz/p+is/6forP+n6Kz/p+is/6forP+n6Kz/p+is/6forP+n6Kz/p+is/6forP+n6Kz/p+is/6fo - rP+n6Kz/p+is/6forP+n6Kz/p+is/6forP+n6Kz/p+is/6forP+n6Kz/p+is/6forP+n6Kz/p+is/6fo - rP+n6Kz/p+is/5jTnO0FBgWaAAAAowAAAK0AAAC1AAAAugAAAL0AAAC9AAAAuwAAALgAAACyAAAAqAAA - AJsAAACLAAAAeAAAAGQAAABPAAAAOwAAACkAAAAbAAAAEAAAAAkAAAAEAAAAAQAAAAEAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA//8AgP//AP///wD///8A////AP///wD///8A//// - AP///wD///8A/62tHP8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/eXko////AP///wD///8A////AP///wD///8A////AP///wD///8A//// - AMD//wD///8A////AP///wD///8A////AP///wD///8A////AP/Y2A7/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv///wD///8A//// - AP///wD///8A////AP///wD///8A////AP///wD///8AAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAKforCmn6KzVp+is/6forP+n6Kz/p+is/6forP+n6Kz/p+is/6forP+n6Kz/p+is/6fo - rP+n6Kz/p+is/6forP+n6Kz/p+is/6forP+n6Kz/p+is/6forP+n6Kz/p+is/6forP+n6Kz/p+is/6fo - rP+n6Kz/p+is/6forP+n6Kz/p+is/6forP+n6Kz/p+is/6forP+n6Kz/p+is/6forP+n6Kz/p+is/6fo - rP+n6Kz/p+is/6forP+n6Kz/bZdwxQAAAJkAAACmAAAArwAAALYAAAC7AAAAvQAAAL0AAAC7AAAAtgAA - AK8AAAClAAAAlwAAAIUAAAByAAAAXQAAAEkAAAA1AAAAJQAAABcAAAANAAAABwAAAAMAAAABAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP//AID//wD///8A////AP///wD///8A//// - AP///wD///8A////AP+trRz/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/3l5KP///wD///8A////AP///wD///8A////AP///wD///8A//// - AP///wDA//8A////AP///wD///8A////AP///wD///8A////AP///wD/2NgO/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL///8A//// - AP///wD///8A////AP///wD///8A////AP///wD///8A////AAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAp+isCqforJmn6Kz+p+is/6forP+n6Kz/p+is/6forP+n6Kz/p+is/6fo - rP+n6Kz/p+is/6forP+n6Kz/p+is/6forP+n6Kz/p+is/6forP+n6Kz/p+is/6forP+n6Kz/p+is/6fo - rP+n6Kz/p+is/6forP+n6Kz/p+is/6forP+n6Kz/p+is/6forP+n6Kz/p+is/6forP+n6Kz/p+is/6fo - rP+n6Kz/p+is/6forP+n6Kz/p+is/6bmq/02SzelAAAAnAAAAKkAAACyAAAAuAAAALsAAAC9AAAAvQAA - ALoAAAC1AAAArAAAAKEAAACSAAAAgAAAAGwAAABXAAAAQgAAADAAAAAgAAAAFAAAAAsAAAAGAAAAAgAA - AAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD//wCA//8A////AP///wD///8A//// - AP///wD///8A////AP///wD/ra0c/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv95eSj///8A////AP///wD///8A////AP///wD///8A//// - AP///wD///8AwP//AP///wD///8A////AP///wD///8A////AP///wD///8A/9jYDv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy//// - AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wABAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAp+isQ6forNqn6Kz/p+is/6forP+n6Kz/p+is/6fo - rP+n6Kz/p+is/6forP+n6Kz/p+is/6forP+n6Kz/p+is/6forP+n6Kz/p+is/6forP+n6Kz/p+is/6fo - rP+n6Kz/p+is/6forP+n6Kz/p+is/6forP+n6Kz/p+is/6forP+n6Kz/p+is/6forP+n6Kz/p+is/6fo - rP+n6Kz/p+is/6forP+n6Kz/p+is/6forP+n6Kz/mdWe6woOCpUAAACgAAAArAAAALQAAAC5AAAAvAAA - AL0AAAC8AAAAuAAAALIAAACpAAAAnQAAAI0AAAB5AAAAZQAAAFAAAAA8AAAAKwAAABwAAAAQAAAACQAA - AAQAAAABAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA//8AgP//AP///wD///8A//// - AP///wD///8A////AP///wD///8A/62tHP8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/eXko////AP///wD///8A////AP///wD///8A//// - AP///wD///8A////AMD//wD///8A////AP///wD///8A////AP///wD///8A////AP/Y2A7/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8AAQAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACn6KwGp+isc6forO+n6Kz/p+is/6fo - rP+n6Kz/p+is/6forP+n6Kz/p+is/6forP+n6Kz/p+is/6forP+n6Kz/p+is/6forP+n6Kz/p+is/6fo - rP+n6Kz/p+is/6forP+n6Kz/p+is/6forP+n6Kz/p+is/6forP+n6Kz/p+is/6forP+n6Kz/p+is/6bm - q+6m5qvpp+is/6forP+n6Kz/p+is/6forP+n6Kz/p+is/6forP95p3zKAAAAlQAAAKMAAACvAAAAtgAA - ALsAAAC9AAAAvQAAALsAAAC3AAAAsAAAAKYAAACYAAAAhwAAAHMAAABeAAAASQAAADYAAAAlAAAAGAAA - AA4AAAAHAAAABAAAAAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP//AID//wD///8A//// - AP///wD///8A////AP///wD///8A////AP+trRz/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/3l5KP///wD///8A////AP///wD///8A//// - AP///wD///8A////AP///wDA//8A////AP///wD///8A////AP///wD///8A////AP///wD/2NgO/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AAEAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACn6KwPp+isc6fo - rOCn6Kz/p+is/6forP+n6Kz/p+is/6forP+n6Kz/p+is/6forP+n6Kz/p+is/6forP+n6Kz/p+is/6fo - rP+n6Kz/p+is/6forP+n6Kz/p+is/6forP+n6Kz/p+is/6forP+n6Kz/p+is/6forP+n6Kz/puar6ZzZ - oYZNa1Aai8KQPKforPqn6Kz/p+is/6forP+n6Kz/p+is/6forP+n6Kz/p+is/kNeRagAAACaAAAApwAA - ALEAAAC4AAAAuwAAAL0AAAC9AAAAugAAALUAAACtAAAAogAAAJMAAACBAAAAbQAAAFgAAABDAAAAMQAA - ACEAAAAUAAAACwAAAAYAAAACAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD//wCA//8A//// - AP///wD///8A////AP///wD///8A////AP///wD/ra0c/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv95eSj///8A////AP///wD///8A//// - AP///wD///8A////AP///wD///8AwP//AP///wD///8A////AP///wD///8A////AP///wD///8A/9jY - Dv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wABAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AACn6KwEp+isVaforMCn6Kz8p+is/6forP+n6Kz/p+is/6forP+n6Kz/p+is/6forP+n6Kz/p+is/6fo - rP+n6Kz/p+is/6forP+n6Kz/p+is/6forP+n6Kz/p+is/6forP+n6Kz/p+is/6forP2k5KnDmtafZT9X - QRAAAAAIAAAABwAAAAWj46h/p+is/6forP+n6Kz/p+is/6forP+n6Kz/p+is/6forP+d2qLxExoUlgAA - AJ4AAACrAAAAswAAALkAAAC8AAAAvgAAALwAAAC5AAAAswAAAKoAAACdAAAAjgAAAHsAAABmAAAAUQAA - AD0AAAArAAAAHAAAABEAAAAKAAAABAAAAAIAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA//8AgP// - AP///wD///8A////AP///wD///8A////AP///wD///8A/62tHP8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/eXko////AP///wD///8A//// - AP///wD///8A////AP///wD///8A////AMD//wD///8A////AP///wD///8A////AP///wD///8A//// - AP/Y2A7/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8AAQAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAp+isFaforGCn6Kyup+is9KforP+n6Kz/p+is/6forP+n6Kz/p+is/6fo - rP+n6Kz/p+is/6forP+n6Kz/p+is/6forP+n6Kz/p+is/6forP+n6KzzpOSpuaHgpnOJvo0hAAAABQAA - AAQAAAAEAAAAAgAAAAEAAAABfa6BBKbnq8mn6Kz/p+is/6forP+n6Kz/p+is/6forP+n6Kz/p+is/4K1 - htIAAACUAAAAowAAAK4AAAC1AAAAuwAAAL0AAAC9AAAAuwAAALgAAACwAAAApgAAAJkAAACIAAAAdAAA - AF8AAABKAAAANwAAACYAAAAZAAAADgAAAAcAAAAEAAAAAQAAAAEAAAAAAAAAAAAAAAAAAAAAAAAAAP// - AID//wD///8A////AP///wD///8A////AP///wD///8A////AP+trRz/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/3l5KP///wD///8A//// - AP///wD///8A////AP///wD///8A////AP///wDA//8A////AP///wD///8A////AP///wD///8A//// - AP///wD/2NgO/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A//// - AAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAKforASn6Kwsp+isWaforIen6Ky0p+is0qfo - rOen6Kz1p+is/6forP+n6Kzyp+is6qbnq9Sm56u1peWqlqTjqWeh4KY3b5tzCQAAAAIAAAACAAAAAQAA - AAEAAAABAAAAAQAAAAAAAAAAAAAAAAAAAAGi4qcmp+is9KforP+n6Kz/p+is/6forP+n6Kz/p+is/6fo - rP+n6Kz/UXBTsAAAAJkAAACmAAAAsQAAALgAAAC7AAAAvQAAAL0AAAC7AAAAtQAAAK4AAACjAAAAlAAA - AIIAAABtAAAAWAAAAEQAAAAxAAAAIQAAABUAAAAMAAAABgAAAAMAAAABAAAAAAAAAAAAAAAAAAAAAAAA - AAD//wCA//8A////AP///wD///8A////AP///wD///8A////AP///wD/ra0c/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv95eSj///8A//// - AP///wD///8A////AP///wD///8A////AP///wD///8AwP//AP///wD///8A////AP///wD///8A//// - AP///wD///8A/9jYDv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy////AP///wD///8A////AP///wD///8A////AP///wD///8A//// - AP///wABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAabmq2un6Kz/p+is/6forP+n6Kz/p+is/6fo - rP+n6Kz/p+is/6HgpvYcJhyZAAAAnQAAAKoAAACzAAAAuQAAALwAAAC+AAAAvAAAALkAAACzAAAAqgAA - AJ4AAACOAAAAfAAAAGcAAABSAAAAPQAAACwAAAAdAAAAEgAAAAoAAAAEAAAAAgAAAAEAAAAAAAAAAAAA - AAAAAAAA//8AgP//AP///wD///8A////AP///wD///8A////AP///wD///8A/62tHP8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/eXko//// - AP///wD///8A////AP///wD///8A////AP///wD///8A////AMD//wD///8A////AP///wD///8A//// - AP///wD///8A////AP/Y2A7/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv///wD///8A////AP///wD///8A////AP///wD///8A//// - AP///wD///8AAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABUdFYCpueruaforP+n6Kz/p+is/6fo - rP+n6Kz/p+is/6forP+n6Kz/i8GP2wECAZMAAACiAAAArQAAALUAAAC7AAAAvQAAAL0AAAC7AAAAuAAA - ALEAAACnAAAAmgAAAIgAAAB1AAAAYQAAAEwAAAA4AAAAJwAAABkAAAAPAAAACAAAAAQAAAABAAAAAQAA - AAAAAAAAAAAAAP//AID//wD///8A////AP///wD///8A////AP///wD///8A////AP+trRz/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/3l5 - KP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wDA//8A////AP///wD///8A//// - AP///wD///8A////AP///wD/2NgO/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL///8A////AP///wD///8A////AP///wD///8A//// - AP///wD///8A////AAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAKHgphun6Kztp+is/6fo - rP+n6Kz/p+is/6forP+n6Kz/p+is/6forP9eg2G3AAAAmAAAAKYAAACwAAAAtwAAALsAAAC9AAAAvQAA - ALsAAAC1AAAArgAAAKMAAACUAAAAgwAAAG8AAABaAAAARQAAADIAAAAiAAAAFgAAAA0AAAAHAAAAAwAA - AAEAAAAAAAAAAAAAAAD//wCA//8A////AP///wD///8A////AP///wD///8A////AP///wD/ra0c/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv95eSj///8A////AP///wD///8A////AP///wD///8A////AP///wD///8AwP//AP///wD///8A//// - AP///wD///8A////AP///wD///8A/9jYDv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy////AP///wD///8A////AP///wD///8A//// - AP///wD///8A////AP///wABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABpeWqWKfo - rP+n6Kz/p+is/6forP+n6Kz/p+is/6forP+n6Kz/pOOp+SY1J50AAACdAAAAqQAAALIAAAC4AAAAvAAA - AL0AAAC8AAAAuQAAALQAAACrAAAAnwAAAI8AAAB9AAAAaAAAAFMAAABAAAAALgAAAB8AAAATAAAACgAA - AAUAAAACAAAAAQAAAAAAAAAA//8AgP//AP///wD///8A////AP///wD///8A////AP///wD///8A/62t - HP8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/eXko////AP///wD///8A////AP///wD///8A////AP///wD///8A////AMD//wD///8A//// - AP///wD///8A////AP///wD///8A////AP/Y2A7/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv///wD///8A////AP///wD///8A//// - AP///wD///8A////AP///wD///8AAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAGm5quop+is/6forP+n6Kz/p+is/6forP+n6Kz/p+is/6forP+RypbjAwUDkwAAAKEAAACsAAAAtQAA - ALoAAAC9AAAAvQAAALsAAAC4AAAAsQAAAKgAAACaAAAAigAAAHYAAABiAAAATQAAADoAAAAoAAAAGgAA - ABAAAAAJAAAABAAAAAEAAAABAAAAAP//AID//wD///8A////AP///wD///8A////AP///wD///8A//// - AP+trRz/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/3l5KP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wDA//8A//// - AP///wD///8A////AP///wD///8A////AP///wD/2NgO/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL///8A////AP///wD///8A//// - AP///wD///8A////AP///wD///8A////AAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAntujEqforOSn6Kz/p+is/6forP+n6Kz/p+is/6forP+n6Kz/p+is/2qTbcAAAACXAAAApQAA - AK8AAAC3AAAAuwAAAL0AAAC9AAAAuwAAALYAAACvAAAApAAAAJYAAACFAAAAcAAAAFwAAABHAAAANAAA - ACQAAAAXAAAADQAAAAcAAAADAAAAAQAAAAD//wCA//8A////AP///wD///8A////AP///wD///8A//// - AP///wD/ra0c/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv95eSj///8A////AP///wD///8A////AP///wD///8A////AP///wD///8AwP// - AP///wD///8A////AP///wD///8A////AP///wD///8A/9jYDv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy////AP///wD///8A//// - AP///wD///8A////AP///wD///8A////AP///wABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAGk5KlHp+is/qforP+n6Kz/p+is/6forP+n6Kz/p+is/6forP+l5ar8M0c1oQAA - AJwAAACpAAAAsgAAALgAAAC7AAAAvQAAALwAAAC6AAAAtAAAAKwAAACgAAAAkQAAAH8AAABqAAAAVQAA - AEEAAAAvAAAAHwAAABMAAAALAAAABgAAAAIAAAAB//8AgP//AP///wD///8A////AP///wD///8A//// - AP///wD///8A/62tHP8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/eXko////AP///wD///8A////AP///wD///8A////AP///wD///8A//// - AMD//wD///8A////AP///wD///8A////AP///wD///8A////AP/Y2A7/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv///wD///8A//// - AP///wD///8A////AP///wD///8A////AP///wD///8AAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAabmq5Wn6Kz/p+is/6forP+n6Kz/p+is/6forP+n6Kz/p+is/5fS - nOkJDQmUAAAAoAAAAKwAAAC0AAAAuQAAALwAAAC9AAAAvAAAALgAAACyAAAAqQAAAJwAAACLAAAAeQAA - AGQAAABPAAAAOwAAACoAAAAcAAAAEAAAAAkAAAAEAAAAAf//AID//wD///8A////AP///wD///8A//// - AP///wD///8A////AP+trRz/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/3l5KP///wD///8A////AP///wD///8A////AP///wD///8A//// - AP///wDA//8A////AP///wD///8A////AP///wD///8A////AP///wD/2NgO/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL///8A//// - AP///wD///8A////AP///wD///8A////AP///wD///8A////AAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACY05wLp+is2aforP+n6Kz/p+is/6forP+n6Kz/p+is/6fo - rP+n6Kz/daN5yAAAAJUAAACjAAAArwAAALYAAAC7AAAAvQAAAL0AAAC7AAAAtwAAAK8AAAClAAAAlwAA - AIYAAABzAAAAXgAAAEkAAAA2AAAAJQAAABgAAAAOAAAABwAAAAP//wCA//8A////AP///wD///8A//// - AP///wD///8A////AP///wD/ra0c/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv95eSj///8A////AP///wD///8A////AP///wD///8A//// - AP///wD///8AwP//AP///wD///8A////AP///wD///8A////AP///wD///8A/9jYDv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy//// - AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wABAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAaTjqTin6Kz7p+is/6forP+n6Kz/p+is/6fo - rP+n6Kz/p+is/6bnq/5AWUKnAAAAmgAAAKcAAACxAAAAuAAAALsAAAC9AAAAvQAAALoAAAC1AAAArQAA - AKEAAACSAAAAgAAAAGwAAABXAAAAQwAAADAAAAAgAAAAFAAAAAsAAAAG/f0Agf//AP///wD///8A//// - AP///wD///8A////AP///wD///8A/62tHP8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/eXko////AP///wD///8A////AP///wD///8A//// - AP///wD///8A////AMD//wD///8A////AP///wD///8A////AP///wD///8A////AP/Y2A7/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8AAQAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABpuarg6forP+n6Kz/p+is/6fo - rP+n6Kz/p+is/6forP+n6Kz/nNmh7xAWEJUAAACfAAAAqwAAALMAAAC5AAAAvAAAAL0AAAC8AAAAuQAA - ALMAAACpAAAAnQAAAI0AAAB6AAAAZgAAAFAAAAA9AAAAKwAAABwAAAARAAAACvv7AIL//wD///8A//// - AP///wD///8A////AP///wD///8A////AP+trRz/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/3l5KP///wD///8A////AP///wD///8A//// - AP///wD///8A////AP///wDA//8A////AP///wD///8A////AP///wD///8A////AP///wD/2NgO/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AAEAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAIvCkAam56vMp+is/6fo - rP+n6Kz/p+is/6forP+n6Kz/p+is/6forP+AsYTPAAAAlAAAAKMAAACuAAAAtQAAALsAAAC9AAAAvQAA - ALsAAAC3AAAAsAAAAKYAAACYAAAAiAAAAHQAAABfAAAASgAAADcAAAAlAAAAGAAAAA75+QCD//8A//// - AP///wD///8A////AP///wD///8A////AP///wD/ra0c/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv95eSj///8A////AP///wD///8A//// - AP///wD///8A////AP///wD///8AwP//AP///wD///8A////AP///wD///8A////AP///wD///8A/9jY - Dv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wABAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABo+OoK6fo - rPan6Kz/p+is/6forP+n6Kz/p+is/6forP+n6Kz/p+is/01rUK0AAACZAAAApgAAALEAAAC4AAAAuwAA - AL0AAAC9AAAAuwAAALUAAACtAAAAogAAAJQAAACCAAAAbQAAAFgAAABDAAAAMQAAACEAAAAV9PQAhv// - AP///wD///8A////AP///wD///8A////AP///wD///8A/62tHP8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/eXko////AP///wD///8A//// - AP///wD///8A////AP///wD///8A////AMD//wD///8A////AP///wD///8A////AP///wD///8A//// - AP/Y2A7/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8AAQAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAGm5qtxp+is/6forP+n6Kz/p+is/6forP+n6Kz/p+is/6forP+g3qX0GiMamAAAAJ4AAACqAAAAswAA - ALkAAAC8AAAAvgAAALwAAAC5AAAAswAAAKoAAACeAAAAjgAAAHsAAABnAAAAUgAAAD0AAAArAAAAHe7u - AIn//wD///8A////AP///wD///8A////AP///wD///8A////AP+trRz/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/3l5KP///wD///8A//// - AP///wD///8A////AP///wD///8A////AP///wDA//8A////AP///wD///8A////AP///wD///8A//// - AP///wD/2NgO/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A//// - AAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAVHRWAqbnq76n6Kz/p+is/6forP+n6Kz/p+is/6forP+n6Kz/p+is/4i9jNgAAACUAAAAogAA - AK0AAAC1AAAAuwAAAL0AAAC9AAAAuwAAALgAAACxAAAApgAAAJkAAACIAAAAdQAAAGAAAABLAAAANwAA - ACfp6QCM//8A////AP///wD///8A////AP///wD///8A////AP///wD/ra0c/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv95eSj///8A//// - AP///wD///8A////AP///wD///8A////AP///wD///8AwP//AP///wD///8A////AP///wD///8A//// - AP///wD///8A/9jYDv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy////AP///wD///8A////AP///wD///8A////AP///wD///8A//// - AP///wABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAACi4acfp+is76forP+n6Kz/p+is/6forP+n6Kz/p+is/6forP+n6Kz/Wn1ctgAA - AJgAAACmAAAAsAAAALcAAAC7AAAAvQAAAL0AAAC7AAAAtQAAAK4AAACjAAAAlAAAAIIAAABuAAAAWQAA - AEUAAAAy4eEAkf//AP///wD///8A////AP///wD///8A////AP///wD///8A/62tHP8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/eXko//// - AP///wD///8A////AP///wD///8A////AP///wD///8A////AMD//wD///8A////AP///wD///8A//// - AP///wD///8A////AP/Y2A7/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv///wD///8A////AP///wD///8A////AP///wD///8A//// - AP///wD///8AAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAaXlql+n6Kz/p+is/6forP+n6Kz/p+is/6forP+n6Kz/p+is/6Pj - qPgjMSScAAAAnQAAAKkAAACzAAAAuQAAALwAAAC9AAAAvAAAALkAAACzAAAAqwAAAJ8AAACPAAAAfAAA - AGgAAABTAAAAP9raAJb//wD///8A////AP///wD///8A////AP///wD///8A////AP+trRz/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/3l5 - KP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wDA//8A////AP///wD///8A//// - AP///wD///8A////AP///wD/2NgO/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL///8A////AP///wD///8A////AP///wD///8A//// - AP///wD///8A////AAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABpuerraforP+n6Kz/p+is/6forP+n6Kz/p+is/6fo - rP+n6Kz/kMiU4AMFA5MAAAChAAAArQAAALUAAAC6AAAAvQAAAL0AAAC7AAAAuAAAALEAAACnAAAAmgAA - AIoAAAB2AAAAYQAAAE3Q0ACd//8A////AP///wD///8A////AP///wD///8A////AP///wD/ra0c/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv95eSj///8A////AP///wD///8A////AP///wD///8A////AP///wD///8AwP//AP///wD///8A//// - AP///wD///8A////AP///wD///8A/9jYDv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy////AP///wD///8A////AP///wD///8A//// - AP///wD///8A////AP///wABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAJ7coxSn6Kznp+is/6forP+n6Kz/p+is/6fo - rP+n6Kz/p+is/6forP9nj2q9AAAAlwAAAKUAAACvAAAAtwAAALsAAAC9AAAAvQAAALsAAAC2AAAArwAA - AKMAAACVAAAAhAAAAHAAAABbyMgAo///AP///wD///8A////AP///wD///8A////AP///wD///8A/62t - HP8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/eXko////AP///wD///8A////AP///wD///8A////AP///wD///8A////AMD//wD///8A//// - AP///wD///8A////AP///wD///8A////AP/Y2A7/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv///wD///8A////AP///wD///8A//// - AP///wD///8A////AP///wD///8AAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABpeWqTKforP6n6Kz/p+is/6fo - rP+n6Kz/p+is/6forP+n6Kz/peWq+y9CMZ8AAACcAAAAqQAAALIAAAC4AAAAvAAAAL0AAAC8AAAAuQAA - ALQAAACsAAAAoAAAAJEAAAB/AAAAasDAAKr//wD///8A////AP///wD///8A////AP///wD///8A//// - AP+trRz/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/3l5KP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wDA//8A//// - AP///wD///8A////AP///wD///8A////AP///wD/2NgO/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL///8A////AP///wD///8A//// - AP///wD///8A////AP///wD///8A////AAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAGm5qubp+is/6fo - rP+n6Kz/p+is/6forP+n6Kz/p+is/6forP+X0ZvnBwkHlAAAAKAAAACsAAAAtAAAALoAAAC8AAAAvQAA - ALsAAAC4AAAAsgAAAKkAAACcAAAAiwAAAHm3twCy//8A////AP///wD///8A////AP///wD///8A//// - AP///wD/ra0c/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv95eSj///8A////AP///wD///8A////AP///wD///8A////AP///wD///8AwP// - AP///wD///8A////AP///wD///8A////AP///wD///8A/9jYDv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy////AP///wD///8A//// - AP///wD///8A////AP///wD///8A////AP///wABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAmtafDafo - rNyn6Kz/p+is/6forP+n6Kz/p+is/6forP+n6Kz/p+is/3KedcYAAACWAAAApAAAAK8AAAC2AAAAuwAA - AL0AAAC9AAAAuwAAALcAAACvAAAApQAAAJcAAACFsLAAuf//AP///wD///8A////AP///wD///8A//// - AP///wD///8A/62tHP8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/eXko////AP///wD///8A////AP///wD///8A////AP///wD///8A//// - AMD//wD///8A////AP///wD///8A////AP///wD///8A////AP/Y2A7/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv///wD///8A//// - AP///wD///8A////AP///wD///8A////AP///wD///8AAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAGk5Kk8p+is/KforP+n6Kz/p+is/6forP+n6Kz/p+is/6forP+m56v9PFM9pQAAAJoAAACoAAAAsQAA - ALgAAAC7AAAAvQAAAL0AAAC6AAAAtQAAAKwAAAChAAAAkaurAL///wD///8A////AP///wD///8A//// - AP///wD///8A////AP+trRz/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/3l5KP///wD///8A////AP///wD///8A////AP///wD///8A//// - AP///wDA//8A////AP///wD///8A////AP///wD///8A////AP///wD/2NgO/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL///8A//// - AP///wD///8A////AP///wD///8A////AP///wD///8A////AAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAabmq4in6Kz/p+is/6forP+n6Kz/p+is/6forP+n6Kz/p+is/5vYoO0OEw6UAAAAnwAA - AKsAAAC0AAAAuQAAALwAAAC9AAAAvAAAALgAAACyAAAAqQAAAJympgDF//8A////AP///wD///8A//// - AP///wD///8A////AP///wD/ra0c/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv95eSj///8A////AP///wD///8A////AP///wD///8A//// - AP///wD///8AwP//AP///wD///8A////AP///wD///8A////AP///wD///8A/9jYDv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy//// - AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wABAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAACPx5QHpuer0aforP+n6Kz/p+is/6forP+n6Kz/p+is/6forP+n6Kz/fa6BzgAA - AJQAAACjAAAArgAAALUAAAC7AAAAvQAAAL0AAAC7AAAAtwAAAK8AAACkoqIAyv//AP///wD///8A//// - AP///wD///8A////AP///wD///8A/62tHP8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/eXko////AP///wD///8A////AP///wD///8A//// - AP///wD///8A////AMD//wD///8A////AP///wD///8A////AP///wD///8A////AP/Y2A7/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8AAQAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAaPjqC6n6Kz4p+is/6forP+n6Kz/p+is/6forP+n6Kz/p+is/6fo - rP5JZkyrAAAAmgAAAKcAAACxAAAAuAAAALsAAAC9AAAAvQAAALoAAACzAAAAqZ+fAM3//wD///8A//// - AP///wD///8A////AP///wD///8A////AP+trRz/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/3l5KP///wD///8A////AP///wD///8A//// - AP///wD///8A////AP///wDA//8A////AP///wD///8A////AP///wD///8A////AP///wD/2NgO/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AAEAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABpuardaforP+n6Kz/p+is/6forP+n6Kz/p+is/6fo - rP+n6Kz/ntyj8xUdFpYAAACeAAAAqgAAALMAAAC5AAAAvAAAALwAAAC7AAAAtQAAAKyengDP//8A//// - AP///wD///8A////AP///wD///8A////AP///wD/ra0c/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv95eSj///8A////AP///wD///8A//// - AP///wD///8A////AP///wD///8AwP//AP///wD///8A////AP///wD///8A////AP///wD///8A/9jY - Dv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wABAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAH2ugQSm56vCp+is/6forP+n6Kz/p+is/6fo - rP+n6Kz/p+is/6forP+Gu4rWAAAAlAAAAKMAAACtAAAAtQAAALkAAAC7AAAAuAAAALMAAACqnp4Azv// - AP///wD///8A////AP///wD///8A////AP///wD///8A/62tHP8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/eXko////AP///wD///8A//// - AP///wD///8A////AP///wD///8A////AMD//wD///8A////AP///wD///8A////AP///wD///8A//// - AP/Y2A7/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8AAQAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABouKnIqforPKn6Kz/p+is/6fo - rP+n6Kz/p+is/6forP+n6Kz/p+is/1Z4WbMAAACXAAAApQAAAK4AAACzAAAAtQAAALMAAACuAAAAo6Gh - AMv//wD///8A////AP///wD///8A////AP///wD///8A////AP+trRz/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/3l5KP///wD///8A//// - AP///wD///8A////AP///wD///8A////AP///wDA//8A////AP///wD///8A////AP///wD///8A//// - AP///wD/2NgO/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A//// - AAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAGl5apjp+is/6fo - rP+n6Kz/p+is/6forP+n6Kz/p+is/6forP+i4af3IC0hmAAAAJkAAACjAAAAqQAAAKwAAACpAAAAowAA - AJmmpgDF//8A////AP///wD///8A////AP///wD///8A////AP///wD/ra0c/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv95eSj///8A//// - AP///wD///8A////AP///wD///8A////AP///wD///8AwP//AP///wD///8A////AP///wD///8A//// - AP///wD///8A/9jYDv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy////AP///wD///8A////AP///wD///8A////AP///wD///8A//// - AP///wABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAabn - q7Kn6Kz/p+is/6forP+n6Kz/p+is/6forP+n6Kz/p+is/4/Gk90BAgGLAAAAlQAAAJwAAACeAAAAnAAA - AJUAAACKrKwAvv//AP///wD///8A////AP///wD///8A////AP///wD///8A/62tHP8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/eXko//// - AP///wD///8A////AP///wD///8A////AP///wD///8A////AMD//wD///8A////AP///wD///8A//// - AP///wD///8A////AP/Y2A7/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv///wD///8A////AP///wD///8A////AP///wD///8A//// - AP///wD///8AAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AACg3qUYp+is6qforP+n6Kz/p+is/6forP+n6Kz/p+is/6forP+n6Kz/Z5BrswAAAIUAAACLAAAAjQAA - AIoAAACDAAAAd7S0ALX//wD///8A////AP///wD///8A////AP///wD///8A////AP+trRz/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/3l5 - KP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wDA//8A////AP///wD///8A//// - AP///wD///8A////AP///wD/2NgO/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL///8A////AP///wD///8A////AP///wD///8A//// - AP///wD///8A////AAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAaXlqlGn6Kz/p+is/6forP+n6Kz/p+is/6forP+n6Kz/p+is/6TkqfoyRjSIAAAAdwAA - AHkAAAB2AAAAbgAAAGO0tACg//8A////AP///wD///8A////AP///wD///8A////AP///wD/uLgZ/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv95eSj///8A////AP///wD///8A////AP///wD///8A////AP///wD///8AwP//AP///wD///8A//// - AP///wD///8A////AP///wD///8A////AP8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/eXko////AP///wD///8A////AP///wD///8A//// - AP///wD///8A////AMQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAABpuaroKforP+n6Kz/p+is/6forP+n6Kz/p+is/6forP+n6Kz/mdSd3gkM - CWQAAABiAAAAXgAAAFgAAABNgIAAaP//AP///wD///8A////AP///wD///8A////AP///wD///8A/+Li - Cf8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/ra0c////AP///wD///8A////AP///wD///8A////AP///wD///8A////AIT//wDH//8A//// - AP///wD///8A////AP///wD///8A////AP///wD/h4cl/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/7i4Gf///wD///8A////AP///wD///8A//// - AP///wD///8A////AP///wCHAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAJzZoQ+n6Kzgp+is/6forP+n6Kz/p+is/6forP+n6Kz/p+is/6fo - rP+CtYalAAAASgAAAEcAAABAAAAAOAAAAC7+/gD4//8A////AP///wD///8A////AP///wD///8A//// - AP///wD/R0cw/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/+LiCf///wD///8A////AP///wD///8A////AP///wD///8A////AP///wBH//8Ai/// - AP///wD///8A////AP///wD///8A////AP///wD///8A/8PDFf8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/0dHMP/29gL///8A////AP///wD///8A//// - AP///wD///8A////AP///wD///8ASwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABpOSpQaforP2n6Kz/p+is/6forP+n6Kz/p+is/6fo - rP+n6Kz/puer/F+EYl8AAAAyAAAALQAAACYAAAAf9/cAwf//AP///wD///8A////AP///wD///8A//// - AP///wD///8A/6GhH/8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/1paLf///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8AC/// - AE///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD/Wlot/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv+trRz///8A////AP///wD///8A//// - AP///wD///8A////AP///wD///8A////AA8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAGm5quOp+is/6forP+n6Kz/p+is/6fo - rP+n6Kz/p+is/6forP+g36XIAAAAIQAAAB0AAAAYAAAAE/LyAIb//wD///8A////AP///wD///8A//// - AP///wD///8A////AP/29gL/R0cw/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv/DwxX///8A////AP///wD///8A////AP///wD///8A////AP///wD///8AzgAA - AAD//wAP//8A////AP///wD///8A////AP///wD///8A////AP///wD///8A/9jYDv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv9qair/9vYC////AP///wD///8A//// - AP///wD///8A////AP///wD///8A////AM4AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAlc+ZCaforNSn6Kz/p+is/6fo - rP+n6Kz/p+is/6forP+g36WuT25SJgAAABMAAAAQAAAADQAAAArs7ABE//8A////AP///wD///8A//// - AP///wD///8A////AP///wD///8A/7i4Gf8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv95eSj///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A//// - AI4AAAAAAAAAAP//AL7//wD///8A////AP///wD///8A////AP///wD///8A////AP///wD/oaEf/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv9HRzD/4uIJ////AP///wD///8A//// - AP///wD///8A////AP///wD///8A////AP///wB/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAGk46kyp+is+afo - rP+n6Kz/p+is/6bnq+yb159cAAAACwAAAAoAAAAKAAAACAAAAAcAAAAEAAAAA///AP7//wD///8A//// - AP///wD///8A////AP///wD///8A////AP///wD/lZUi/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv9HRzD/9vYC////AP///wD///8A////AP///wD///8A////AP///wD///8A//// - AP///wA/AAAAAAAAAAD//wBv//8A////AP///wD///8A////AP///wD///8A////AP///wD///8A//// - AP+VlSL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv9HRzD/4uIJ////AP///wD///8A//// - AP///wD///8A////AP///wD///8A////AP///wD///8AHwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAKbm - q3yn6Kz/p+is/6bnq66NxZIaAAAABAAAAAQAAAAEAAAABAAAAAMAAAACAAAAAQAAAAH//wCe//8A//// - AP///wD///8A////AP///wD///8A////AP///wD///8A////AP+VlSL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv9aWi3/4uIJ////AP///wD///8A////AP///wD///8A////AP///wD///8A//// - AP///wDuAAAAAAAAAAAAAAAA//8ABf//AO7//wD///8A////AP///wD///8A////AP///wD///8A//// - AP///wD///8A/8PDFf9HRzD/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv95eSj/9vYC////AP///wD///8A//// - AP///wD///8A////AP///wD///8A////AP///wD///8AlAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AACn6KwDp+istqXlql0AAAABAAAAAQAAAAEAAAABAAAAAQAAAAEAAAABAAAAAQAAAAAAAAAA//8ANP// - AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A/62tHP8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv+HhyX/9vYC////AP///wD///8A////AP///wD///8A////AP///wD///8A//// - AP///wD///8AhAAAAAAAAAAAAAAAAAAAAAD//wCE//8A////AP///wD///8A////AP///wD///8A//// - AP///wD///8A////AP///wD/7OwF/5WVIv9HRzD/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/3l5KP/Y2A7///8A////AP///wD///8A//// - AP///wD///8A////AP///wD///8A////AP///wD///8A////ACQAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAD//wCU//8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD/7OwF/5WV - Iv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIy - Mv8yMjL/MjIy/3l5KP/Y2A7///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A//// - AP///wD///8A1///AAUAAAAAAAAAAAAAAAAAAAAAAAAAAP//AL///wD///8A////AP///wD///8A//// - AP///wD///8A////AP///wD///8A////AP///wD/9vYC/87OEv+trRz/ra0c/62tHP+trRz/ra0c/62t - HP+trRz/ra0c/62tHP+trRz/ra0c/62tHP+trRz/ra0c/62tHP+trRz/ra0c/62tHP+trRz/ra0c/62t - HP+trRz/ra0c/62tHP+trRz/ra0c/62tHP+trRz/w8MV/+zsBf///wD///8A////AP///wD///8A//// - AP///wD///8A////AP///wD///8A////AP///wD///8A////AIcAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAA//8AFf//AOf//wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A//// - AP///wD/9vYC/87OEv+trRz/ra0c/62tHP+trRz/ra0c/62tHP+trRz/ra0c/62tHP+trRz/ra0c/62t - HP+trRz/ra0c/62tHP+trRz/ra0c/62tHP+trRz/ra0c/62tHP+trRz/ra0c/62tHP+trRz/ra0c/62t - HP+trRz/w8MV/+zsBf///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A//// - AP///wD///8A////AGQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD//wA0//8A////AP///wD///8A//// - AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A//// - AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A//// - AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A//// - AP///wD///8A////AP///wD///8A////AP///wD///8A////AMEAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAD//wBQ//8A////AP///wD///8A////AP///wD///8A////AP///wD///8A//// - AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A//// - AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A//// - AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A//// - AP///wD///8A////AJ8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP//AG///wD///8A//// - AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A//// - AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A//// - AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A//// - AP///wD///8A////AP///wD///8A////AP///wD///8A////AOn//wAqAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAP//AIr//wD///8A////AP///wD///8A////AP///wD///8A//// - AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A//// - AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A//// - AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A//// - AP///wD///8A////ANn//wAIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA//8Aqf// - AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A//// - AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A//// - AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A//// - AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wBKAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA//8Auf//AP///wD///8A////AP///wD///8A//// - AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A//// - AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A//// - AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A//// - AP///wD///8A////AP///wA4AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAD//wC5//8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A//// - AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A//// - AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A//// - AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wBKAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD//wC5//8A////AP///wD///8A//// - AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A//// - AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A//// - AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A//// - AP///wD///8A////APn//wBKAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAP//AH///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A//// - AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A//// - AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A//// - AP///wD///8A////AP///wD///8A////AP///wD///8A////ANn//wA4AAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP//AJn//wD///8A//// - AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A//// - AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A//// - AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A//// - AP///wD///8A////AMn//wAqAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAA//8ARP//ANf//wD///8A////AP///wD///8A////AP///wD///8A//// - AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A//// - AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A//// - AP///wD///8A////AP///wD///8A////AP///wD///8A////AJ///wAIAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA//8AX/// - APb//wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A//// - AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A//// - AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A//// - AP///wD///8A////AI8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD//wAF//8Al///AP///wD///8A////AP///wD///8A//// - AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A//// - AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A//// - AP///wD///8A////AP///wD///8A////AP///wD///8Azv//AGQAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAD//wAk//8ApP//AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A//// - AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A//// - AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A//// - AP///wD///8Avv//AFQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD//wBE//8Arv//AP///wD///8A//// - AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A//// - AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A//// - AP///wD///8A////AP///wD///8A////AP///wDO//8AZAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAD//wBE//8Arv//AP///wD///8A////AP///wD///8A////AP///wD///8A//// - AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A//// - AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A//// - AP///wDO//8AZAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD//wAf//8AX/// - AJv//wDX//8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A//// - AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A//// - AP///wD///8A////AP///wDn//8Aq///AG///wAvAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD//wAf//8AX///AJv//wDX//8A////AP///wD///8A//// - AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A//// - AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wDn//8Aq/// - AG///wAvAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAP//ABX//wBR//8AgP//AID//wCA//8AgP//AID//wCA//8AgP//AID//wCA//8AgP// - AID//wCA//8AgP//AID//wCA//8AgP//AID//wCA//8AgP//AID//wCA//8AgP//AID//wCA//8AgP// - AID//wCA//8AgP//AGH//wAlAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP//ABX//wBR//8AgP// - AID//wCA//8AgP//AID//wCA//8AgP//AID//wCA//8AgP//AID//wCA//8AgP//AID//wCA//8AgP// - AID//wCA//8AgP//AID//wCA//8AgP//AID//wCA//8AgP//AID//wCA//8AgP//AGH//wAlAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAA///////////////////AAAAH/////////////////////////////////////4AAAAP///// - ////////////////////////////////AAAAAf////////////////////////////////////4AAAAA - /////////////////////////////////////AAAAAB////////////////////////////////////4 - AAAAAD////////////////////////////////////AAAAAAH/////////////////////////////// - ////4AAAAAAP///////////////////////////////////AAAAAAAf///////////////////////// - /////////4AAAAAAA///////////////////////////////////AAAAAAAB//////////////////// - //////////////4AAAAAAAD//////////////////////////////////AAAAAAAAH////////////// - ///////////////////4AAAAAAAAP/////////////////////////////////AAAAAAAAAf//////// - ////////////////////////4AAAAAAAAA/////////////////////////////////AAAAAAAAAB/// - /////////////////////////////4AAAAAAAAAD////////////////////////////////AAAAAAAA - AAH///////////////////////////////4AAAAAAAAAAP///////////////////////////////AAA - AAAAAAAAf//////////////////////////////4AAAAAAAAAAA///////////////////////////// - //AAAAAAAAAAAB//////////////////////////////4AAAAAAAAAAAD/////////////////////// - ///////AAAAAAAAAAAAH/////////////////////////////4AAAAAAAAAAAAP///////////////// - ////////////AAAAAAAAAAAAAf////////////////////////////4AAAAAAAAAAAAA//////////// - /////////////////AAAAAAAAAAAAAB////////////////////////////4AAAAAAAAAAAAAD////// - //////////////////////AAAAAAAAAAAAAAH///////////////////////////4AAAAAAAAAAAAAAP - ///////////////////////////AAAAAAAAAAAAAAAf//////////////////////////4AAAAAAAAAA - AAAAA///////////////////////////AAAAAAAAAAAAAAAB//////////////////////////4AAAAA - AAAAAAAAAAD//////////////////////////AAAAAAAAAAAAAAAAH/////////////////////////4 - AAAAAAAAAAAAAAAAP/////////////////////////AAAAAAAAAAAAAAAAAf//////////////////// - ////4AAAAAAAAAAAAAAAAA/////////////////////////AAAAAAAAAAAAAAAAAB/////////////// - /////////4AAAAAAAAAAAAAAAAAD////////////////////////AAAAAAAAAAAAAAAAAAH///////// - //////////////4AAAAAAAAAAAAAAAAAAP///////////////////////AAAAAAAAAAAAAAAAAAAf/// - ///////////////////4AAAAAAAAAAAAAAAAAAA///////////////////////AAAAAAAAAAAAAAAAAA - AB//////////////////////4AAAAAAAAAAAAAAAAAAAD//////////////////////AAAAAAAAAAAAA - AAAAAAAH/////////////////////4AAAAAAAAAAAAAAAAAAAAP/////////////////////AAAAAAAA - AAAAAAAAAAAAAf////////////////////4AAAAAAAAAAAAAAAAAAAAA/////////////////////AAA - AAAAAAAAAAAAAAAAAAB////////////////////4AAAAAAAAAAAAAAAAAAAAAD////////////////// - //AAAAAAAAAAAAAAAAAAAAAAH///////////////////4AAAAAAAAAAAAAAAAAAAAAAP//////////// - ///////AAAAAAAAAAAAAAAAAAAAAAAf//////////////////4AAAAAAAAAAAAAAAAAAAAAAA/////// - ////////////AAAAAAAAAAAAAAAAAAAAAAAB//////////////////4AAAAAAAAAAAAAAAAAAAAAAAD/ - /////////////////AAAAAAAAAAAAAAAAAAAAAAAAH/////////////////4AAAAAAAAAAAAAAAAAAAA - AAAAP/////////////////AAAAAAAAAAAAAAAAAAAAAAAAAf////////////////4AAAAAAAAAAAAAAA - AAAAAAAAAA/////////////////AAAAAAAAAAAAAAAAAAAAAAAAAB////////////////4AAAAAAAAAA - AAAAAAAAAAAAAAAD////////////////AAAAAAAAAAAAAAAAAAAAAAAAAAH///////////////4AAAAA - AAAAAAAAAAAAAAAAAAAAAP///////////////AAAAAAAAAAAAAAAAAAAAAAAAAAAf//////////////4 - AAAAAAAAAAAAAAAAAAAAAAAAAAA///////////////AAAAAAAAAAAAAAAAAAAAAAAAAAAB////////// - ////4AAAAAAAAAAAAAAAAAAAAAAAAAAAD//////////////AAAAAAAAAAAAAAAAAAAAAAAAAAAAH//// - /////////4AAAAAAAAAAAAAAAAAAAAAAAAAAAAP/////////////AAAAAAAAAAAAAAAAAAAAAAAAAAAA - Af////////////4AAAAAAAAAAAAAAAAAAAAAAAAAAAAAf////////////AAAAAAAAAAAAAAAAAAAAAAA - AAAAAAA////////////4AAAAAAAAAAAAAAAAAAAAAAAAAAAAAB////////////AAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAD///////////4AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAH///////////AAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAP//////////4AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAf//////////AAAAAAAA - AAAAAAABAAAAAAAAAAAAAAAA//////////4AAAAAAAAAAAAAAAOAAAAAAAAAAAAAAAB//////////AAA - AAAAAAAAAAAAB8AAAAAAAAAAAAAAAD/////////4AAAAAAAAAAAAAAAP4AAAAAAAAAAAAAAAH/////// - //AAAAAAAAAAAAAAAB/wAAAAAAAAAAAAAAAP////////4AAAAAAAAAAAAAAAP/gAAAAAAAAAAAAAAAf/ - ///////AAAAAAAAAAAAAAAB//AAAAAAAAAAAAAAAA////////4AAAAAAAAAAAAAAAP/+AAAAAAAAAAAA - AAAB////////AAAAAAAAAAAAAAAB//8AAAAAAAAAAAAAAAD///////wAAAAAAAAAAAAAAAP//4AAAAAA - AAAAAAAAAH//////+AAAAAAAAAAAAAAAB///wAAAAAAAAAAAAAAAP//////wAAAAAAAAAAAAAAAP///g - AAAAAAAAAAAAAAAf/////+AAAAAAAAAAAAAAAB////AAAAAAAAAAAAAAAA//////wAAAAAAAAAAAAAAA - H///+AAAAAAAAAAAAAAAB/////+AAAAAAAAAAAAAAAAH///8AAAAAAAAAAAAAAAD/////wAAAAAAAAAA - AAAAAAP///4AAAAAAAAAAAAAAAH////+AAAAAAAAAAAAAAAAAf///wAAAAAAAAAAAAAAAP////wAAAAA - AAAAAAAAAAAB////gAAAAAAAAAAAAAAAf///+AAAAAAAAAAAAAAAAAD////AAAAAAAAAAAAAAAA////w - AAAAAAAAAAAAAAAAAP///+AAAAAAAAAAAAAAAB///+AAAAAAAAAAAAAAAAAAf///8AAAAAAAAAAAAAAA - D///wAAAAAAAAAAAAAAAAAB////4AAAAAAAAAAAAAAAH//+AAAAAAAAAAAAAAAAAAD////wAAAAAAAAA - AAAAAAP//wAAAAAAAAAAAAAAAAAAP////gAAAAAAAAAAAAAAAf/+AAAAAAAAAAAAAAAAAAA/////AAAA - AAAAAAAAAAAA//wAAAAAAAAAAAAAAAAAAD////+AAAAAAAAAAAAAAAB/+AAAAAAAAAAAAAAAAAAAP/// - /8AAAAAAAAAAAAAAAD/wAAAAAAAAAAAAAAAAAAA/////4AAAAAAAAAAAAAAAH/AAAAAAAAAAAAAAAAAA - AD/////wAAAAAAAAAAAAAAAP4AAAAAAAAAAAAAAAAAAAP/////gAAAAAAAAAAAAAAA/AAAAAAAAAAAAA - AAAAAAA//////AAAAAAAAAAAAAAAB8AAAAAAAAAAAAAAAAAAADgAAH/+AAAAAAAAAAAAAAADgAAAAAAA - AAAAAAAAAAAAAAAAA/8AAAAAAAAAAAAAAAOAAAAAAAAAAAAAAAAAAAAAAAAAf4AAAAAAAAAAAAAAA4AA - AAAAAAAAAAAAAAAAAAAAAAAfwAAAAAAAAAAAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAfgAAAAAAAAAAAA - AAEAAAAAAAAAAAAAAAAAAAAAAAAAAfAAAAAAAAAAAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAeAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA4A - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABwAAAAAAAAAAAAAAAAAAAAAAAAAAAAMAAAAAAAAA - AAADgAAAAAAAAAAAAAAAAAAAAAAAAAAABwAAAAAAAAAAAAHAAAAAAAAAAAAAAAAAAAAAAAAAAAAPgAAA - AAAAAAAAAOAAAAAAAAAAAAAAAAAAAAAAAAAAAB/AAAAAAAAAAAAAcAAAAAAAAAAAAAAAAAAAAAAAAAAA - P+AAAAAAAAAAAAA4AAAAAAAAAAAAAAAAAAAAAAAAAAB/8AAAAAAAAAAAABwAAAAAAAAAAAAAAAAAAAAA - AAAAAP/8AAAAAAAAAAAADgAAAAAAAAAAAAAAAAAAAAAAAAAB///AAAAAAAAAAAAPAAAAAAAAAAAAAAAA - AAAAAAAAAAP//4AAAAAAAAAAAAeAAAAAAAAAAAAAAAAAAAAAAAAAB///AAAAAAAAAAAAA8AAAAAAAAAA - AAAAAAAAAAAAAAAP//8AAAAAAAAAAAAD4AAAAAAAAAAAAAAAAAAAAAAAAB///gAAAAAAAAAAAAHwAAAA - AAAAAAAAAAAAAAAAAAAAP//+AAAAAAAAAAAAAfgAAAAAAAAAAAAAAAAAAAAAAAB///wAAAAAAAAAAAAA - /AAAAAAAAAAAAAAAAAAAAAAAAP///AAAAAAAAAAAAAD+AAAAAAAAAAAAAAAAAAAAAAAB///4AAAAAAAA - AAAAAH8AAAAAAAAAAAAAAAAAAAAAAAP///gAAAAAAAAAAAAAf4AAAAAAAAAAAAAAAAAAAAAAB///8AAA - AAAAAAAAAAA/wAAAAAAAAAAAAAAAAAAAAAAP///wAAAAAAAAAAAAAD/gAAAAAAAAAAAAAAAAAAAAAA// - //AAAAAAAAAAAAAAP/AAAAAAAAAAAAAAAAAAAAAAD///4AAAAAAAAAAAAAA/8AAAAAAAAAAAAAAAAAAA - AAAP///gAAAAAAAAAAAAAB/wAAAAAAAAAAAAAAAAAAAAAA///+AAAAAAAAAAAAAAH/AAAAAAAAAAAAAA - AAAAAAAAD///4AAAAAAAAAAAAAAf8AAAAAAAAAAAAAAAAAAAAAAP///gAAAAAAAAAAAAAB/wAAAAAAAA - AAAAAAAAAAAAAA///8AAAAAAAAAAAAAAD/AAAAAAAAAAAAAAAAAAAAAAD///wAAAAAAAAAAAAAAP8AAA - AAAAAAAAAAAAAAAAAAAP///AAAAAAAAAAAAAAA/wAAAAAAAAAAAAAAAAAAAAAA///8AAAAAAAAAAAAAA - D/AAAAAAAAAAAAAAAAAAAAAAD///wAAAAAAAAAAAAAAP8AAAAAAAAAAAAAAAAAAAAAAP///AAAAAAAAA - AAAAAA/wAAAAAAAAAAAAAAAAAAAAAA///8AAAAAAAAAAAAAAD/AAAAAAAAAAAAAAAAAAAAAAD///wAAA - AAAAAAAAAAAP8AAAAAAAAAAAAAAAAAAAAAAP///AAAAAAAAAAAAAAA/wAAAAAAAAAAAAAAAAAAAAAA// - /8AAAABgAAAAAAAAD/AAAAAAAAAAAAAAAAAAAAAAD///wAAAAGAAAAAAAAAP8AAAAAAAAAAAAAAAAAAA - AAAP///AAAAAYAAAAAAAAA/wAAAAAAAAAAAAAAAAAAAAAA///8AAAAAgAAAAAAAAD/AAAAAAAAAAAAAA - AAAAAAAAD///wAAAACAAAAAAAAAP8AAAAAAAAAAAAAAAAAAAAAAP///AAAAAAAAAAAAAAA/wAAAAAAAA - AAAAAAAAAAAAAA///8AAAAAAAAAAAAAAD/AAAAAAAAAAAAAAAAAAAAAAD///wAAAAAAAAAAAAAAP8AAA - AAAAAAAAAAAAAAAAAAAP///AAAAAAAAAAAAAAA/wAAAAAAAAAAAAAAAAAAAAAA///8AAAAAAAAAAAAAA - D/AAAAAAAAAAAAAAAAAAAAAAD///wAAAAAAAAAAAAAAP8AAAAAAAAAAAAAAAAAAAAAAP///gAAAAAAAA - AAAAAB/wAAAAAAAAAAAAAAAAAAAAAA///+AAAAAAAAAAAAAAH/AAAAAAAAAAAAAAAAAAAAAAD///4AAA - AAAAAAAAAAAf8AAAAAAAAAAAAAAAAAAAAAAP///gAAAAAAAAAAAAAB/wAAAAAAAAAAAAAAAAAAAAAA// - /+AAAAAAAAAAAAAAP/AAAAAAAAAAAAAAAAAAAAAAD///8AAAAAAAAAAAAAA/8AAAAAAAAAAAAAAAAAAA - AAAP///wAAAAAAAAAAAAAD/wAAAAAAAAAAAAAAAAAAAAAA////AAAAAAAAAAAAAAP/AAAAAAAAAAAAAA - AAAAAAAAD///+AAAAAAAAAAAAAB/8AAAAAAAAAAAAAAAAAAAAAAP///4AAAAAAAAAAAAAH/wAAAAAAAA - AAAAAAAAAAAAAA////wAAAAAAAAAAAAA//AAAAAAAAAAAAAAAAAAAAAAD////AAAAAAAAAAAAAD/8AAA - AAAAAAAAAAAAAAAAAAAP///+AAAAAAAAAAAAAf/wAAAAAAAAAAAAAAAAAAAAAA////4AAAAAAAAAAAAB - //AAAAAAAAAAAAAAAAAAAAAAD////wAAAAAAAAAAAAP/8AAAAAAAAAAAAAAAAAAAAAAP////AAAAAAAA - AAAAA//wAAAAAAAAAAAAAAAAAAAAAA////+AAAAAAAAAAAAH//AAAAAAAAAAAAAAAAAAAAAAD////8AA - AAAAAAAAAA//8AAAAAAAAAAAAAAAAAAAAAAP////wAAAAAAAAAAAD//wAAAAAAAAAAAAAAAAAAAAAA// - ///gAAAAAAAAAAAH//AAAAAAAAAAAAAAAAAAAAAAD/////AAAAAAAAAAAAP/8AAAAAAAAAAAAAAAAAAA - AAAP////+AAAAAAAAAAAA//wAAAAAAAAAAAAAAAAAAAAAA/////8AAAAAAAAAAAB//AAAAAAAAAAAAAA - AAAAAAAAD/////4AAAAAAAAAAAD/8AAAAAAAAAAAAAAAAAAAAAAP/////wAAAAAAAAAAAP/wAAAAAAAA - AAAAAAAAAAAAAA//////gAAAAAAAAAAAf/AAAAAAAAAAAAAAAAAAAAAAD//////AAAAAAAAAAAA/8AAA - AAAAAAAAAAAAAAAAAAAP/////+AAAAAAAAAAAD/wAAAAAAAAAAAAAAAAAAAAAA//////8AAAAAAAAAAA - H/AAAAAAAAAAAAAAAAAAAAAAD//////8AAAAAAAAAAAP8AAAAAAAAAAAAAAAAAAAAAAP//////4AAAAA - AAAAAA/wAAAAAAAAAAAAAAAAAAAAAA///////4AAAAAAAAAAB/AAAAAAAAAAAAAAAAAAAAAAD/////// - 4AAAAAAAAAAD8AAAAAAAAAAAAAAAAAAAAAAP///////8AAAAAAAAAAHwAAAAAAAAAAAAAAAAAAAAAA// - //////+AAABwAAAAAfAAAAAAAAAAAAAAAAAAAAAAD/////////////gAAAAA8AAAAAAAAAAAAAAAAAAA - AAAP/////////////AAAAABwAAAAAAAAAAAAAAAAAAAAAA/////////////+AAAAAHAAAAAAAAAAAAAA - AAAAAAAAD/////////////4AAAAAMAAAAAAAAAAAAAAAAAAAAAAP/////////////wAAAAAQAAAAAAAA - AAAAAAAAAAAAAA//////////////gAAAABAAAAAAAAAAAAAAAAAAAAAAD/////////////+AAAAAAAAA - AAAAAAAAAAAAAAAAAAAP/////////////8AAAAAAAAAAAAAAAAAAAAAAAAAAAA//////////////4AAA - AAAAAAAAAAAAAAAAAAAAAAAAD//////////////gAAAAAAAAAAAAAAAAAAAAAAAAAAAP//////////// - //AAAAAAAAAAAAAAAAAAAAAAAAAAAA//////////////+AAAAAAAAAAAAAAAAAAAAAAAAAAAD/////// - ///////4AAAAAAAAAAAAAAAAAAAAAAAAAAAP//////////////wAAAAAAAAAAAAAAAAAAAAAAAAAAA// - /////////////gAAAAAAAAAAAAAAAAAAAAAAAAAAD///////////////AAAAAAAAAAAAAAAAAAAAAAAA - AAAP//////////////8AAAAAAAAAAAAAAAAAAAAAAAAAAA///////////////4AAAAAAAAAAAAAAAAAA - AAAAAAAAD///////////////wAAAAAAAAAAAAAAAAAAAAAAAAAAP///////////////AAAAAAAAAAAAA - AAAAAAAAAAAAAA///////////////+AAAAAAAAAAAAAAAAAAAAAAAAAAD///////////////8AAAAAAA - AAAAAAAAAAAAAAAAAAAP///////////////wAAAAAAAAAAAAAAAAAAAAAAAAAA////////////////gA - AAAAAAAAAAAAAAAAAAAAAAAAD////////////////AAAAAAAAAAAAAAAAAAAAAAAAAAP//////////// - ///8AAAAAAAAAAAAAAAAAAAAAAAAAA////////////////4AAAAAAAAAAAAAAAAAAAAAAAAAD/////// - /////////wAAAAAAAAAAAAAAAAAAAAAAAAAP////////////////AAAAAAAAAAAAAAAAAAAAAAAAAA// - //////////////+AAAAAAAAAAAAAAAAAAAAAAAAAD////////////////8AAAAAAAAAAAAAAAAAAAAAA - AAAP////////////////4AAAAAAAAAAAAAAAAAAAAAAAAA/////////////////gAAAAAAAAAAAAAAAA - AAAAAAAAH/////////////////AAAAAAAAAAAAAAAAAAAAAAAAAf////////////////+AAAAAAAAAAA - AAAAAAAAAAAAAB/////////////////4AAAAAAAAAAAAAAAAAAAAAAAAH/////////////////wAAAAA - AAAAAAABAAAAAAAAAAA//////////////////gAAAAAAAAAAAAGAAAAAAAAAAD/////////////////+ - AAAAAAAAAAAAAYAAAAAAAAAAP/////////////////+AAAAAAAAAAAADgAAAAAAAAAB///////////// - /////4AMAAAAAAAAAAPAAAAAAAAAAH////////////////////4AAAAAAAAAA+AAAAAAAAAA//////// - /////////////gAAAAAAAAAH4AAAAAAAAAH/////////////////////AAAAAAAAAA/wAAAAAAAAAf// - //////////////////+AAAAAAAAAD/gAAAAAAAAD/////////////////////8AAAAAAAAAf/AAAAAAA - AAf/////////////////////4AAAAAAAAD/+AAAAAAAAD//////////////////////wAAAAAAAAf/8A - AAAAAAAf//////////////////////gAAAAAAAH//4AAAAAAAH///////////////////////AAAAAAA - A///4AAAAAAB////////////////////////AAAAAAAP///4AAAAAAf////////////////////////A - AAAAAD////+AAAAAf/////////////////////////wAAAAD//8= - - - \ No newline at end of file diff --git a/FAAStripItemPlugin.cs b/FAAStripItemPlugin.cs deleted file mode 100644 index 7f855a1..0000000 --- a/FAAStripItemPlugin.cs +++ /dev/null @@ -1,156 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Text.RegularExpressions; -using vatsys; -using vatsys.Plugin; -using System.Collections.Concurrent; -using System.ComponentModel.Composition; //<--Need to add a reference to System.ComponentModel.Composition -using static vatsys.Performance; -using static vatsys.Network; -using System.Linq; - -namespace FAAStripItemsPlugin -{ - [Export(typeof(IPlugin))] - - public class FAAStripItemsPlugin : IStripPlugin - { - - /// The name of the custom label item we've added to Labels - /// in the Profile - const string STRIP_ITEM_HEAVY = "FAA_HEAVY"; - const string STRIP_ITEM_CTLSECTOR = "AURORA_CDA"; - const string STRIP_ITEM_NXTSECTOR = "AURORA_NDA"; - const string STRIP_ITEM_EQSUFFIX = "FAA_EQUIPMENT"; - const string STRIP_ITEM_TRUNCSYM = "FAA_TRUNCATION"; - const string STRIP_ITEM_TAS = "FAA_TAS"; - const string STRIP_ITEM_GS = "FAA_GS"; - const string STRIP_ITEM_HOUR = "FAA_HOUR"; - const string STRIP_ITEM_MINUTE = "FAA_MINUTE"; - const string STRIP_ITEM_ROUTE = "FAA_ROUTE"; - const string STRIP_ITEM_REMARKS = "FAA_REMARKS"; - - public string Name => throw new NotImplementedException(); - - /// Plugin Name - - public void OnFDRUpdate(FDP2.FDR updated) - { - - } - - /// This is called each time a radar track is updated - public void OnRadarTrackUpdate(RDP.RadarTrack updated) - { - - } - - private void ItemMouseClick(CustomLabelItemMouseClickEventArgs e) - { - - } - public CustomStripItem GetCustomStripItem(string itemType, Track track, FDP2.FDR flightDataRecord, RDP.RadarTrack radarTrack) - - { - //bool trunc = flightDataRecord.DepAirport != flightDataRecord.Route.Equals; - bool heavy = Regex.IsMatch(flightDataRecord.AircraftWake, @"H"); - bool faaFp = !flightDataRecord.IsICAOFormat; - int level = radarTrack == null ? flightDataRecord.PRL / 100 : radarTrack.CorrectedAltitude / 100; - int cfl; - bool isCfl = Int32.TryParse(flightDataRecord.CFLString, out cfl); - - - if (flightDataRecord is null) - return null; - - switch (itemType) - { - case STRIP_ITEM_HEAVY: - - if (heavy) - { - return new CustomStripItem() - { - Text = "H/" - }; - } - return null; - - case STRIP_ITEM_EQSUFFIX: - - if (faaFp) - { - return new CustomStripItem() - { - Text = "/" + flightDataRecord.AircraftEquip - }; - } - return null; - - - case STRIP_ITEM_NXTSECTOR: - - return new CustomStripItem() - { - Text = flightDataRecord.HandoffSector.ToString() - }; - - case STRIP_ITEM_TAS: - var mach = flightDataRecord.TAS / 581.0; - return new CustomStripItem() - { - //Text = "M" + Convert.ToDecimal(mach).ToString("F2").Replace(".", "") - Text = "T" + flightDataRecord.TAS.ToString("000")//format as 3 digits (with leading zeros) - }; - - case STRIP_ITEM_GS: - - return new CustomStripItem() - { - Text = radarTrack == null ? null :"G" + radarTrack.GroundSpeed.ToString("000")//format as 3 digits (with leading zeros) - }; - - case STRIP_ITEM_HOUR: - - return new CustomStripItem() - { - Text = flightDataRecord.PredictedPosition.ETO.ToString("HH") //format as 2 digit hour - }; - - case STRIP_ITEM_MINUTE: - - - return new CustomStripItem() - { - Text = flightDataRecord.PredictedPosition.ETO.ToString("mm") //format as 2 digit minute - }; - - case STRIP_ITEM_ROUTE: - - return new CustomStripItem() - { - Text = flightDataRecord.Route - }; - - case STRIP_ITEM_REMARKS: - - return new CustomStripItem() - { - Text = "○" + flightDataRecord.Remarks - }; - //case STRIP_ITEM_TRUNCSYM: - // - // if (trunc) - // { - // return new CustomStripItem() - // { - // Text = "./." - // }; - // } - // return null; - - default: return null; - } - } - } -} diff --git a/FPAP.cs b/FPAP.cs index bcc4db9..8967d38 100644 --- a/FPAP.cs +++ b/FPAP.cs @@ -1,32 +1,30 @@ using System; using System.Linq; using System.Text.RegularExpressions; -using static vatsys.SectorsVolumes; using System.Threading; -using vatsys.Plugin; using vatsys; -using System.ComponentModel.Composition; +using static vatsys.SectorsVolumes; namespace AuroraLabelItemsPlugin { public class FPAP { - public Match pbn; - public Match sur; - public bool rnp10; - public bool rnp4; - public bool pbcs; - public bool cpdlc; public bool adsc; + public int alt; + public int cfl; + public bool cpdlc; public bool jet; - public double vs; + public bool pbcs; + public Match pbn; public int prl; - public int cfl; public int rfl; - public int alt; + public bool rnp10; + public bool rnp4; + public Match sur; + public double vs; public void OnFDRUpdate(FDP2.FDR updated) - { + { pbn = Regex.Match(updated.Remarks, @"PBN\/\w+\s"); sur = Regex.Match(updated.Remarks, @"SUR\/\w+\s"); rnp10 = pbn.Value.Contains("A1") && updated.AircraftEquip.Contains("R"); @@ -42,13 +40,10 @@ public void OnFDRUpdate(FDP2.FDR updated) alt = cfl == -1 ? rfl : cfl; } - public void TOC(RDP.RadarTrack rt) + public void TOC(RDP.RadarTrack rt) { var fdr = rt.CoupledFDR; - if (fdr != null && rt != null) - { - TransferOfControl(fdr); - } + if (fdr != null && rt != null) TransferOfControl(fdr); } @@ -60,26 +55,23 @@ public static void TransferOfControl(FDP2.FDR fdr) var rt = fdr.CoupledTrack; if (fdr != null) if (!fdr.ESTed && MMI.IsMySectorConcerned(fdr)) - { MMI.EstFDR(fdr); - } if (MMI.SectorsControlled.ToList() - .Exists(s => s.IsInSector(fdr.GetLocation(), fdr.PRL)) && !fdr.IsTrackedByMe && !fdr.IsTracked) //MMI.SectorsControlled.Contains(fdr.ControllingSector) || fdr.ControllingSector == null - { + .Exists(s => s.IsInSector(fdr.GetLocation(), fdr.PRL)) && !fdr.IsTrackedByMe && + !fdr.IsTracked) //MMI.SectorsControlled.Contains(fdr.ControllingSector) || fdr.ControllingSector == null MMI.AcceptJurisdiction(fdr); - } - - foreach (Volume volume in Volumes) - { - if (rt != null && (fdr.PRL == -1 || (fdr.PRL <= volume.UpperLevel && fdr.PRL > volume.LowerLevel)) && Conversions.IsLatlonInPoly(fdr.GetLocation(), volume.Boundary)) + foreach (var volume in Volumes) + if (rt != null && (fdr.PRL == -1 || (fdr.PRL <= volume.UpperLevel && fdr.PRL > volume.LowerLevel)) && + Conversions.IsLatlonInPoly(fdr.GetLocation(), volume.Boundary)) { - var whichVol = volume; - var whichFIR = SectorsVolumes.FindSector(whichVol); - if (MMI.GetSectorEntryTime(fdr) == DateTime.MaxValue && MMI.SectorsControlled.ToList().TrueForAll(s => !s.IsInSector(fdr.GetLocation(), fdr.PRL))) // && whichFIR != fdr.ControllingSector + var whichFIR = FindSector(whichVol); + if (MMI.GetSectorEntryTime(fdr) == DateTime.MaxValue && MMI.SectorsControlled.ToList() + .TrueForAll(s => + !s.IsInSector(fdr.GetLocation(), fdr.PRL))) // && whichFIR != fdr.ControllingSector { //toc.HandoffNextSector(); @@ -89,8 +81,6 @@ public static void TransferOfControl(FDP2.FDR fdr) RDP.DeCouple(rt); } } - } - } //void SendNextDataAuthority(Network network, NetworkPilot pilot, VSCSFrequency freq) @@ -109,6 +99,5 @@ public static void TransferOfControl(FDP2.FDR fdr) // pilot.LastContactMe = DateTime.UtcNow; // } //} - } -} +} \ No newline at end of file diff --git a/GEO.cs b/GEO.cs index 65e3fed..ac87952 100644 --- a/GEO.cs +++ b/GEO.cs @@ -1,15 +1,11 @@ -using System; -using System.Threading; +//<--Need to add a reference to System.ComponentModel.Composition +using System; using System.Collections.Concurrent; +using System.Collections.Generic; using System.ComponentModel.Composition; -using System.Linq; //<--Need to add a reference to System.ComponentModel.Composition -using System.Text.RegularExpressions; using vatsys; using vatsys.Plugin; using static vatsys.FDP2; -using static vatsys.SectorsVolumes; -using System.Collections.Generic; -using System.Runtime.CompilerServices; //Note the reference to vatsys (set Copy Local to false) -----> @@ -21,45 +17,55 @@ public class GEO : ILabelPlugin { /// The name of the custom label item we've added to Labels /// in the Profile - const string LABEL_ITEM_SELECT_HORI = "SELECT_HORI"; - const string LABEL_ITEM_SELECT_VERT = "SELECT_VERT"; - const string LABEL_ITEM_COMM_ICON = "AURORA_COMM_ICON"; //field a(2) - const string LABEL_ITEM_ADSB_CPDLC = "AURORA_ADSB_CPDLC"; //field c(4) - const string LABEL_ITEM_ADS_FLAGS = "AURORA_ADS_FLAGS"; //field c(4) - const string LABEL_ITEM_MNT_FLAGS = "AURORA_MNT_FLAGS"; //field c(4) - const string LABEL_ITEM_SCC = "AURORA_SCC"; //field d(5) - const string LABEL_ITEM_ANNOT_IND = "AURORA_ANNOT_IND"; //field e(1) - const string LABEL_ITEM_RESTR = "AURORA_RESTR"; //field f(1) - const string LABEL_ITEM_LEVEL = "AURORA_LEVEL"; //field g(3) - const string LABEL_ITEM_VMI = "AURORA_VMI"; //field h(1) - const string LABEL_ITEM_CLEARED_LEVEL = "AURORA_CLEARED_LEVEL"; //field i(7) - const string LABEL_ITEM_HANDOFF_IND = "AURORA_HO_IND"; //field j(4) - const string LABEL_ITEM_RADAR_IND = "AURORA_RADAR_IND"; //field k(1) - const string LABEL_ITEM_INHIBIT_IND = "AURORA_INHIBIT_IND"; //field l(1) - const string LABEL_ITEM_FILED_SPEED = "AURORA_FILEDSPEED"; //field m(4) - const string LABEL_ITEM_3DIGIT_GROUNDSPEED = "AURORA_GROUNDSPEED"; //field n(5) - const string LABEL_ITEM_DESTINATION = "AURORA_DESTINATION"; //field o(4) - readonly static CustomColour EastboundColour = new CustomColour(240, 255, 255); - readonly static CustomColour WestboundColour = new CustomColour(240, 231, 140); - readonly static CustomColour NonRVSM = new CustomColour(242, 133, 0); - readonly static CustomColour Probe = new CustomColour(0, 255, 0); - readonly static CustomColour NotCDA = new CustomColour(100, 0, 100); - readonly static CustomColour Advisory = new CustomColour(255, 165, 0); - readonly static CustomColour Imminent = new CustomColour(255, 0, 0); - readonly static CustomColour SpecialConditionCode = new CustomColour(255, 255, 0); - readonly static CustomColour ApsBlue = new CustomColour(141, 182, 205); - readonly ConcurrentDictionary eastboundCallsigns = new ConcurrentDictionary(); - readonly ConcurrentDictionary adsbcpdlcValues = new ConcurrentDictionary(); - readonly ConcurrentDictionary adsflagValues = new ConcurrentDictionary(); - readonly ConcurrentDictionary mntflagValues = new ConcurrentDictionary(); - readonly ConcurrentDictionary sccflagValues = new ConcurrentDictionary(); - readonly ConcurrentDictionary altValues = new ConcurrentDictionary(); - readonly ConcurrentDictionary radartoggle = new ConcurrentDictionary(); - readonly ConcurrentDictionary mntflagtoggle = new ConcurrentDictionary(); - readonly ConcurrentDictionary downlink = new ConcurrentDictionary(); - public readonly ConcurrentDictionary> advisoryConflict = new ConcurrentDictionary>(); - public readonly ConcurrentDictionary> imminentConflict = new ConcurrentDictionary>(); - + private const string LABEL_ITEM_SELECT_HORI = "SELECT_HORI"; + + private const string LABEL_ITEM_SELECT_VERT = "SELECT_VERT"; + private const string LABEL_ITEM_COMM_ICON = "AURORA_COMM_ICON"; //field a(2) + private const string LABEL_ITEM_ADSB_CPDLC = "AURORA_ADSB_CPDLC"; //field c(4) + private const string LABEL_ITEM_ADS_FLAGS = "AURORA_ADS_FLAGS"; //field c(4) + private const string LABEL_ITEM_MNT_FLAGS = "AURORA_MNT_FLAGS"; //field c(4) + private const string LABEL_ITEM_SCC = "AURORA_SCC"; //field d(5) + private const string LABEL_ITEM_ANNOT_IND = "AURORA_ANNOT_IND"; //field e(1) + private const string LABEL_ITEM_RESTR = "AURORA_RESTR"; //field f(1) + private const string LABEL_ITEM_LEVEL = "AURORA_LEVEL"; //field g(3) + private const string LABEL_ITEM_VMI = "AURORA_VMI"; //field h(1) + private const string LABEL_ITEM_CLEARED_LEVEL = "AURORA_CLEARED_LEVEL"; //field i(7) + private const string LABEL_ITEM_HANDOFF_IND = "AURORA_HO_IND"; //field j(4) + private const string LABEL_ITEM_RADAR_IND = "AURORA_RADAR_IND"; //field k(1) + private const string LABEL_ITEM_INHIBIT_IND = "AURORA_INHIBIT_IND"; //field l(1) + private const string LABEL_ITEM_FILED_SPEED = "AURORA_FILEDSPEED"; //field m(4) + private const string LABEL_ITEM_3DIGIT_GROUNDSPEED = "AURORA_GROUNDSPEED"; //field n(5) + private const string LABEL_ITEM_DESTINATION = "AURORA_DESTINATION"; //field o(4) + private static readonly CustomColour EastboundColour = new CustomColour(240, 255, 255); + private static readonly CustomColour WestboundColour = new CustomColour(240, 231, 140); + private static readonly CustomColour NonRVSM = new CustomColour(242, 133, 0); + private static readonly CustomColour Probe = new CustomColour(0, 255, 0); + private static readonly CustomColour NotCDA = new CustomColour(100, 0, 100); + private static readonly CustomColour Advisory = new CustomColour(255, 165, 0); + private static readonly CustomColour Imminent = new CustomColour(255, 0, 0); + private static readonly CustomColour SpecialConditionCode = new CustomColour(255, 255, 0); + private static readonly CustomColour ApsBlue = new CustomColour(141, 182, 205); + private readonly ConcurrentDictionary adsbcpdlcValues = new ConcurrentDictionary(); + private readonly ConcurrentDictionary adsflagValues = new ConcurrentDictionary(); + + public readonly ConcurrentDictionary> advisoryConflict = + new ConcurrentDictionary>(); + + private readonly ConcurrentDictionary altValues = new ConcurrentDictionary(); + private readonly ConcurrentDictionary downlink = new ConcurrentDictionary(); + + private readonly ConcurrentDictionary eastboundCallsigns = + new ConcurrentDictionary(); + + public readonly ConcurrentDictionary> imminentConflict = + new ConcurrentDictionary>(); + + private readonly ConcurrentDictionary mntflagtoggle = new ConcurrentDictionary(); + private readonly ConcurrentDictionary mntflagValues = new ConcurrentDictionary(); + private readonly ConcurrentDictionary radartoggle = new ConcurrentDictionary(); + + private readonly ConcurrentDictionary + sccflagValues = new ConcurrentDictionary(); public GEO() @@ -69,42 +75,19 @@ public GEO() } - private void Network_RadioMessageAcknowledged(object sender, RadioMessageEventArgs e) - { - throw new NotImplementedException(); - } - - private void Network_PrivateMessagesChanged(object sender, Network.GenericMessageEventArgs e) - { - bool downLink = e.Message.Sent == true; - - if (downLink) - { - downlink.TryRemove(e.Message.Address, out _); - } - else - { - downlink.TryAdd(e.Message.Address, 0); - } - } - - /// Plugin Name - public string Name - { - get => "Aurora Label Items"; - } + public string Name => "Aurora Label Items"; /// This is called each time a flight data record is updated /// Here we are updating the eastbound callsigns dictionary with each flight data record /// When the FDR is updated we check if it still exists in the Flight Data Processor and remove from our dictionary if not. Otherwise we do some simple regex matching to find /// the flight planned PBN category and store the character we want to display in the label in the dictionary. - public void OnFDRUpdate(FDP2.FDR updated) + public void OnFDRUpdate(FDR updated) { - FPAP fpap = new FPAP(); + var fpap = new FPAP(); - if (FDP2.GetFDRIndex(updated.Callsign) == -1) + if (GetFDRIndex(updated.Callsign) == -1) { eastboundCallsigns.TryRemove(updated.Callsign, out _); adsbcpdlcValues.TryRemove(updated.Callsign, out _); @@ -117,12 +100,9 @@ public void OnFDRUpdate(FDP2.FDR updated) downlink.TryRemove(updated.Callsign, out _); advisoryConflict.TryRemove(updated.Callsign, out _); imminentConflict.TryRemove(updated.Callsign, out _); - } else { - - char c1 = default; if (!updated.ADSB && fpap.cpdlc) @@ -160,7 +140,7 @@ public void OnFDRUpdate(FDP2.FDR updated) NetworkPilot code; code = new NetworkPilot(); - string d1 = string.Empty; + var d1 = string.Empty; if (!fpap.rnp10 && !fpap.rnp4) d1 = "RNP"; @@ -187,7 +167,7 @@ public void OnFDRUpdate(FDP2.FDR updated) else if (fpap.alt / 100 > fpap.prl || fpap.vs > 300) //Issued or trending climb h1 = '↑'; - else if (fpap.alt / 100 > 0 && fpap.alt < fpap.prl || fpap.vs < -300) //Issued or trending descent + else if ((fpap.alt / 100 > 0 && fpap.alt < fpap.prl) || fpap.vs < -300) //Issued or trending descent h1 = '↓'; else if (fpap.prl - fpap.alt / 100 >= 3) //deviating above @@ -203,41 +183,24 @@ public void OnFDRUpdate(FDP2.FDR updated) { //calculate track from first route point to last (Departure point to destination point) var rte = updated.ParsedRoute; - double trk = Conversions.CalculateTrack(rte.First().Intersection.LatLong, + var trk = Conversions.CalculateTrack(rte.First().Intersection.LatLong, rte.Last().Intersection.LatLong); - bool east = trk >= 0 && trk < 180; + var east = trk >= 0 && trk < 180; eastboundCallsigns.AddOrUpdate(updated.Callsign, east, (c, e) => east); } FPAP.TransferOfControl(updated); - CPAR cpar = new CPAR(); - CPAR.ConflictData reqLat = new CPAR.ConflictData(); + var cpar = new CPAR(); + var reqLat = new CPAR.ConflictData(); cpar.ConflictProbe(updated, reqLat.latSep); - } } - /// Could use the new position of the radar track or its change in state (cancelled, etc.) to do some processing. + + /// Could use the new position of the radar track or its change in state (cancelled, etc.) to do some processing. public void OnRadarTrackUpdate(RDP.RadarTrack updated) { - - } - - private void HandleRadarFlagClick(CustomLabelItemMouseClickEventArgs e) - { - bool radarToggled = radartoggle.TryGetValue(e.Track.GetFDR().Callsign, out _); - - if (radarToggled) - { - radartoggle.TryRemove(e.Track.GetFDR().Callsign, out _); - } - else - { - radartoggle.TryAdd(e.Track.GetFDR().Callsign, 0); - } - - e.Handled = true; } @@ -245,9 +208,10 @@ private void HandleRadarFlagClick(CustomLabelItemMouseClickEventArgs e) /// itemType is the value of the Type attribute in Labels.xml /// If it's not our item being called (another plugins, for example), return null. /// As a general rule, don't do processing in here as you'll slow down the ASD refresh. In the case of parsing a level to a string though, that's fine. - public CustomLabelItem GetCustomLabelItem(string itemType, Track track, FDP2.FDR flightDataRecord, RDP.RadarTrack radarTrack) + public CustomLabelItem GetCustomLabelItem(string itemType, Track track, FDR flightDataRecord, + RDP.RadarTrack radarTrack) { - FPAP fpap = new FPAP(); + var fpap = new FPAP(); if (flightDataRecord == null || radarTrack == null) return null; @@ -264,94 +228,79 @@ public CustomLabelItem GetCustomLabelItem(string itemType, Track track, FDP2.FDR altValues.TryGetValue(flightDataRecord.Callsign, out h1); - - bool radarToggled = radartoggle.TryGetValue(flightDataRecord.Callsign, out _); - bool mntflagToggled = mntflagtoggle.TryGetValue(flightDataRecord.Callsign, out _); - bool downLink = downlink.TryGetValue(flightDataRecord.Callsign, out _); - bool isNonRVSM = !flightDataRecord.RVSM; - var notProbe = flightDataRecord.State == (FDR.FDRStates.STATE_PREACTIVE | FDR.FDRStates.STATE_COORDINATED) ? BorderFlags.All : BorderFlags.None; - var colour = (!flightDataRecord.RVSM ? NonRVSM : ExcludeConflictColor(track, flightDataRecord)); - var excludeConflict = (SelectASDTrackColour(track) == GetConflictColour(flightDataRecord.Callsign)); + var radarToggled = radartoggle.TryGetValue(flightDataRecord.Callsign, out _); + var mntflagToggled = mntflagtoggle.TryGetValue(flightDataRecord.Callsign, out _); + var downLink = downlink.TryGetValue(flightDataRecord.Callsign, out _); + var isNonRVSM = !flightDataRecord.RVSM; + var notProbe = flightDataRecord.State == (FDR.FDRStates.STATE_PREACTIVE | FDR.FDRStates.STATE_COORDINATED) + ? BorderFlags.All + : BorderFlags.None; + var colour = !flightDataRecord.RVSM ? NonRVSM : ExcludeConflictColor(track, flightDataRecord); + var excludeConflict = SelectASDTrackColour(track) == GetConflictColour(flightDataRecord.Callsign); switch (itemType) { + case LABEL_ITEM_SELECT_HORI: - case LABEL_ITEM_SELECT_HORI: + if (MMI.SelectedTrack?.GetFDR()?.Callsign == track.GetFDR().Callsign) + return new CustomLabelItem + { + Text = "", + Border = BorderFlags.Bottom + }; + + return null; + + case LABEL_ITEM_SELECT_VERT: if (MMI.SelectedTrack?.GetFDR()?.Callsign == track.GetFDR().Callsign) - { - return new CustomLabelItem() - - { - Text = "", - Border = BorderFlags.Bottom - }; - } - - return null; - - case LABEL_ITEM_SELECT_VERT: - - if (MMI.SelectedTrack?.GetFDR()?.Callsign == track.GetFDR().Callsign) - { - return new CustomLabelItem() - { - Text = "", - Border = BorderFlags.Left - }; - } - - return null; + return new CustomLabelItem + { + Text = "", + Border = BorderFlags.Left + }; + + return null; case LABEL_ITEM_COMM_ICON: if (downLink) - { - return new CustomLabelItem() + return new CustomLabelItem { Text = "▼", Border = BorderFlags.All, ForeColourIdentity = excludeConflict ? Colours.Identities.Custom : default, CustomForeColour = ExcludeConflictColor(track, flightDataRecord) }; - } - else + return new CustomLabelItem { - return new CustomLabelItem() - { - Text = "⬜", - ForeColourIdentity = excludeConflict ? Colours.Identities.Custom : default, - CustomForeColour = ExcludeConflictColor(track, flightDataRecord) - }; - } + Text = "⬜", + ForeColourIdentity = excludeConflict ? Colours.Identities.Custom : default, + CustomForeColour = ExcludeConflictColor(track, flightDataRecord) + }; case LABEL_ITEM_ADSB_CPDLC: - bool useCustomForeColour = + var useCustomForeColour = flightDataRecord.State == (FDR.FDRStates.STATE_PREACTIVE | FDR.FDRStates.STATE_COORDINATED); if (useCustomForeColour) - { - return new CustomLabelItem() + return new CustomLabelItem { ForeColourIdentity = Colours.Identities.Custom, CustomForeColour = NotCDA, Text = c1.ToString() }; - } - else + return new CustomLabelItem { - return new CustomLabelItem() - { - Text = c1.ToString(), - ForeColourIdentity = excludeConflict ? Colours.Identities.Custom : default, - CustomForeColour = ExcludeConflictColor(track, flightDataRecord) - }; - } + Text = c1.ToString(), + ForeColourIdentity = excludeConflict ? Colours.Identities.Custom : default, + CustomForeColour = ExcludeConflictColor(track, flightDataRecord) + }; case LABEL_ITEM_ADS_FLAGS: - return new CustomLabelItem() + return new CustomLabelItem { Text = c2.ToString(), ForeColourIdentity = excludeConflict ? Colours.Identities.Custom : default, @@ -362,63 +311,55 @@ public CustomLabelItem GetCustomLabelItem(string itemType, Track track, FDP2.FDR case LABEL_ITEM_MNT_FLAGS: if (mntflagToggled) - { - return new CustomLabelItem() + return new CustomLabelItem { Text = c3.ToString(), ForeColourIdentity = excludeConflict ? Colours.Identities.Custom : default, CustomForeColour = ExcludeConflictColor(track, flightDataRecord) }; - } - else - return new CustomLabelItem() - { - Text = "", - }; + return new CustomLabelItem + { + Text = "" + }; case LABEL_ITEM_SCC: - + + { + return new CustomLabelItem { - return new CustomLabelItem() - { - Text = d1, - ForeColourIdentity = Colours.Identities.Custom, - CustomForeColour = SpecialConditionCode - }; - } + Text = d1, + ForeColourIdentity = Colours.Identities.Custom, + CustomForeColour = SpecialConditionCode + }; + } case LABEL_ITEM_ANNOT_IND: - bool scratch = String.IsNullOrEmpty(flightDataRecord.LabelOpData); + var scratch = string.IsNullOrEmpty(flightDataRecord.LabelOpData); if (scratch) - { - return new CustomLabelItem() + return new CustomLabelItem { Text = "◦", ForeColourIdentity = excludeConflict ? Colours.Identities.Custom : default, CustomForeColour = ExcludeConflictColor(track, flightDataRecord) }; - } - else + return new CustomLabelItem { - return new CustomLabelItem() - { - Text = "&", - ForeColourIdentity = excludeConflict ? Colours.Identities.Custom : default, - CustomForeColour = ExcludeConflictColor(track, flightDataRecord) - }; - } + Text = "&", + ForeColourIdentity = excludeConflict ? Colours.Identities.Custom : default, + CustomForeColour = ExcludeConflictColor(track, flightDataRecord) + }; case LABEL_ITEM_RESTR: if (flightDataRecord.LabelOpData.Contains("AT ") || flightDataRecord.LabelOpData.Contains(" BY ") || flightDataRecord.LabelOpData.Contains("CLEARED TO ")) - return new CustomLabelItem() + return new CustomLabelItem { Text = "x", ForeColourIdentity = excludeConflict ? Colours.Identities.Custom : default, @@ -431,21 +372,20 @@ public CustomLabelItem GetCustomLabelItem(string itemType, Track track, FDP2.FDR var level = fpap.prl == -1 ? null : (radarTrack.CorrectedAltitude / 100).ToString(); - - return new CustomLabelItem() - { - Text = level.ToString(), - Border = notProbe, - BorderColourIdentity = Colours.Identities.Custom, - CustomBorderColour = NotCDA, - ForeColourIdentity = excludeConflict ? Colours.Identities.Custom : default, - CustomForeColour = colour - }; + return new CustomLabelItem + { + Text = level, + Border = notProbe, + BorderColourIdentity = Colours.Identities.Custom, + CustomBorderColour = NotCDA, + ForeColourIdentity = excludeConflict ? Colours.Identities.Custom : default, + CustomForeColour = colour + }; case LABEL_ITEM_VMI: - return new CustomLabelItem() + return new CustomLabelItem { Text = h1.ToString(), ForeColourIdentity = excludeConflict ? Colours.Identities.Custom : default, @@ -453,30 +393,27 @@ public CustomLabelItem GetCustomLabelItem(string itemType, Track track, FDP2.FDR }; - case LABEL_ITEM_CLEARED_LEVEL: - if (radarTrack.ReachedCFL || fpap.prl == fpap.alt || Math.Abs(flightDataRecord.PRL - fpap.alt) < 300) - return new CustomLabelItem() + if (radarTrack.ReachedCFL || fpap.prl == fpap.alt || + Math.Abs(flightDataRecord.PRL - fpap.alt) < 300) + return new CustomLabelItem { Text = "" }; - else + return new CustomLabelItem { - return new CustomLabelItem() - { - Text = fpap.alt.ToString(), - Border = notProbe, - BorderColourIdentity = Colours.Identities.Custom, - CustomBorderColour = NotCDA, - ForeColourIdentity = excludeConflict ? Colours.Identities.Custom : default, - CustomForeColour = colour - }; - } + Text = fpap.alt.ToString(), + Border = notProbe, + BorderColourIdentity = Colours.Identities.Custom, + CustomBorderColour = NotCDA, + ForeColourIdentity = excludeConflict ? Colours.Identities.Custom : default, + CustomForeColour = colour + }; -// case LABEL_ITEM_HANDOFF_IND: + // case LABEL_ITEM_HANDOFF_IND: // // // if (flightDataRecord.IsHandoff) @@ -507,58 +444,48 @@ public CustomLabelItem GetCustomLabelItem(string itemType, Track track, FDP2.FDR if (radarToggled) - { - return new CustomLabelItem() + return new CustomLabelItem { Text = "★", OnMouseClick = HandleRadarFlagClick, ForeColourIdentity = excludeConflict ? Colours.Identities.Custom : default, CustomForeColour = ExcludeConflictColor(track, flightDataRecord) }; - } - else + return new CustomLabelItem { - return new CustomLabelItem() - { - Text = "◦", - OnMouseClick = HandleRadarFlagClick, - ForeColourIdentity = excludeConflict ? Colours.Identities.Custom : default, - CustomForeColour = ExcludeConflictColor(track, flightDataRecord) - }; - } + Text = "◦", + OnMouseClick = HandleRadarFlagClick, + ForeColourIdentity = excludeConflict ? Colours.Identities.Custom : default, + CustomForeColour = ExcludeConflictColor(track, flightDataRecord) + }; case LABEL_ITEM_INHIBIT_IND: if (flightDataRecord.State == FDR.FDRStates.STATE_INHIBITED) - { - return new CustomLabelItem() + return new CustomLabelItem { Text = "^", ForeColourIdentity = excludeConflict ? Colours.Identities.Custom : default, CustomForeColour = ExcludeConflictColor(track, flightDataRecord) }; - } - else + return new CustomLabelItem { - return new CustomLabelItem() - { - Text = "" - }; - } + Text = "" + }; case LABEL_ITEM_FILED_SPEED: - var mach = Conversions.CalculateMach(flightDataRecord.TAS, GRIB.FindTemperature(flightDataRecord.PRL, track.GetLocation(), true)); - return new CustomLabelItem() + var mach = Conversions.CalculateMach(flightDataRecord.TAS, + GRIB.FindTemperature(flightDataRecord.PRL, track.GetLocation(), true)); + return new CustomLabelItem { Text = "M" + Convert.ToDecimal(mach).ToString("F2").Replace(".", ""), //Text = "N" + flightDataRecord.TAS ForeColourIdentity = excludeConflict ? Colours.Identities.Custom : default, CustomForeColour = ExcludeConflictColor(track, flightDataRecord) - }; case LABEL_ITEM_3DIGIT_GROUNDSPEED: @@ -566,16 +493,16 @@ public CustomLabelItem GetCustomLabelItem(string itemType, Track track, FDP2.FDR var gs = radarTrack == null ? flightDataRecord.PredictedPosition.Groundspeed : radarTrack.GroundSpeed; - return new CustomLabelItem() + return new CustomLabelItem { - Text = "N" + gs.ToString("000"),//format as 3 digits (with leading zeros) + Text = "N" + gs.ToString("000"), //format as 3 digits (with leading zeros) ForeColourIdentity = excludeConflict ? Colours.Identities.Custom : default, CustomForeColour = ExcludeConflictColor(track, flightDataRecord) }; case LABEL_ITEM_DESTINATION: - return new CustomLabelItem() + return new CustomLabelItem { Text = flightDataRecord.DesAirport, ForeColourIdentity = excludeConflict ? Colours.Identities.Custom : default, @@ -597,21 +524,17 @@ public CustomColour SelectASDTrackColour(Track track) //only apply East/West colour to jurisdiction state - if (track.State == MMI.HMIStates.Jurisdiction) //read our dictionary of stored bools (true means is easterly) and return the correct colour - { - + if (track.State == + MMI.HMIStates + .Jurisdiction) //read our dictionary of stored bools (true means is easterly) and return the correct colour return GetConflictColour(fdr.Callsign) ?? GetDirectionColour(fdr.Callsign, fdr); - } - if (fdr.State != (FDR.FDRStates.STATE_PREACTIVE | FDR.FDRStates.STATE_COORDINATED)) //only apply conflict colours if planes are of concern - { + if (fdr.State != + (FDR.FDRStates.STATE_PREACTIVE | + FDR.FDRStates.STATE_COORDINATED)) //only apply conflict colours if planes are of concern return GetConflictColour(fdr.Callsign) ?? null; - } - - else - - return default; + return default; } public CustomColour SelectGroundTrackColour(Track track) @@ -619,14 +542,41 @@ public CustomColour SelectGroundTrackColour(Track track) return null; } + + private void Network_RadioMessageAcknowledged(object sender, RadioMessageEventArgs e) + { + throw new NotImplementedException(); + } + + private void Network_PrivateMessagesChanged(object sender, Network.GenericMessageEventArgs e) + { + var downLink = e.Message.Sent; + + if (downLink) + downlink.TryRemove(e.Message.Address, out _); + else + downlink.TryAdd(e.Message.Address, 0); + } + + private void HandleRadarFlagClick(CustomLabelItemMouseClickEventArgs e) + { + var radarToggled = radartoggle.TryGetValue(e.Track.GetFDR().Callsign, out _); + + if (radarToggled) + radartoggle.TryRemove(e.Track.GetFDR().Callsign, out _); + else + radartoggle.TryAdd(e.Track.GetFDR().Callsign, 0); + + e.Handled = true; + } + private CustomColour GetDirectionColour(string callsign, FDR fdr) { - if (eastboundCallsigns.TryGetValue(callsign, out bool east)) + if (eastboundCallsigns.TryGetValue(callsign, out var east)) { if (east) return EastboundColour; - else - return WestboundColour; + return WestboundColour; } return default; @@ -635,30 +585,18 @@ private CustomColour GetDirectionColour(string callsign, FDR fdr) private CustomColour GetConflictColour(string callsign) { if (imminentConflict.Count % 2 == 0 && imminentConflict.TryGetValue(callsign, out _)) - { return Imminent; - } - else if (advisoryConflict.Count % 2 == 0 && advisoryConflict.TryGetValue(callsign, out _)) - { - return Advisory; - } - + if (advisoryConflict.Count % 2 == 0 && advisoryConflict.TryGetValue(callsign, out _)) return Advisory; + return default; } - private CustomColour ExcludeConflictColor(Track track, FDP2.FDR flightDataRecord) + private CustomColour ExcludeConflictColor(Track track, FDR flightDataRecord) { if ((imminentConflict.Count > 0 || advisoryConflict.Count > 0) && track.State == MMI.HMIStates.Jurisdiction) - { return GetDirectionColour(flightDataRecord.Callsign, flightDataRecord); - } - else if (imminentConflict.Count > 0 || advisoryConflict.Count > 0) - { - return ApsBlue; - } + if (imminentConflict.Count > 0 || advisoryConflict.Count > 0) return ApsBlue; return default; - } - } } \ No newline at end of file diff --git a/MEARTSLabelItemsPlugin.cs b/MEARTSLabelItemsPlugin.cs deleted file mode 100644 index defb0b9..0000000 --- a/MEARTSLabelItemsPlugin.cs +++ /dev/null @@ -1,319 +0,0 @@ -using System; -using System.Collections.Concurrent; -using System.ComponentModel.Composition; //<--Need to add a reference to System.ComponentModel.Composition -using System.Text.RegularExpressions; -using vatsys; -using vatsys.Plugin; - - -//Note the reference to vatsys (set Copy Local to false) -----> - -namespace AuroraLabelItemsPlugin -{ - [Export(typeof(IPlugin))] - - public class MEARTSLabelItemsPlugin : ILabelPlugin - { - - /// The name of the custom label item we've added to Labels - /// in the Profile - const string LABEL_ITEM_SELECT_HORI = "SELECT_HORI"; - const string LABEL_ITEM_SELECT_VERT = "SELECT_VERT"; - const string LABEL_ITEM_COMM_ICON = "AURORA_COMM_ICON"; //field a(2) - const string LABEL_ITEM_ADSB_CPDLC = "AURORA_ADSB_CPDLC"; //field c(4) - const string LABEL_ITEM_ADS_FLAGS = "AURORA_ADS_FLAGS"; //field c(4) - const string LABEL_ITEM_MNT_FLAGS = "AURORA_MNT_FLAGS"; //field c(4) - const string LABEL_ITEM_SCC = "AURORA_SCC"; //field c(5) - const string LABEL_ITEM_ANNOT_IND = "AURORA_ANNOT_IND"; //field e(1) - const string LABEL_ITEM_RESTR = "AURORA_RESTR"; //field f(1) - const string LABEL_ITEM_VMI = "AURORA_VMI"; //field h(1) - const string LABEL_ITEM_CLEARED_LEVEL = "AURORA_CLEARED_LEVEL"; //field i(7) - const string LABEL_ITEM_RADAR_IND = "AURORA_RADAR_IND"; //field k(1) - const string LABEL_ITEM_FILED_SPEED = "AURORA_FILEDSPEED"; //field m(4) - const string LABEL_ITEM_3DIGIT_GROUNDSPEED = "AURORA_GROUNDSPEED"; //field n(5) - readonly static CustomColour EastboundColour = new CustomColour(240, 255, 255); - readonly static CustomColour WestboundColour = new CustomColour(240, 231, 140); - readonly static CustomColour NonRVSM = new CustomColour(242, 133, 0); - readonly static CustomColour Probe = new CustomColour(0, 255, 0); - readonly static CustomColour NotCDA = new CustomColour(100, 0, 100); - readonly ConcurrentDictionary eastboundCallsigns = new ConcurrentDictionary(); - readonly ConcurrentDictionary adsbcpdlcValues = new ConcurrentDictionary(); - readonly ConcurrentDictionary adsflagValues = new ConcurrentDictionary(); - readonly ConcurrentDictionary mntflagValues = new ConcurrentDictionary(); - readonly ConcurrentDictionary altValues = new ConcurrentDictionary(); - readonly ConcurrentDictionary radartoggle = new ConcurrentDictionary(); - readonly ConcurrentDictionary adsflagtoggle = new ConcurrentDictionary(); - readonly ConcurrentDictionary mntflagtoggle = new ConcurrentDictionary(); - readonly ConcurrentDictionary downlink = new ConcurrentDictionary(); - - public MEARTSLabelItemsPlugin() - { - Network.PrivateMessagesChanged += Network_PrivateMessagesChanged; - Network.RadioMessageAcknowledged += Network_RadioMessageAcknowledged; - } - - - private void Network_RadioMessageAcknowledged(object sender, RadioMessageEventArgs e) - { - throw new NotImplementedException(); - } - - private void Network_PrivateMessagesChanged(object sender, Network.GenericMessageEventArgs e) - { - bool downLink = e.Message.Sent == true; - - if (downLink) - { - downlink.TryRemove(e.Message.Address, out _); - } - else - { - downlink.TryAdd(e.Message.Address, 0); - } - - } - - /// Plugin Name - public string Name { get => "Aurora Label Items"; } - - /// This is called each time a flight data record is updated - /// Here we are updating the eastbound callsigns dictionary with each flight data record - /// When the FDR is updated we check if it still exists in the Flight Data Processor and remove from our dictionary if not. Otherwise we do some simple regex matching to find - /// the flight planned PBN category and store the character we want to display in the label in the dictionary. - public void OnFDRUpdate(FDP2.FDR updated) - { - if (FDP2.GetFDRIndex(updated.Callsign) == -1) - { - - altValues.TryRemove(updated.Callsign, out _); - - } - else - { - int cfl; - bool isCfl = Int32.TryParse(updated.CFLString, out cfl); - var vs = updated.PredictedPosition.VerticalSpeed; - int level = updated.PRL / 100; - - - - - char h1 = default; - - if (level == cfl || level == updated.RFL)//level - h1 = default; - - else if (cfl > level || vs > 300)//Issued or trending climb - h1 = '↑'; - - else if (cfl > 0 && cfl < level || vs < -300)//Issued or trending descent - h1 = '↓'; - - else if (level - updated.RFL / 100 >= 3)//deviating above - h1 = '+'; - - else if (level - updated.RFL / 100 <= -3)//deviating below - h1 = '-'; - - - altValues.AddOrUpdate(updated.Callsign, h1, (k, v) => h1); - - - - if (updated.ParsedRoute.Count > 1) - { - //calculate track from first route point to last (Departure point to destination point) - var rte = updated.ParsedRoute; - double trk = Conversions.CalculateTrack(rte.First().Intersection.LatLong, rte.Last().Intersection.LatLong); - bool east = trk >= 0 && trk < 180; - eastboundCallsigns.AddOrUpdate(updated.Callsign, east, (c, e) => east); - } - } - } - - - /// Could use the new position of the radar track or its change in state (cancelled, etc.) to do some processing. - public void OnRadarTrackUpdate(RDP.RadarTrack updated) - { - - } - - - private void HandleRadarFlagClick(CustomLabelItemMouseClickEventArgs e) - { - - } - private void HandleADSFlagClick(CustomLabelItemMouseClickEventArgs e) - { - - } - - private void HandleMNTFlagClick(CustomLabelItemMouseClickEventArgs e) - { - - } - /// vatSys calls this function when it encounters a custom label item (defined in Labels.xml) during the label rendering. - /// itemType is the value of the Type attribute in Labels.xml - /// If it's not our item being called (another plugins, for example), return null. - /// As a general rule, don't do processing in here as you'll slow down the ASD refresh. In the case of parsing a level to a string though, that's fine. - public CustomLabelItem GetCustomLabelItem(string itemType, Track track, FDP2.FDR flightDataRecord, RDP.RadarTrack radarTrack) - { - - if (flightDataRecord == null || track == null) - return null; - - - bool selectedCallsign = MMI.SelectedTrack?.GetFDR()?.Callsign == flightDataRecord.Callsign; - - - switch (itemType) - { - case LABEL_ITEM_SELECT_HORI: - - if (selectedCallsign) - { - return new CustomLabelItem() - - { - Border = BorderFlags.Top - }; - } - - else - { - return new CustomLabelItem() - - { - Border = BorderFlags.None - }; - } - - case LABEL_ITEM_SELECT_VERT: - - if (selectedCallsign) - { - return new CustomLabelItem() - { - Text = "", - Border = BorderFlags.Left - }; - } - - else - { - return new CustomLabelItem() - { - Text = "", - Border = BorderFlags.None - }; - } - - - - - - //case LABEL_ITEM_SCC: - // - // return new CustomLabelItem() - // { - // Text = pos //| ca | la | ra | rcf | dup | spd - // }; - - - case LABEL_ITEM_ANNOT_IND: - bool scratch = String.IsNullOrEmpty(flightDataRecord.LabelOpData); - - if (scratch) - { - return new CustomLabelItem() - { - Text = "◦" - }; - } - - else - { - return new CustomLabelItem() - { - Text = "&" - }; - } - - case LABEL_ITEM_RESTR: - - if (flightDataRecord.LabelOpData.Contains("AT") || flightDataRecord.LabelOpData.Contains("BY") || flightDataRecord.LabelOpData.Contains("CLEARED TO")) - - return new CustomLabelItem() - { - Text = "x" - }; - - return null; - - - case LABEL_ITEM_CLEARED_LEVEL: - - return new CustomLabelItem() - { - Text = (track.NewCFL && radarTrack.ReachedCFL) ? string.Empty : flightDataRecord.CFLString, - ForeColourIdentity = Colours.Identities.Custom, - CustomForeColour = !flightDataRecord.RVSM ? NonRVSM : Probe - }; - - - - case LABEL_ITEM_FILED_SPEED: - var mach = flightDataRecord.TAS / 581.0; - return new CustomLabelItem() - { - Text = "M" + Convert.ToDecimal(mach).ToString("F2").Replace(".", "") - //Text = "N" + flightDataRecord.TAS - }; - - case LABEL_ITEM_3DIGIT_GROUNDSPEED: - //get groundspeed value from either FDR or radarTrack if coupled - var gs = radarTrack == null ? flightDataRecord.PredictedPosition.Groundspeed : radarTrack.GroundSpeed; - return new CustomLabelItem() - { - Text = "N" + gs.ToString("000")//format as 3 digits (with leading zeros) - }; - - default: - return null; - } - } - - public CustomColour SelectASDTrackColour(Track track) - { - //only apply East/West colour to jurisdiction state - if (track.State != MMI.HMIStates.Jurisdiction) - return null; - - var fdr = track.GetFDR(); - //if track doesn't have an FDR coupled do nothing - if (fdr == null) - return null; - - //read our dictionary of stored bools (true means is easterly) and return the correct colour - return GetDirectionColour(fdr.Callsign); - } - - public CustomColour SelectGroundTrackColour(Track track) - { - return null; - } - - private CustomColour GetDirectionColour(string callsign) - { - if (eastboundCallsigns.TryGetValue(callsign, out bool east)) - { - if (east) - return EastboundColour; - else - return WestboundColour; - } - - return null; - } - } -} \ No newline at end of file diff --git a/Properties/AssemblyInfo.cs b/Properties/AssemblyInfo.cs index b2c5e45..97e0d2e 100644 --- a/Properties/AssemblyInfo.cs +++ b/Properties/AssemblyInfo.cs @@ -32,4 +32,4 @@ // by using the '*' as shown below: // [assembly: AssemblyVersion("1.0.*")] [assembly: AssemblyVersion("1.0.0.0")] -[assembly: AssemblyFileVersion("1.0.0.0")] +[assembly: AssemblyFileVersion("1.0.0.0")] \ No newline at end of file diff --git a/Strips.cs b/Strips.cs deleted file mode 100644 index e9f42bc..0000000 --- a/Strips.cs +++ /dev/null @@ -1,620 +0,0 @@ -using System; -using System.Text.RegularExpressions; -using vatsys; -using vatsys.Plugin; -using System.Collections.Concurrent; -using System.ComponentModel.Composition; //<--Need to add a reference to System.ComponentModel.Composition -using static vatsys.FDP2; -using System.Collections.Generic; -using System.Linq; -using AuroraLabelItemsPlugin; - -namespace AuroraStripItemsPlugin -{ - [Export(typeof(IPlugin))] - - public class AuroraStripItemsPlugin : IStripPlugin - { - AuroraLabelItemsPlugin.GEO label = new AuroraLabelItemsPlugin.GEO(); - CPAR.ConflictData cpar = new CPAR.ConflictData(); - FPAP fpap = new FPAP(); - /// The name of the custom label item we've added to Labels - /// in the Profile - const string LABEL_ITEM_ADSB_CPDLC = "AURORA_ADSB_CPDLC"; //field c(4) - const string STRIP_ITEM_CALLSIGN = "AURORA_CALLSIGN"; - const string STRIP_ITEM_CTLSECTOR = "AURORA_CDA"; - const string STRIP_ITEM_NXTSECTOR = "AURORA_NDA"; - const string STRIP_ITEM_T10_FLAG = "AURORA_T10_FLAG"; - const string STRIP_ITEM_MNT_FLAG = "AURORA_MNT_FLAG"; - const string STRIP_ITEM_DIST_FLAG = "AURORA_DIST_FLAG"; - const string STRIP_ITEM_RVSM_FLAG = "AURORA_RVSM_FLAG"; - const string STRIP_ITEM_VMI = "AURORA_STRIP_VMI"; - const string STRIP_ITEM_COMPLEX = "AURORA_STRIP_COMPLEX"; - const string STRIP_ITEM_CLEARED_LEVEL = "AURORA_CLEARED_LEVEL"; - const string STRIP_ITEM_REQUESTED_LEVEL = "AURORA_REQUESTED_LEVEL"; - const string STRIP_ITEM_MAN_EST = "AURORA_MAN_EST"; - const string STRIP_ITEM_POINT = "AURORA_POINT"; - const string STRIP_ITEM_ROUTE = "AURORA_ROUTE_STRIP"; - const string STRIP_ITEM_RADAR_IND = "AURORA_RADAR_IND"; - const string STRIP_ITEM_ANNOT_IND = "AURORA_ANNOT_STRIP"; - const string STRIP_ITEM_LATERAL_FLAG = "AURORA_LATERAL_FLAG"; - const string STRIP_ITEM_RESTR = "AURORA_RESTR_STRIP"; - const string STRIP_ITEM_CLRD_RTE = "AURORA_CLRD_RTE"; - const string CPAR_ITEM_TYPE = "CPAR_TYP"; - const string CPAR_ITEM_REQUIRED = "CPAR_REQUIRED"; - const string CPAR_ITEM_ANGLE = "CPAR_ANGLE"; - const string CPAR_ITEM_LOS = "CPAR_LOS"; - const string CPAR_ITEM_ACTUAL = "CPAR_ACTUAL"; - const string CPAR_ITEM_PASSING = "CPAR_PASSING"; - const string CPAR_ITEM_CONF_SEG_START_1 = "CPAR_CONF_SEG_START_1"; - const string CPAR_ITEM_CONF_SEG_START_2 = "CPAR_CONF_SEG_START_2"; - const string CPAR_ITEM_CONF_SEG_END_1 = "CPAR_CONF_SEG_END_1"; - const string CPAR_ITEM_CONF_SEG_END_2 = "CPAR_CONF_SEG_END_2"; - const string CPAR_ITEM_STARTIME_1 = "CPAR_START_TIME_1"; - const string CPAR_ITEM_STARTIME_2 = "CPAR_START_TIME_2"; - const string CPAR_ITEM_ENDTIME_1 = "CPAR_END_TIME_1"; - const string CPAR_ITEM_ENDTIME_2 = "CPAR_END_TIME_2"; - const string CPAR_ITEM_AID_2 = "CPAR_AID_2"; - const string CPAR_ITEM_TYP_2 = "CPAR_TYP_2"; - const string CPAR_ITEM_SPD_2 = "CPAR_SPD_2"; - const string CPAR_ITEM_ALT_2 = "CPAR_ALT_2"; - readonly static CustomColour NonRVSM = new CustomColour(242, 133, 0); - readonly static CustomColour SepFlags = new CustomColour(0, 196, 253); - readonly static CustomColour Pending = new CustomColour(46, 139, 87); - readonly static CustomColour NotCDA = new CustomColour(100, 0, 100); - readonly ConcurrentDictionary eastboundCallsigns = new ConcurrentDictionary(); - readonly ConcurrentDictionary flagtoggle = new ConcurrentDictionary(); - - /// Plugin Name - public string Name { get => "Aurora Label Items"; } - - public void OnFDRUpdate(FDP2.FDR updated) - { - if (FDP2.GetFDRIndex(updated.Callsign) == -1) //FDR was removed (that's what triggered the update) - { - eastboundCallsigns.TryRemove(updated.Callsign, out _); - flagtoggle.TryRemove(updated.Callsign, out _); - } - - else - - { - - if (updated.ParsedRoute.Count > 1) - { - //calculate track from first route point to last (Departure point to destination point) - var rte = updated.ParsedRoute; - double trk = Conversions.CalculateTrack(rte.First().Intersection.LatLong, rte.Last().Intersection.LatLong); - bool east = trk >= 0 && trk < 180; - eastboundCallsigns.AddOrUpdate(updated.Callsign, east, (c, e) => east); - } - } - } - - /// This is called each time a radar track is updated - public void OnRadarTrackUpdate(RDP.RadarTrack updated) - { - - } - - //public void Estimates(FDP2.FDR.ExtractedRoute.Segment estimate) - //{ - // estimate.IsPETO = true; - //} - - private void ItemMouseClick(CustomStripItemMouseClickEventArgs e) - { - bool flagToggled = flagtoggle.TryGetValue(e.Track.GetFDR().Callsign, out _); - - if (flagToggled) - { - flagtoggle.TryRemove(e.Track.GetFDR().Callsign, out _); - } - else - { - flagtoggle.TryAdd(e.Track.GetFDR().Callsign, 0); - } - e.Handled = true; - } - public CustomStripItem GetCustomStripItem(string itemType, Track track, FDP2.FDR flightDataRecord, RDP.RadarTrack radarTrack) - - { - int level = radarTrack == null ? flightDataRecord.PRL / 100 : radarTrack.CorrectedAltitude / 100; - bool isEastBound = true; - eastboundCallsigns.TryGetValue(flightDataRecord.Callsign, out isEastBound); - - - if (flightDataRecord == null) - return null; - - switch (itemType) - { - case STRIP_ITEM_CALLSIGN: - - - if (isEastBound) - { - return new CustomStripItem() - { - BackColourIdentity = Colours.Identities.StripText, - ForeColourIdentity = Colours.Identities.StripBackground, - Text = flightDataRecord.Callsign - }; - } - else - { - return new CustomStripItem() - { - BackColourIdentity = Colours.Identities.StripBackground, - ForeColourIdentity = Colours.Identities.StripText, - Text = flightDataRecord.Callsign - }; - } - - case STRIP_ITEM_CTLSECTOR: - - bool pendingCoordination = flightDataRecord.State == (FDR.FDRStates.STATE_PREACTIVE | FDR.FDRStates.STATE_COORDINATED); - string sectorName = flightDataRecord.ControllingSector == null ? "" : flightDataRecord.ControllingSector.Name; - - { - return new CustomStripItem() - { - ForeColourIdentity = pendingCoordination ? Colours.Identities.Custom : default, - CustomForeColour = Pending, - Text = sectorName - }; - } - - - - - case STRIP_ITEM_NXTSECTOR: - - TOC toc; - toc = new TOC(flightDataRecord); - - string firName = toc.nextSector == null ? "" : toc.nextSector.Name; - - { - return new CustomStripItem() - { - ForeColourIdentity = Colours.Identities.Custom, - CustomForeColour = Pending, - Text = firName - }; - } - - - - case LABEL_ITEM_ADSB_CPDLC: - - - if (!isEastBound && !flightDataRecord.ADSB && fpap.cpdlc) - - return new CustomStripItem() - { - BackColourIdentity = Colours.Identities.StripBackground, - ForeColourIdentity = Colours.Identities.StripText, - Text = "⧆" - }; - - if (isEastBound && !flightDataRecord.ADSB && fpap.cpdlc) - - return new CustomStripItem() - { - BackColourIdentity = Colours.Identities.StripText, - ForeColourIdentity = Colours.Identities.StripBackground, - Text = "⧆" - }; - - if (!isEastBound && !flightDataRecord.ADSB) - - return new CustomStripItem() - { - BackColourIdentity = Colours.Identities.StripBackground, - ForeColourIdentity = Colours.Identities.StripText, - Text = "⎕" - }; - - if (isEastBound && !flightDataRecord.ADSB) - - return new CustomStripItem() - { - BackColourIdentity = Colours.Identities.StripText, - ForeColourIdentity = Colours.Identities.StripBackground, - Text = "⎕" - }; - - if (!isEastBound && flightDataRecord.ADSB) - - return new CustomStripItem() - { - BackColourIdentity = Colours.Identities.StripBackground, - ForeColourIdentity = Colours.Identities.StripText, - Text = "*" - }; - - if (isEastBound && fpap.cpdlc) - - return new CustomStripItem() - { - BackColourIdentity = Colours.Identities.StripText, - ForeColourIdentity = Colours.Identities.StripBackground, - Text = "*" - }; - - return null; - - case STRIP_ITEM_T10_FLAG: - - if (flightDataRecord.PerformanceData?.IsJet ?? false) - - return new CustomStripItem() - { - //BackColourIdentity = Colours.Identities.Custom, - //CustomBackColour = SepFlags, - Text = "M" - //OnMouseClick = ItemMouseClick - }; - - return null; - - case STRIP_ITEM_MNT_FLAG: - - if (flightDataRecord.PerformanceData?.IsJet ?? false) - - return new CustomStripItem() - { - //BackColourIdentity = Colours.Identities.Custom, - //CustomBackColour = SepFlags, - Text = "R" - }; - - return null; - - case STRIP_ITEM_DIST_FLAG: - - if (fpap.adsc && fpap.cpdlc && (fpap.rnp4 || fpap.rnp10) && fpap.pbcs) - - - return new CustomStripItem() - { - BackColourIdentity = Colours.Identities.Custom, - CustomBackColour = SepFlags, - Text = fpap.rnp4 ? "3" : "D" - }; - return null; - - case STRIP_ITEM_RVSM_FLAG: - - if (flightDataRecord.RVSM) - - return new CustomStripItem() - { - BackColourIdentity = Colours.Identities.Custom, - CustomBackColour = SepFlags, - Text = "W" - }; - - return null; - - case STRIP_ITEM_VMI: - var vs = radarTrack == null ? flightDataRecord.PredictedPosition.VerticalSpeed : radarTrack.VerticalSpeed; - - if (level == fpap.cfl || level == flightDataRecord.RFL)//level - - return new CustomStripItem() - { - Text = "" - }; - else if (fpap.cfl > level && track.NewCFL || vs > 300)//Issued or trending climb - - return new CustomStripItem() - { - Text = "↑", - }; - - else if (fpap.cfl > 0 && fpap.cfl < level && track.NewCFL || vs < -300)//Issued or trending descent - - return new CustomStripItem() - { - Text = "↓", - }; - - return null; - - case STRIP_ITEM_COMPLEX: - - if (flightDataRecord.LabelOpData.Contains("AT ") || flightDataRecord.LabelOpData.Contains(" BY ") || - flightDataRecord.LabelOpData.Contains("CLEARED TO ")) - - return new CustomStripItem() - { - Text = "*" - }; - - return null; - - case STRIP_ITEM_CLEARED_LEVEL: - - if (fpap.cfl == 0) - { - return new CustomStripItem() - { - Text = "" - }; - } - - else - { - return new CustomStripItem() - { - Text = fpap.cfl.ToString() - }; - } - - case STRIP_ITEM_REQUESTED_LEVEL: - - if (flightDataRecord.State == FDR.FDRStates.STATE_INACTIVE || flightDataRecord.State == FDR.FDRStates.STATE_INACTIVE) - { - return new CustomStripItem() - { - Text = fpap.rfl.ToString(), - }; - } - - else - { - return new CustomStripItem() - { - Text = "" - }; - } - - //case STRIP_ITEM_MAN_EST: - - //if (Estimates) - // return new CustomStripItem() - // { - // BackColourIdentity = Colours.Identities.HighlightedText - // }; - //return null; - - //case STRIP_ITEM_POINT: - // Coordinate coordinate = Conversions.ConvertToCoordinate(FDR.ExtractedRoute); - // - // if (StripItemType.Point == ) - // return new CustomStripItem() - // { - // Text = Conversions.ConvertToFlightplanLatLong() - // }; - case STRIP_ITEM_ROUTE: - - return new CustomStripItem() - { - Text = "F", - //OnMouseClick = ItemMouseClick - }; - - - case STRIP_ITEM_RADAR_IND: - - return new CustomStripItem() - { - Text = "A", - //OnMouseClick = - }; - - - case STRIP_ITEM_ANNOT_IND: - - bool scratch = String.IsNullOrEmpty(flightDataRecord.LabelOpData); - - if (scratch) - { - return new CustomStripItem() - { - Text = "." - }; - } - - else - { - return new CustomStripItem() - { - Text = "&" - }; - } - - - case STRIP_ITEM_LATERAL_FLAG: - - if (fpap.adsc && fpap.cpdlc && (fpap.rnp4 || fpap.rnp10) && fpap.pbcs) - - - return new CustomStripItem() - { - BackColourIdentity = Colours.Identities.Custom, - CustomBackColour = SepFlags, - Text = fpap.rnp4 ? "4" : fpap.rnp10 ? "R" : "", - //OnMouseClick = ItemMouseClick - }; - return null; - - case STRIP_ITEM_RESTR: - - if (flightDataRecord.LabelOpData.Contains("AT ") || flightDataRecord.LabelOpData.Contains(" BY ") || - flightDataRecord.LabelOpData.Contains("CLEARED TO ")) - - return new CustomStripItem() - { - Text = "x" - }; - - return null; - - case STRIP_ITEM_CLRD_RTE: - - return new CustomStripItem() - { - Text = "Cleared Route:" + flightDataRecord.RouteNoParse - }; - - //if (label.imminentConflict.TryGetValue(flightDataRecord.Callsign, out _) || (label.advisoryConflict.TryGetValue(flightDataRecord.Callsign, out)) == flightDataRecord.Callsign; - - case CPAR_ITEM_TYPE: - - return new CustomStripItem() - { - Text = cpar.conflictType - }; - - case CPAR_ITEM_REQUIRED: - - if(cpar.longType == cpar.timeLongsame) - - return new CustomStripItem() - { - Text = "REQUIRED " + cpar.longTimesep + " ( " + cpar.latSep + ") " + cpar.verticalSep + " ft" - }; - - else - return new CustomStripItem() - { - Text = "REQUIRED " + cpar.longDistsep + " ( " + cpar.latSep + ") " + cpar.verticalSep + " ft" - }; - - case CPAR_ITEM_ANGLE: - - return new CustomStripItem() - { - Text = cpar.trkAngle.ToString() + " degrees" - }; - - case CPAR_ITEM_LOS: - - return new CustomStripItem() - { - Text = cpar.earliestLOS.ToString() - }; - - case CPAR_ITEM_ACTUAL: - - if (cpar.longType == cpar.timeLongsame) - - return new CustomStripItem() - { - Text = " ACTUAL " + cpar.longTimeact + " ( " + cpar.latAct + ") " + cpar.verticalAct + " ft" - }; - - else - return new CustomStripItem() - { - Text = " ACTUAL " + cpar.longDistact + " ( " + cpar.latAct +") " + cpar.verticalAct + " ft" - }; - - case CPAR_ITEM_PASSING: - - return new CustomStripItem() - { - Text = cpar.top.Time.ToString() - }; - - case CPAR_ITEM_CONF_SEG_START_1: - - return new CustomStripItem() - { - Text = cpar.startLatlong.ToString() - }; - - case CPAR_ITEM_CONF_SEG_START_2: - - return new CustomStripItem() - { - Text = cpar.startLatlong.ToString() - }; - - case CPAR_ITEM_CONF_SEG_END_1: - - return new CustomStripItem() - { - Text = cpar.endLatlong.ToString() - }; - - case CPAR_ITEM_CONF_SEG_END_2: - - return new CustomStripItem() - { - Text = cpar.endLatlong.ToString() - }; - - case CPAR_ITEM_STARTIME_1: - - return new CustomStripItem() - { - Text = cpar.startTime.ToString() - }; - - case CPAR_ITEM_STARTIME_2: - - return new CustomStripItem() - { - Text = cpar.startTime.ToString() - }; - - case CPAR_ITEM_ENDTIME_1: - - return new CustomStripItem() - { - Text = cpar.endTime.ToString() - }; - - case CPAR_ITEM_ENDTIME_2: - - return new CustomStripItem() - { - Text = cpar.endTime.ToString() - }; - - case CPAR_ITEM_AID_2: - - return new CustomStripItem() - { - Text = cpar.fdr2.Callsign - }; - - case CPAR_ITEM_TYP_2: - - return new CustomStripItem() - { - Text = cpar.fdr2.AircraftType - }; - - case CPAR_ITEM_SPD_2: - - return new CustomStripItem() - { - Text = cpar.fdr2.TAS.ToString() - }; - - case CPAR_ITEM_ALT_2: - - return new CustomStripItem() - { - Text = cpar.fdr2.PredictedPosition.Altitude.ToString() - }; - - default: return null; - } - } - //private CustomColour PETOColor(FDP2.FDR.ExtractedRoute.Segment estimate, Colours.Identities state) - //{ - // if (estimate.IsPETO) - // { - // return state = state; - // } - // - // return null; - //} - } -} diff --git a/TOC.cs b/TOC.cs index 01bbfc6..8bd4645 100644 --- a/TOC.cs +++ b/TOC.cs @@ -1,71 +1,53 @@ #region Assembly vatSys, Version=0.4.8114.34539, Culture=neutral, PublicKeyToken=null + // E:\vatsys\bin\vatSys.exe // Decompiled with ICSharpCode.Decompiler 7.1.0.6543 + #endregion using System; using System.Collections.Generic; -using System.ComponentModel; -using System.Drawing; using System.Linq; - namespace vatsys { public class TOC { public FDP2.FDR fdr; - - public List sectors; public SectorsVolumes.Sector nextSector; + public List sectors; + public TOC(FDP2.FDR fdr) { this.fdr = fdr; - FDP2.FDR.ExtractedRoute.Segment segment = (from s in fdr.ParsedRoute.ToList() - where s.Type == FDP2.FDR.ExtractedRoute.Segment.SegmentTypes.ZPOINT && fdr.ControllingSector != SectorsVolumes.FindSector((SectorsVolumes.Volume)s.Tag) - select s).FirstOrDefault((FDP2.FDR.ExtractedRoute.Segment s) => s.ETO > DateTime.UtcNow); + var segment = (from s in fdr.ParsedRoute.ToList() + where s.Type == FDP2.FDR.ExtractedRoute.Segment.SegmentTypes.ZPOINT && fdr.ControllingSector != + SectorsVolumes.FindSector((SectorsVolumes.Volume)s.Tag) + select s).FirstOrDefault(s => s.ETO > DateTime.UtcNow); SectorsVolumes.Volume volume = null; - if (segment != null) - { - volume = (SectorsVolumes.Volume)segment.Tag; - } + if (segment != null) volume = (SectorsVolumes.Volume)segment.Tag; if (volume != null) - { nextSector = SectorsVolumes.FindSector(volume); - } else - { nextSector = null; - } if (nextSector != null) { SectorsVolumes.Sector sector = null; - foreach (SectorsVolumes.Sector s2 in SectorsVolumes.SectorGroupings.Keys) - { - if (s2.SubSectors.Contains(nextSector) && (sector == null || sector.SubSectors.Count > s2.SubSectors.Count)) - { + foreach (var s2 in SectorsVolumes.SectorGroupings.Keys) + if (s2.SubSectors.Contains(nextSector) && + (sector == null || sector.SubSectors.Count > s2.SubSectors.Count)) sector = s2; - } - } - if (sector != null) - { - nextSector = sector; - } + if (sector != null) nextSector = sector; } - } + public void HandoffNextSector() - { - if (nextSector != null) - { - MMI.HandoffJurisdiction(fdr, nextSector); - } - } + { + if (nextSector != null) MMI.HandoffJurisdiction(fdr, nextSector); } } - - +} \ No newline at end of file diff --git a/bin/Release/AuroraLabelItemsPlugin.dll b/bin/Release/AuroraLabelItemsPlugin.dll deleted file mode 100644 index d97d583dd83b2e296a7173c9477a24e0ae74c5f8..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 10752 zcmeHNeRLdGb-y#SvtPE>*6Pc49D8j?j;xQ3EZL46C&8=Tm8^Irt+lcsiD5n39m|V% zch)nzwuP!3`9Pe|q_l3JB%I?O0!bTFph*gcq-}ZvAt?vQfs|5CO4BB!0ZvH@p`4yT zi__nIGrQWA6F9W}uN`^r+^=`vefQmW-vaTBc-xNQ5)3`dRV;~>E2OQEB; zvnu~vemW$xaHU~)l98iCKjc8Hyq1VogZJ=$qM?gJbvKyEd2-QK_3+`c?WAOn_=ujAkN#R}i3WuuWcQ!6|(Th-xf0}j4)Z2u)! zkJP>hv#$DXJqyh7Tympxw{->D8yf+(ce}g4rz~6vR53OIx@^Zc15NjCv_g1xnpb0d zi(3SGkkPF`yIZ@_JCFJ22pmG+toF&R-Kqhn{ALPjU6?b!YIHK4V|qKVzM#V~s+=CF z16t_9Z&s?j?W%!E@vrJMb})aT#<%ISHCi>`g@3!!g>buD)MhpG5Pi|uy&uRQe(N*w z-B$v+_o~(__Pq>e9p=7!fe*#uH5jKaeB=1OM{FTC4d;e>Y>E5g-#@jx11guEj9B3= zAj}C{L#u50!%s!Nx$l0vW#@M<{d;)B(CY|;V&1{taR9Fq9sPq~atLkahq?E^7R-w^ z=FgbjjkeOou&eRql zvFFp%eo1ntdz&4>$z?%bl~<|p+^&TljBwp0Dc$F@@ePAcy4;3Tb}jZo+-c4)x2RcO z=CyV^oh{bXRHF|K&9h*Le5tj%ucp%49dPxo4!DdkG&g5&?eVF`H8#3hHBdwSL8WUa z9^1XDF<=XBUO!MB#D$unI`QUT_E+Wi*W|Fv%`eHWg+V;ieL-}(3)nVH4AGP3{ykSa z19-67sMF5KKBcusy=_f35ZzT%uD3Jwd3ZWSBw$SX9I26_W(C=O2?sebR1X1^G0fw#JTU{NC5$Lj0HA|t# zv5HhK0RJoH3Lz8q3s&u{UA?k!HLWOIEv}9hRTNCc{35sFdeOIA5vA6y6K6Rr=1W!K zbuS89k{#vi-T*!HZvb`-R1qXp*Zr`xy;<$uYDIx{ZeF_>6VEk^aemr*izC3h9gQ`P z#@fp@npH36GL5>h<*m(`qD}~FtSJhJ=(k>g0%G$-0TIe>ENq)6%7Nguc6;3EW>?yG z6g!U)HoN*f=4K4JM>Tu!u-$IOyl${YF@pD<$HR_0&gWU&Q5V8Pu0wt({|^i$^D4$y8hc|o^_zRcWT)--X{0+a1J zTG)$Ro3rhkvv#8(NVo!DWI|Qsb6d0Adv)mP3meb++gJ6p${r&DU));g9*Lw|{GN_? zt@6mmICujuySq0zquC^jJ-mB3b<;5PV97rFoZ1!c4-fVa?!=nptj+`WdWg2&MszQp z5BPwm%4V)OXR*fh@NWn^z_!CFDkE_4pSF!29z&YY2SDesu(l27jagR41y$*tn?K?6 z0ij<=gM`Bg_l`9$j%GMm5Sr0C+zM{^EzV@sdqp0`J|VD@WXJdR4$@1uVFjvqQjP0e?&I4=H~F3)cwvu;6@DdD-Qr$K^Lv zKW%fjxdZfW*8^z#BQJA$!12?NfM+~y;G??x{B&4;!Rx0#RT*AGFL+PTLvYfd&%td! z-7mf1JxvQJAAb6_$``=Hr>>uzM%%`7TBqw3SLk1Ro*qocmB%YM3BP~VphdcGsCrY9WgD5xfS(rI_Q z=bz*Nz2>yrsJ7!xWcha6msixE$w7MhYNpQ79-kWvje_%eK$*^i zqX>?R&HAdumi}54UgXEI}%0;xj4tf1Ny(sOV*GZE{flo^ee+kX|rDxvHTd|I{Gufjr0}35WNm~6$P!-9-qv4nWIpdc)vH5#-BEDS zqnm$p&gTCe@_nV=18BLDXV+F2Rsyc;Z_K3Av7A-PYxB{(W?2IR>3+I?vN#f(I$X+X zW&Ot4G&p0$^56iC#F7IPHHw*vY3jvtESD+gjG|`FA041b&a_HeMu%3Vm^nH~*N+?7 zN?yN_u1}h|Q?N8vDCPA6+G*S>rkAx`-nx+{jB+#J;Kl!y$+6X~((_;@-M zjnJUQj?W>VuAU~!6{ zb$vx6i9~8_bfUhW=;Zi#dMr9QK^8(WW+mg(lQb1e(x_g>Y}Bhx#bK-7-gsmp4IU+R z^O#{4v|>h&X=P3LHHu@AmY*yMM#0J$W5A zt>o&cm_A#Xo73RivIZK@@MHYzesFjIP7|+1z1N0Ntc;rfe`2kGN))XSp~=jl5AY z>76JT^|T%25yM2<3I%(zBdM5}-Ug;!N9*}^YexxF7RzykL^P`H?4*t5w7H^zN|mvy zVW{S@h^0|V>E@|iM!!tV;o%}yliS4#Y0u%aNFa7jptM?o>yM z4vde9vS?9hwkXyX`qE1yc@1yocHnG$Mb<5+Z~PR@Mog&lQpKu7sk2D0#n(wY_+%7M z*)^>;oN4_05}wlMux?D06B8Q-f@E8Y9!JebBaXh!L49WpLIPve^8hXpO&|sgV$b&K^;IVL*SCd|-UyGK~m$6Oc>` zoeB6r>lc)js1@FE3}Ql){S$p7 ziuLgs6|p)jWGO@_E^Lyru}4y#*&!((*(NFY0;YVwQ|gGo#}HzaZMaD}137+DQ2Izx z&To;FdvGHTo_@Sf;G4c@Sm@K{#-5|_D}lchJR3#-E9EJ8lEmmnpc8=xUD?=v9NY=W z?by+(5Pai5#J7eIB5it3U)Xc|snp~he_N0qy5s)u;@hAkd6f`JDv;)8CIbv)rh^f$ z$0Y~X22VCYCEy~-8*sM;-z^7ZZ%CF~Xl;w+3Q_PRq+S)s(tR#>aOon0&-h4g!UO-j zZNa6_D*+icWohHOmXOjSwNQ&B*o?GDvRhV3mIDFV9q@YGvh4LX`8*^Cm!1v;U|n{( zo0pzd+`*gOthSb2ZW29yTXr|W;XnZG1Ay$s?f7y4$ZcM5d8A+gg9#R7#UshWxQvU1 zuh@f8+#y9$Rn_H@eO}m7yxuRo@5s#hT`ztx)EMT=6MSoo?>AhBenivnKB`Tc(re`K7N+uvzwCA_fJ4iVGGP2;pBK~Lsd zOjk(M{x%05vOf!VNEED{hC^Sv7zz#a51@eVkm#!2dv{*jKdWW>b`I>#^zG7Shx&$w zc4hmH?H(G`ckSudv^`k5t0nU6#0PTx;j^Yh8^aUv>Dt>suXBXG0Uyz?4G+NUKx<9t zyvp-?QY*I#)g&RIeN>`b8_suO=X}>2vUkniP}O{YcvpC6=gwW>!Ckut_x6UOl{~*~ z-B8pkIHl%$LrJ`rXUc8}L!SRz^k_Z#PZ$I(k^Ne%cPUHUJe%xDu)Lr}? zzy6v^#Zn*t(w!GiKX-BeL(hKs;9mrP`bjnzz3#|i3ul8Px#7xu(m1V~M=Wgn8U2W< zmkjI3ThGYA5o7kfNANy_!-oDgI^j}wmhOlwJ8?hbp=G)ryQfYM|0xA8wy}JET+0ggNAe6t>D)K zn!#R_28?4*($0nXPGt{-2rze;freA!R@;wdf{puIjE1|Bio60B-Cw~XM6 zX&xt)F)GqAoMiaAN_^9r7N?pb&L4SbmZ4`r$G#qRy$Yied@4gL2mah!So(_4vG-ht zyKp)}3}^#dN+`bu&PN6GU4#{!a>TW@PF6y{MViN$HKFII!1E4hRXvZvf`zXp>_@4= z&-&BZ^4VZrW10|imV|u+BduV*%5{&|Nr%WE&~4r D0qYKR diff --git a/bin/Release/AuroraLabelItemsPlugin.pdb b/bin/Release/AuroraLabelItemsPlugin.pdb deleted file mode 100644 index 3ab2de7b2bd28121d179a21051c7ab9899224cdf..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 26112 zcmeHP3vg7|c|I#E3gF5h41|Y`SAYNuX|=nOki^S+f~gV6NccgN!tUxyT3GEWcXyF+ z+{{i42~C=o@wj!}sWWsOH~3MH-OzDu<0)=viXAd_;-tk>(or)WH|}(TlW7_}C2qg( zJa(^ED~cCkW3$Kn`<=&s&VSB-{`0v1y>e$bWXIyM{)D@&rft%TzqitYwvvZxcBi_x2#w{ zw&(8W`_}F}`&V@>-}}xjov-}3pzNz#18;m<_0Qnd-P=O%rb+|6=kFBj%4Pz!2_RN1 zPKkNqP_S*OyV_mn@q4`0`1Ski{T_eas=9_yU&yyQ;P(ZC!Nx#cAkfzzT)ldA(ChPA zes6t~tQ^90pc6un`ur64*?nN0sXtqV?IOXNkgRzzaNzb7X8%gI^z(Y zHBpX|+)=(EDgm(`t$=|uz7oW?H>{og>>%PSr**K*0+~R|Fubpo|Kk{WX*uL&nUj~6 zWq4PfYkrZuPOEeBn)VBLaSiY}@4rBF&{LNT)PEsd8yevJuMw4H9IbKEJ9pAv~hE_|@C~9dw(2vIk7ks_q4?#5i69y zH7oAfWJN7I91=?$li-fuS4Dm&?xd7K&-z+xXXwjx!)iv+Pasm+t9dcS0ok+MB-kw=`KUHaXfay zlKH%AIO`_ty%lxmKm><^19Hr+lG~5>nA&+J3zq2gR7Y~x3HZdP(+5%X|m4*5vG9S&1%O8j{oxd%ZH88AoRgU&efL)jT6av{_!3W>Y z7@ld{u)_D|H7`ciSuM+)d2Aj>ZOL`Wm$Ib6b>rbNlxU5O<|S)`UfT!cE-pj`h3J5@ zv}BQyrNp#!w@abeO7Y+iKF-@1c)C!Zbqzn~hRtAp(st0_XUjRr$5vZ)KQHKh(k4v6 zK2_2@zMq@ySTfo-zN>lZ$E?Y3>PwGv-e*8=tC5Q}*&epl5vH|6-EhK&L9AzZ%^HEp zq;&(g15P4kqxtB^*vu?_0W$X>wu$Gil91_VXCO4VH8~Wt>>evLn3qn>ePA?)EZpNt z_8M6o@kDqCyA;-5K4UVvf0hRk!VA*qRlF2(;zka1ulA>Icw~mT0;OHvkN(|{x~yk- zjqXu3t^4f#$ytW|iCb5CAId6|dl%c}KIAO3qr*O2e`P)HMOkHa$in@{U55N|W#M=S zETNUwoA+Ar=(REj2Fjq9jEvuaWEJdDs0Lkh`9hI!Ut(=PmHbVdD`eYYCV8Wo~RK9?LuK6%LdB#?pK zJ0N2McO{X6j(Mj^Edl=g-217e!1YM`bei{_W~4U&TY!DQR^UNk8}JF>MqnwPyvoET zq-d80xUiVIXZBCXkv7#8!}63&duZ+5$`h zyMgqx20r()&XMhhQ{V%{rkp55LH;^tu-;SW~ zi-C_LT@L&f%KgBnk*)*2fOH4&6{PP5eh2A6;3=f{0KW%30Q^4iLE!7aBfuYm?>XQ< zBYgt+Cel9u{wvbI0**oMO&IvwNH+t2hV%gNS4dMKzXpB@_#5Ou3H+2x9C!(MgG;1- z44ml_5BwT97wJ+_37y|8O2t;tS3uiAHJ~-1CK-o{Feje@tq=>uBJ4NIG>(i*bKVr+ zT^gC*2V%NK^KR0(M`J|eeZUG`kFvg?F zRZXl1?<~Y`1F|p8KVAb&i%;?Qs=iT?cZR3s56GmsEe&o z+#%b@=#=%;S)9AxHeIhv)?1dIi(U*;otLiknY##Wflr1W@N+CXfZQMM0&j#GQ$Bz^@d(m?2z(rfxcCc~jba4;bC2a+51N}CrbAtaZ1^z}*7ibW40Q6^|6Clp< zjDQY+z6m-G8UyhRabtjupk7b{^bqK2&`Ho)5I30lpej&1=pN88=n$w7rcML=1E_`5 zYkt8wI|RKSMAL|hKSG@Ns7}A4@$YqhxlX?aCi49r=7rdy@lIX-InCdsaY*x%mvpb@ zr{jQWtYL{i(fsdeK9}ZuS(n#qtk(HWnh$%1tp9nP&wUD6;@@=sUz+}F?9};hYQCh- zU!d!|icv5jq|!MoM->y?CgMa#`8a0sxQd&dtP|o6`Kbwo$l%x}3*5t1{b`f2=<-R6 zFR=jar@-paRkNA9SU{Vo@QVlR0%oV&V&)dE!<_xp%b}!BM}Cv`*ex4 z<00c1b;wjax^8_&<}`Vy%yJYu>Zx*F4;L)c*MzK><@9sZQ{}o|L#D4|vR-Zno*Ad& z(RCYn2T=3DJz}z8&W6d#3;7>^4IC<=oh#ePrdp zcy!%B#@>(0x>*iOM?F=p>jg7=&Kw*!E|GCQ8aXOo^M^8hq@U2SmNQO7hb+aT>-Gt} zYgFsw7#=iTLOIfm9F?betqkvcIEq|CIm8UF%G134nK9h2d6oApqbrrK_@#sK3Y!?$ z_{emhi$_eESo{aG#k(VXe*GCT#z0kwH?vR&K3^}8@t>d2S@>F9#n={OCarR3i7||o zp-axUiksiupA>p>XA56jTdl9Qfd?>xk&|2QO!}Z?;92b$g3QY;U=q2WbsIvvcD0A` zbz)$DTLfRf`Th9#p`*6Gp`)c0r;Q31@6U93PcXdMSn1}g=y1fc`I(-(QZ%mKSnu~X z@LtPs@wRVBU%lpo7suteu&zB29f*XZ1MRU;atQCfZZQ_fY0me_XV2jH;9Ift?e!Tc0M~+zv%ge(IK{s34vwIe{w>J(*3i@H}#z? z%zF-mBWXfl**hTTdrQN_GWw*-O@;$mMqd+kksVk@-%>?(0n#j^KPX#&WMvusKjlnh z1(wl&gKcI)U>SWhlayZ zOJ#-&wx+C&e+xKGE5qawi>0;EXI2Eguu_qD4ZkFY5m3J0tzPC=y7`K|$mg>8HaW=- zgHMUgH`iL-QfKmq%2i>8oCFomlwX0^LmsvFvoA)tK|X`jYzasAa!V35J)LcMw`hr) zC_Vv-i<-C{su{EbeU=@>*Bg6PMnAT&cui=^zxtNaF0b*+{1ST#dT^01sJSNjUWxN? z1b2G|p2KFXVw(^%P>A=Uc$QN836E9o4~IZ}K3xT(Kb+z0o$!8NLYM=dmE;FE_u$7M z$hjBahxLC3`M45EzCoZNH{!=Z$7bVs7tc$)D;xo`&lMm>94*C#655^$PJ>Oy&O~sm#%^3 zm(E(?`~+&C@csWMa8f_Oka*S?{QvSjzdU;j{{IhPJZaWxa8x6~173$_jgDujoc9q& zxv84fLRNO}$H)mxnT%8>`v1h-7b)lcg!d2LW9WXMPvLe@4`??i0vZJ!038M$1swyO z0G$T$4)qr3UC;&4)#Cr>`Y-r@%%8Ged;TBZ!zT;oY?!RPkpJ=5K*9f)nL{2>1^-`u z{y(F|?TEYzntHEUzAavT9>uH8|M%6G$KIsvANjjOPmKKFiRPo -using System; -using System.Reflection; -[assembly: global::System.Runtime.Versioning.TargetFrameworkAttribute(".NETFramework,Version=v4.7.2", FrameworkDisplayName = ".NET Framework 4.7.2")] diff --git a/obj/Debug/DesignTimeResolveAssemblyReferencesInput.cache b/obj/Debug/DesignTimeResolveAssemblyReferencesInput.cache deleted file mode 100644 index 0598af6510617f8287d9303c4f8620e247bd0a8f..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 6879 zcmeHMdruoj5Vv_;FoYCSN(dyW)23CDx>ugzA@K*;xIqPkutO_x7Fpko&4%->ySoQC zh|khbQ1v6WGiUqEE3~S75`XwCkC%PSZ+3Qe@3%uN9*f2P#)p3CdDw%(+2*zsN|d#^ z&y~;Iy!IU~%#5g3g}0gANT>EeDlWX$nMHG&KIv4(ceO8J)dOEk=B87-e#zzbFHkRt zWAIi>({ts8@?v>r##xwVbF7~rmp+5E?sL~6yiHGo6t!O^tJOf7drWS6HD9YIIQR*3 zU2zJ|no>|Lx%G`R4IWvghOu`>cx7J6aTmsI<~iJ98d^Q6R!x*g;ODqTTKO4 z!nUz1Z8_mOIN#?~SzxjPIvkewOA7Q3Dp4;P-f_gO;2gGuWemJ@teClHPkh_ zKIXTpcy^=y@~D)H^HlnpnOQEu)| zo@<;FhFo(9ID5XQc@>&Nu4`&|Nlo|)_Mi+BJXDpFqKZmCqNYc(RU5d)=rMW?BNppL z*%Ob)4g8{v_59JFuPY5z3{PBNTT{T9KZ6I7+vXNJ>%+{!!5v+2N9;4#hh4_yhuN@e zUQ6y((y6Mlg>-qTy~pPN^A=lNWDEAf+nMFLd6-^WE~f9Y7ms&C zG>Rw+cT*I~?|Dphcms6RDN256^VoW(ft;6yKq!9*Vw`$-@jh$SANz@GsU2@-=O zhENO|4^hU9VHDZ(y(V*7$s>_IWfH8A>{{l|Mj_;o>63YL(VR`UC}@*zZk$~hk5JQb zX2p81kbhcy-LLN=+N09h}>>ok#^s0$1zTYs_NMesM>X8a(kqRbZjFN(8uP?FO zd$#n}7{kIKR!*C9({nS+iLdbQ*kF>}OJ8H0gn7!ns$)FHa-ZqAt}zjm;0%(q0_0$W zXg^1PAZ4o{b58|CKJ^MQUR&W@QcXu9*}dfQ(9o;Sw;Hy#JDQpN5tFsRf=Ps9k-)WB zUH~(NFrOlU32A7xCOq);ws63udlkkFC*~U9KSg{eT6_rs(lbOli4rNxG&4!$LAURN z0rvB#XBl8q;C_urhf&UwKvD>D6eY+GX!D)cjh*lU(d;PEeyh5{Dt#06v7z5h%T&5drK5N9P80p$1$v0NkgDoGRQwYR9G*0i zbJ+4%U-$;NnXBj~A}B5S*_=rfao_31@9?$kpg1s)c!{T8>q!#hr9`dq9g6pnya19! zr~{1evCx;pBx{_=b-=hU8xtqCeWNx>^qZb!z!0%uyh1T?p1C#adttoB*3t8K+|!ij zqXZza<_qHu)=!=nZck~}FN`0sy)&#njhcqf_t+`XS4w(b7(ZgwI=c6N5q)}XHHdza z_&Z%)3=>5(>t+0es*90?LXO$YLDrrOE(i$oAXtA24tje3>>g+T_FtCnaTaF3i$nha D!I -using System; -using System.Reflection; -[assembly: global::System.Runtime.Versioning.TargetFrameworkAttribute(".NETFramework,Version=v4.7.2", FrameworkDisplayName = ".NET Framework 4.7.2")] diff --git a/obj/Release/AuroraLabelItemsPlugin.csproj.CoreCompileInputs.cache b/obj/Release/AuroraLabelItemsPlugin.csproj.CoreCompileInputs.cache deleted file mode 100644 index c334cad..0000000 --- a/obj/Release/AuroraLabelItemsPlugin.csproj.CoreCompileInputs.cache +++ /dev/null @@ -1 +0,0 @@ -f2a688439a5d3dd2097dce27da2f5686a482960d diff --git a/obj/Release/AuroraLabelItemsPlugin.csproj.FileListAbsolute.txt b/obj/Release/AuroraLabelItemsPlugin.csproj.FileListAbsolute.txt deleted file mode 100644 index 5328b12..0000000 --- a/obj/Release/AuroraLabelItemsPlugin.csproj.FileListAbsolute.txt +++ /dev/null @@ -1,12 +0,0 @@ -C:\Users\jakes\source\repos\AuroraLabelItemsPlugin\bin\Release\AuroraLabelItemsPlugin.dll -C:\Users\jakes\source\repos\AuroraLabelItemsPlugin\bin\Release\AuroraLabelItemsPlugin.pdb -C:\Users\jakes\source\repos\AuroraLabelItemsPlugin\obj\Release\AuroraLabelItemsPlugin.csproj.CoreCompileInputs.cache -C:\Users\jakes\source\repos\AuroraLabelItemsPlugin\obj\Release\AuroraLabelItemsPlugin.dll -C:\Users\jakes\source\repos\AuroraLabelItemsPlugin\obj\Release\AuroraLabelItemsPlugin.pdb -C:\Users\jakes\source\repos\AuroraLabelItemsPlugin\obj\Release\AuroraLabelItemsPlugin.csproj.AssemblyReference.cache -C:\Users\iBuyPower\source\repos\AuroraLabelItemsPlugin2\bin\Release\AuroraLabelItemsPlugin.dll -C:\Users\iBuyPower\source\repos\AuroraLabelItemsPlugin2\bin\Release\AuroraLabelItemsPlugin.pdb -C:\Users\iBuyPower\source\repos\AuroraLabelItemsPlugin2\obj\Release\AuroraLabelItemsPlugin.csproj.CoreCompileInputs.cache -C:\Users\iBuyPower\source\repos\AuroraLabelItemsPlugin2\obj\Release\AuroraLabelItemsPlugin.dll -C:\Users\iBuyPower\source\repos\AuroraLabelItemsPlugin2\obj\Release\AuroraLabelItemsPlugin.pdb -C:\Users\iBuyPower\source\repos\AuroraLabelItemsPlugin2\obj\Release\AuroraLabelItemsPlugin.csproj.AssemblyReference.cache diff --git a/obj/Release/AuroraLabelItemsPlugin.dll b/obj/Release/AuroraLabelItemsPlugin.dll deleted file mode 100644 index d97d583dd83b2e296a7173c9477a24e0ae74c5f8..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 10752 zcmeHNeRLdGb-y#SvtPE>*6Pc49D8j?j;xQ3EZL46C&8=Tm8^Irt+lcsiD5n39m|V% zch)nzwuP!3`9Pe|q_l3JB%I?O0!bTFph*gcq-}ZvAt?vQfs|5CO4BB!0ZvH@p`4yT zi__nIGrQWA6F9W}uN`^r+^=`vefQmW-vaTBc-xNQ5)3`dRV;~>E2OQEB; zvnu~vemW$xaHU~)l98iCKjc8Hyq1VogZJ=$qM?gJbvKyEd2-QK_3+`c?WAOn_=ujAkN#R}i3WuuWcQ!6|(Th-xf0}j4)Z2u)! zkJP>hv#$DXJqyh7Tympxw{->D8yf+(ce}g4rz~6vR53OIx@^Zc15NjCv_g1xnpb0d zi(3SGkkPF`yIZ@_JCFJ22pmG+toF&R-Kqhn{ALPjU6?b!YIHK4V|qKVzM#V~s+=CF z16t_9Z&s?j?W%!E@vrJMb})aT#<%ISHCi>`g@3!!g>buD)MhpG5Pi|uy&uRQe(N*w z-B$v+_o~(__Pq>e9p=7!fe*#uH5jKaeB=1OM{FTC4d;e>Y>E5g-#@jx11guEj9B3= zAj}C{L#u50!%s!Nx$l0vW#@M<{d;)B(CY|;V&1{taR9Fq9sPq~atLkahq?E^7R-w^ z=FgbjjkeOou&eRql zvFFp%eo1ntdz&4>$z?%bl~<|p+^&TljBwp0Dc$F@@ePAcy4;3Tb}jZo+-c4)x2RcO z=CyV^oh{bXRHF|K&9h*Le5tj%ucp%49dPxo4!DdkG&g5&?eVF`H8#3hHBdwSL8WUa z9^1XDF<=XBUO!MB#D$unI`QUT_E+Wi*W|Fv%`eHWg+V;ieL-}(3)nVH4AGP3{ykSa z19-67sMF5KKBcusy=_f35ZzT%uD3Jwd3ZWSBw$SX9I26_W(C=O2?sebR1X1^G0fw#JTU{NC5$Lj0HA|t# zv5HhK0RJoH3Lz8q3s&u{UA?k!HLWOIEv}9hRTNCc{35sFdeOIA5vA6y6K6Rr=1W!K zbuS89k{#vi-T*!HZvb`-R1qXp*Zr`xy;<$uYDIx{ZeF_>6VEk^aemr*izC3h9gQ`P z#@fp@npH36GL5>h<*m(`qD}~FtSJhJ=(k>g0%G$-0TIe>ENq)6%7Nguc6;3EW>?yG z6g!U)HoN*f=4K4JM>Tu!u-$IOyl${YF@pD<$HR_0&gWU&Q5V8Pu0wt({|^i$^D4$y8hc|o^_zRcWT)--X{0+a1J zTG)$Ro3rhkvv#8(NVo!DWI|Qsb6d0Adv)mP3meb++gJ6p${r&DU));g9*Lw|{GN_? zt@6mmICujuySq0zquC^jJ-mB3b<;5PV97rFoZ1!c4-fVa?!=nptj+`WdWg2&MszQp z5BPwm%4V)OXR*fh@NWn^z_!CFDkE_4pSF!29z&YY2SDesu(l27jagR41y$*tn?K?6 z0ij<=gM`Bg_l`9$j%GMm5Sr0C+zM{^EzV@sdqp0`J|VD@WXJdR4$@1uVFjvqQjP0e?&I4=H~F3)cwvu;6@DdD-Qr$K^Lv zKW%fjxdZfW*8^z#BQJA$!12?NfM+~y;G??x{B&4;!Rx0#RT*AGFL+PTLvYfd&%td! z-7mf1JxvQJAAb6_$``=Hr>>uzM%%`7TBqw3SLk1Ro*qocmB%YM3BP~VphdcGsCrY9WgD5xfS(rI_Q z=bz*Nz2>yrsJ7!xWcha6msixE$w7MhYNpQ79-kWvje_%eK$*^i zqX>?R&HAdumi}54UgXEI}%0;xj4tf1Ny(sOV*GZE{flo^ee+kX|rDxvHTd|I{Gufjr0}35WNm~6$P!-9-qv4nWIpdc)vH5#-BEDS zqnm$p&gTCe@_nV=18BLDXV+F2Rsyc;Z_K3Av7A-PYxB{(W?2IR>3+I?vN#f(I$X+X zW&Ot4G&p0$^56iC#F7IPHHw*vY3jvtESD+gjG|`FA041b&a_HeMu%3Vm^nH~*N+?7 zN?yN_u1}h|Q?N8vDCPA6+G*S>rkAx`-nx+{jB+#J;Kl!y$+6X~((_;@-M zjnJUQj?W>VuAU~!6{ zb$vx6i9~8_bfUhW=;Zi#dMr9QK^8(WW+mg(lQb1e(x_g>Y}Bhx#bK-7-gsmp4IU+R z^O#{4v|>h&X=P3LHHu@AmY*yMM#0J$W5A zt>o&cm_A#Xo73RivIZK@@MHYzesFjIP7|+1z1N0Ntc;rfe`2kGN))XSp~=jl5AY z>76JT^|T%25yM2<3I%(zBdM5}-Ug;!N9*}^YexxF7RzykL^P`H?4*t5w7H^zN|mvy zVW{S@h^0|V>E@|iM!!tV;o%}yliS4#Y0u%aNFa7jptM?o>yM z4vde9vS?9hwkXyX`qE1yc@1yocHnG$Mb<5+Z~PR@Mog&lQpKu7sk2D0#n(wY_+%7M z*)^>;oN4_05}wlMux?D06B8Q-f@E8Y9!JebBaXh!L49WpLIPve^8hXpO&|sgV$b&K^;IVL*SCd|-UyGK~m$6Oc>` zoeB6r>lc)js1@FE3}Ql){S$p7 ziuLgs6|p)jWGO@_E^Lyru}4y#*&!((*(NFY0;YVwQ|gGo#}HzaZMaD}137+DQ2Izx z&To;FdvGHTo_@Sf;G4c@Sm@K{#-5|_D}lchJR3#-E9EJ8lEmmnpc8=xUD?=v9NY=W z?by+(5Pai5#J7eIB5it3U)Xc|snp~he_N0qy5s)u;@hAkd6f`JDv;)8CIbv)rh^f$ z$0Y~X22VCYCEy~-8*sM;-z^7ZZ%CF~Xl;w+3Q_PRq+S)s(tR#>aOon0&-h4g!UO-j zZNa6_D*+icWohHOmXOjSwNQ&B*o?GDvRhV3mIDFV9q@YGvh4LX`8*^Cm!1v;U|n{( zo0pzd+`*gOthSb2ZW29yTXr|W;XnZG1Ay$s?f7y4$ZcM5d8A+gg9#R7#UshWxQvU1 zuh@f8+#y9$Rn_H@eO}m7yxuRo@5s#hT`ztx)EMT=6MSoo?>AhBenivnKB`Tc(re`K7N+uvzwCA_fJ4iVGGP2;pBK~Lsd zOjk(M{x%05vOf!VNEED{hC^Sv7zz#a51@eVkm#!2dv{*jKdWW>b`I>#^zG7Shx&$w zc4hmH?H(G`ckSudv^`k5t0nU6#0PTx;j^Yh8^aUv>Dt>suXBXG0Uyz?4G+NUKx<9t zyvp-?QY*I#)g&RIeN>`b8_suO=X}>2vUkniP}O{YcvpC6=gwW>!Ckut_x6UOl{~*~ z-B8pkIHl%$LrJ`rXUc8}L!SRz^k_Z#PZ$I(k^Ne%cPUHUJe%xDu)Lr}? zzy6v^#Zn*t(w!GiKX-BeL(hKs;9mrP`bjnzz3#|i3ul8Px#7xu(m1V~M=Wgn8U2W< zmkjI3ThGYA5o7kfNANy_!-oDgI^j}wmhOlwJ8?hbp=G)ryQfYM|0xA8wy}JET+0ggNAe6t>D)K zn!#R_28?4*($0nXPGt{-2rze;freA!R@;wdf{puIjE1|Bio60B-Cw~XM6 zX&xt)F)GqAoMiaAN_^9r7N?pb&L4SbmZ4`r$G#qRy$Yied@4gL2mah!So(_4vG-ht zyKp)}3}^#dN+`bu&PN6GU4#{!a>TW@PF6y{MViN$HKFII!1E4hRXvZvf`zXp>_@4= z&-&BZ^4VZrW10|imV|u+BduV*%5{&|Nr%WE&~4r D0qYKR diff --git a/obj/Release/AuroraLabelItemsPlugin.pdb b/obj/Release/AuroraLabelItemsPlugin.pdb deleted file mode 100644 index 3ab2de7b2bd28121d179a21051c7ab9899224cdf..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 26112 zcmeHP3vg7|c|I#E3gF5h41|Y`SAYNuX|=nOki^S+f~gV6NccgN!tUxyT3GEWcXyF+ z+{{i42~C=o@wj!}sWWsOH~3MH-OzDu<0)=viXAd_;-tk>(or)WH|}(TlW7_}C2qg( zJa(^ED~cCkW3$Kn`<=&s&VSB-{`0v1y>e$bWXIyM{)D@&rft%TzqitYwvvZxcBi_x2#w{ zw&(8W`_}F}`&V@>-}}xjov-}3pzNz#18;m<_0Qnd-P=O%rb+|6=kFBj%4Pz!2_RN1 zPKkNqP_S*OyV_mn@q4`0`1Ski{T_eas=9_yU&yyQ;P(ZC!Nx#cAkfzzT)ldA(ChPA zes6t~tQ^90pc6un`ur64*?nN0sXtqV?IOXNkgRzzaNzb7X8%gI^z(Y zHBpX|+)=(EDgm(`t$=|uz7oW?H>{og>>%PSr**K*0+~R|Fubpo|Kk{WX*uL&nUj~6 zWq4PfYkrZuPOEeBn)VBLaSiY}@4rBF&{LNT)PEsd8yevJuMw4H9IbKEJ9pAv~hE_|@C~9dw(2vIk7ks_q4?#5i69y zH7oAfWJN7I91=?$li-fuS4Dm&?xd7K&-z+xXXwjx!)iv+Pasm+t9dcS0ok+MB-kw=`KUHaXfay zlKH%AIO`_ty%lxmKm><^19Hr+lG~5>nA&+J3zq2gR7Y~x3HZdP(+5%X|m4*5vG9S&1%O8j{oxd%ZH88AoRgU&efL)jT6av{_!3W>Y z7@ld{u)_D|H7`ciSuM+)d2Aj>ZOL`Wm$Ib6b>rbNlxU5O<|S)`UfT!cE-pj`h3J5@ zv}BQyrNp#!w@abeO7Y+iKF-@1c)C!Zbqzn~hRtAp(st0_XUjRr$5vZ)KQHKh(k4v6 zK2_2@zMq@ySTfo-zN>lZ$E?Y3>PwGv-e*8=tC5Q}*&epl5vH|6-EhK&L9AzZ%^HEp zq;&(g15P4kqxtB^*vu?_0W$X>wu$Gil91_VXCO4VH8~Wt>>evLn3qn>ePA?)EZpNt z_8M6o@kDqCyA;-5K4UVvf0hRk!VA*qRlF2(;zka1ulA>Icw~mT0;OHvkN(|{x~yk- zjqXu3t^4f#$ytW|iCb5CAId6|dl%c}KIAO3qr*O2e`P)HMOkHa$in@{U55N|W#M=S zETNUwoA+Ar=(REj2Fjq9jEvuaWEJdDs0Lkh`9hI!Ut(=PmHbVdD`eYYCV8Wo~RK9?LuK6%LdB#?pK zJ0N2McO{X6j(Mj^Edl=g-217e!1YM`bei{_W~4U&TY!DQR^UNk8}JF>MqnwPyvoET zq-d80xUiVIXZBCXkv7#8!}63&duZ+5$`h zyMgqx20r()&XMhhQ{V%{rkp55LH;^tu-;SW~ zi-C_LT@L&f%KgBnk*)*2fOH4&6{PP5eh2A6;3=f{0KW%30Q^4iLE!7aBfuYm?>XQ< zBYgt+Cel9u{wvbI0**oMO&IvwNH+t2hV%gNS4dMKzXpB@_#5Ou3H+2x9C!(MgG;1- z44ml_5BwT97wJ+_37y|8O2t;tS3uiAHJ~-1CK-o{Feje@tq=>uBJ4NIG>(i*bKVr+ zT^gC*2V%NK^KR0(M`J|eeZUG`kFvg?F zRZXl1?<~Y`1F|p8KVAb&i%;?Qs=iT?cZR3s56GmsEe&o z+#%b@=#=%;S)9AxHeIhv)?1dIi(U*;otLiknY##Wflr1W@N+CXfZQMM0&j#GQ$Bz^@d(m?2z(rfxcCc~jba4;bC2a+51N}CrbAtaZ1^z}*7ibW40Q6^|6Clp< zjDQY+z6m-G8UyhRabtjupk7b{^bqK2&`Ho)5I30lpej&1=pN88=n$w7rcML=1E_`5 zYkt8wI|RKSMAL|hKSG@Ns7}A4@$YqhxlX?aCi49r=7rdy@lIX-InCdsaY*x%mvpb@ zr{jQWtYL{i(fsdeK9}ZuS(n#qtk(HWnh$%1tp9nP&wUD6;@@=sUz+}F?9};hYQCh- zU!d!|icv5jq|!MoM->y?CgMa#`8a0sxQd&dtP|o6`Kbwo$l%x}3*5t1{b`f2=<-R6 zFR=jar@-paRkNA9SU{Vo@QVlR0%oV&V&)dE!<_xp%b}!BM}Cv`*ex4 z<00c1b;wjax^8_&<}`Vy%yJYu>Zx*F4;L)c*MzK><@9sZQ{}o|L#D4|vR-Zno*Ad& z(RCYn2T=3DJz}z8&W6d#3;7>^4IC<=oh#ePrdp zcy!%B#@>(0x>*iOM?F=p>jg7=&Kw*!E|GCQ8aXOo^M^8hq@U2SmNQO7hb+aT>-Gt} zYgFsw7#=iTLOIfm9F?betqkvcIEq|CIm8UF%G134nK9h2d6oApqbrrK_@#sK3Y!?$ z_{emhi$_eESo{aG#k(VXe*GCT#z0kwH?vR&K3^}8@t>d2S@>F9#n={OCarR3i7||o zp-axUiksiupA>p>XA56jTdl9Qfd?>xk&|2QO!}Z?;92b$g3QY;U=q2WbsIvvcD0A` zbz)$DTLfRf`Th9#p`*6Gp`)c0r;Q31@6U93PcXdMSn1}g=y1fc`I(-(QZ%mKSnu~X z@LtPs@wRVBU%lpo7suteu&zB29f*XZ1MRU;atQCfZZQ_fY0me_XV2jH;9Ift?e!Tc0M~+zv%ge(IK{s34vwIe{w>J(*3i@H}#z? z%zF-mBWXfl**hTTdrQN_GWw*-O@;$mMqd+kksVk@-%>?(0n#j^KPX#&WMvusKjlnh z1(wl&gKcI)U>SWhlayZ zOJ#-&wx+C&e+xKGE5qawi>0;EXI2Eguu_qD4ZkFY5m3J0tzPC=y7`K|$mg>8HaW=- zgHMUgH`iL-QfKmq%2i>8oCFomlwX0^LmsvFvoA)tK|X`jYzasAa!V35J)LcMw`hr) zC_Vv-i<-C{su{EbeU=@>*Bg6PMnAT&cui=^zxtNaF0b*+{1ST#dT^01sJSNjUWxN? z1b2G|p2KFXVw(^%P>A=Uc$QN836E9o4~IZ}K3xT(Kb+z0o$!8NLYM=dmE;FE_u$7M z$hjBahxLC3`M45EzCoZNH{!=Z$7bVs7tc$)D;xo`&lMm>94*C#655^$PJ>Oy&O~sm#%^3 zm(E(?`~+&C@csWMa8f_Oka*S?{QvSjzdU;j{{IhPJZaWxa8x6~173$_jgDujoc9q& zxv84fLRNO}$H)mxnT%8>`v1h-7b)lcg!d2LW9WXMPvLe@4`??i0vZJ!038M$1swyO z0G$T$4)qr3UC;&4)#Cr>`Y-r@%%8Ged;TBZ!zT;oY?!RPkpJ=5K*9f)nL{2>1^-`u z{y(F|?TEYzntHEUzAavT9>uH8|M%6G$KIsvANjjOPmKKFiRPoxfG4~ahr#tkYU%XVlb&LZo(vDt8U>+bFW z4&t-)6IA_(?acYXGqkFFQvUE+9xwZt-^|?X-EW6jJQj=njTimWb-xdVv%_sEl&ETR zkE?*WMIAU?m>a_Lguj*DOsDohDlYuB*(EbWpLA*?aCIPI&4)ls=B88mpyG1-7ig5k z5%_DB%zSmRx>TK=brv&ho(&S@@+Xkq1l)B9Z_C#pMg3RF>UEH2fyphu9%%Il7e8XI zD^9>!R|>p}+t@tS;FDEq6lZS;zshSl?!u(ae1|(sLwhFms+nrwx;e=_I1%!wJyc>9 z9Gkc@mJ_an{ywG75|cI1on^(KqCoGW67`(dd?6tVRfeJ1@|8yWF05-Res%Yxrn=_T zhx~RGPj2*IUX^muPo=M!ndK5}EhGmuR(CX$MPSlC%rkwc#%k9(M(R>jF+$|kxP%&4 zS~e~gB+xMp6vAm#bU7H8P$sVp?FgSAfqZs*cb2QV%NhiDePJunW||B0QrMuBkn3nY z*XR?bTx$t9g}~R`gVvJknwn8kQ-Oj4R6&A|s&Z0zsPqGBdLY}qVOWelqu(%Mv3`_& z@p#<8FUnZoAA`k)(%@lw;{CNXC7k&)_#nA$Zey_C&+hNvF$H(T9&-c8GcMoHb*2`z zIP?NW@ zYQ0m)KP~~pOkZP?gn7b!&oLfid%$#D*O&@ha0*Gf2NYt1 zh(E`OAZe>1cTa^>KJ@}IUZS%tT9;~t66x-xpmz+t8h)#3>%~NKqj<<@hWL*W--#AqLWuMPk&dH8$}-JN5=GD# zC&Cc>Y1CeZ*p#?mBho>XUJ^(OK@Ot?*#&LB)w;P8o*|kYCE9PE8{VaFqIQdbwz>a% zi1sa_O>M4P$4sk+vMSuCChi&&A3Fo|)bDYX9#`q=sl3}%KYW26U^T>3g9nO#grS4u zW_b=r{u=1K0d7_+dZh>|On$Oz5=Gv3`{sA~V76Z#8cICJr(XL?66d8-t??a-cagjR zl0>OPjPJ2Aki#--oalAPxi1?NC%%27H%SDXu4Kp%v0=PGF?F_aYu)$Uc!{IqXK%T$ zsnSO!K;q5k#w+ZfJ}cc`)NGs^Kj3(Gczqf*jh+?Q3DH+7d!8FVl5!01|DyWz+G Date: Mon, 12 Feb 2024 22:07:58 -0500 Subject: [PATCH 39/76] Extract color/strip key constants --- AuroraLabelItemsPlugin.cs | 84 +++++++++++--------------------- AuroraLabelItemsPlugin.csproj | 1 + AuroraStripItemPlugin.cs | 90 +++++++++-------------------------- Constants.cs | 85 +++++++++++++++++++++++++++++++++ 4 files changed, 136 insertions(+), 124 deletions(-) create mode 100644 Constants.cs diff --git a/AuroraLabelItemsPlugin.cs b/AuroraLabelItemsPlugin.cs index 2c28aae..c5428ed 100644 --- a/AuroraLabelItemsPlugin.cs +++ b/AuroraLabelItemsPlugin.cs @@ -19,36 +19,6 @@ namespace AuroraLabelItemsPlugin [Export(typeof(IPlugin))] public class AuroraLabelItemsPlugin : ILabelPlugin { - /// The name of the custom label item we've added to Labels - /// in the Profile - private const string LABEL_ITEM_SELECT_HORI = "SELECT_HORI"; - - private const string LABEL_ITEM_SELECT_VERT = "SELECT_VERT"; - private const string LABEL_ITEM_COMM_ICON = "AURORA_COMM_ICON"; //field a(2) - private const string LABEL_ITEM_ADSB_CPDLC = "AURORA_ADSB_CPDLC"; //field c(4) - private const string LABEL_ITEM_ADS_FLAGS = "AURORA_ADS_FLAGS"; //field c(4) - private const string LABEL_ITEM_MNT_FLAGS = "AURORA_MNT_FLAGS"; //field c(4) - private const string LABEL_ITEM_SCC = "AURORA_SCC"; //field d(5) - private const string LABEL_ITEM_ANNOT_IND = "AURORA_ANNOT_IND"; //field e(1) - private const string LABEL_ITEM_RESTR = "AURORA_RESTR"; //field f(1) - private const string LABEL_ITEM_LEVEL = "AURORA_LEVEL"; //field g(3) - private const string LABEL_ITEM_VMI = "AURORA_VMI"; //field h(1) - private const string LABEL_ITEM_CLEARED_LEVEL = "AURORA_CLEARED_LEVEL"; //field i(7) - private const string LABEL_ITEM_HANDOFF_IND = "AURORA_HO_IND"; //field j(4) - private const string LABEL_ITEM_RADAR_IND = "AURORA_RADAR_IND"; //field k(1) - private const string LABEL_ITEM_INHIBIT_IND = "AURORA_INHIBIT_IND"; //field l(1) - private const string LABEL_ITEM_FILED_SPEED = "AURORA_FILEDSPEED"; //field m(4) - private const string LABEL_ITEM_3DIGIT_GROUNDSPEED = "AURORA_GROUNDSPEED"; //field n(5) - private const string LABEL_ITEM_DESTINATION = "AURORA_DESTINATION"; //field o(4) - private static readonly CustomColour EastboundColour = new CustomColour(240, 255, 255); - private static readonly CustomColour WestboundColour = new CustomColour(240, 231, 140); - private static readonly CustomColour NonRVSM = new CustomColour(242, 133, 0); - private static readonly CustomColour Probe = new CustomColour(0, 255, 0); - private static readonly CustomColour NotCDA = new CustomColour(100, 0, 100); - private static readonly CustomColour Advisory = new CustomColour(255, 165, 0); - private static readonly CustomColour Imminent = new CustomColour(255, 0, 0); - private static readonly CustomColour SpecialConditionCode = new CustomColour(255, 255, 0); - private static readonly CustomColour ApsBlue = new CustomColour(141, 182, 205); private readonly ConcurrentDictionary adsbcpdlcValues = new ConcurrentDictionary(); private readonly ConcurrentDictionary adsflagValues = new ConcurrentDictionary(); @@ -277,13 +247,13 @@ public CustomLabelItem GetCustomLabelItem(string itemType, Track track, FDR flig var notProbe = flightDataRecord.State == (FDR.FDRStates.STATE_PREACTIVE | FDR.FDRStates.STATE_COORDINATED) ? BorderFlags.All : BorderFlags.None; - var colour = !flightDataRecord.RVSM ? NonRVSM : ExcludeConflictColor(track, flightDataRecord); + var colour = !flightDataRecord.RVSM ? CustomColors.NonRVSM : ExcludeConflictColor(track, flightDataRecord); var excludeConflict = SelectASDTrackColour(track) == GetConflictColour(flightDataRecord.Callsign); switch (itemType) { - case LABEL_ITEM_SELECT_HORI: + case LabelConstants.LABEL_ITEM_SELECT_HORI: if (MMI.SelectedTrack?.GetFDR()?.Callsign == track.GetFDR().Callsign) return new CustomLabelItem @@ -294,7 +264,7 @@ public CustomLabelItem GetCustomLabelItem(string itemType, Track track, FDR flig return null; - case LABEL_ITEM_SELECT_VERT: + case LabelConstants.LABEL_ITEM_SELECT_VERT: if (MMI.SelectedTrack?.GetFDR()?.Callsign == track.GetFDR().Callsign) return new CustomLabelItem @@ -305,7 +275,7 @@ public CustomLabelItem GetCustomLabelItem(string itemType, Track track, FDR flig return null; - case LABEL_ITEM_COMM_ICON: + case LabelConstants.LABEL_ITEM_COMM_ICON: if (downLink) return new CustomLabelItem @@ -321,7 +291,7 @@ public CustomLabelItem GetCustomLabelItem(string itemType, Track track, FDR flig ForeColourIdentity = excludeConflict ? Colours.Identities.Custom : default, CustomForeColour = ExcludeConflictColor(track, flightDataRecord) }; - case LABEL_ITEM_ADSB_CPDLC: + case LabelConstants.LABEL_ITEM_ADSB_CPDLC: var useCustomForeColour = flightDataRecord.State == (FDR.FDRStates.STATE_PREACTIVE | FDR.FDRStates.STATE_COORDINATED); @@ -330,7 +300,7 @@ public CustomLabelItem GetCustomLabelItem(string itemType, Track track, FDR flig return new CustomLabelItem { ForeColourIdentity = Colours.Identities.Custom, - CustomForeColour = NotCDA, + CustomForeColour = CustomColors.NotCDA, Text = c1.ToString() }; return new CustomLabelItem @@ -340,7 +310,7 @@ public CustomLabelItem GetCustomLabelItem(string itemType, Track track, FDR flig CustomForeColour = ExcludeConflictColor(track, flightDataRecord) }; - case LABEL_ITEM_ADS_FLAGS: + case LabelConstants.LABEL_ITEM_ADS_FLAGS: return new CustomLabelItem { @@ -350,7 +320,7 @@ public CustomLabelItem GetCustomLabelItem(string itemType, Track track, FDR flig }; - case LABEL_ITEM_MNT_FLAGS: + case LabelConstants.LABEL_ITEM_MNT_FLAGS: if (mntflagToggled) return new CustomLabelItem @@ -366,19 +336,19 @@ public CustomLabelItem GetCustomLabelItem(string itemType, Track track, FDR flig }; - case LABEL_ITEM_SCC: + case LabelConstants.LABEL_ITEM_SCC: { return new CustomLabelItem { Text = d1, ForeColourIdentity = Colours.Identities.Custom, - CustomForeColour = SpecialConditionCode + CustomForeColour = CustomColors.SpecialConditionCode }; } - case LABEL_ITEM_ANNOT_IND: + case LabelConstants.LABEL_ITEM_ANNOT_IND: var scratch = string.IsNullOrEmpty(flightDataRecord.LabelOpData); if (scratch) @@ -396,7 +366,7 @@ public CustomLabelItem GetCustomLabelItem(string itemType, Track track, FDR flig CustomForeColour = ExcludeConflictColor(track, flightDataRecord) }; - case LABEL_ITEM_RESTR: + case LabelConstants.LABEL_ITEM_RESTR: if (flightDataRecord.LabelOpData.Contains("AT ") || flightDataRecord.LabelOpData.Contains(" BY ") || flightDataRecord.LabelOpData.Contains("CLEARED TO ")) @@ -410,7 +380,7 @@ public CustomLabelItem GetCustomLabelItem(string itemType, Track track, FDR flig return null; - case LABEL_ITEM_LEVEL: + case LabelConstants.LABEL_ITEM_LEVEL: var level = prl == -1 ? null : (radarTrack.CorrectedAltitude / 100).ToString(); @@ -420,12 +390,12 @@ public CustomLabelItem GetCustomLabelItem(string itemType, Track track, FDR flig Text = level, Border = notProbe, BorderColourIdentity = Colours.Identities.Custom, - CustomBorderColour = NotCDA, + CustomBorderColour = CustomColors.NotCDA, ForeColourIdentity = excludeConflict ? Colours.Identities.Custom : default, CustomForeColour = colour }; - case LABEL_ITEM_VMI: + case LabelConstants.LABEL_ITEM_VMI: return new CustomLabelItem { @@ -435,7 +405,7 @@ public CustomLabelItem GetCustomLabelItem(string itemType, Track track, FDR flig }; - case LABEL_ITEM_CLEARED_LEVEL: + case LabelConstants.LABEL_ITEM_CLEARED_LEVEL: if (radarTrack.ReachedCFL || prl == alt || Math.Abs(flightDataRecord.PRL - alt) < 300) @@ -449,7 +419,7 @@ public CustomLabelItem GetCustomLabelItem(string itemType, Track track, FDR flig Text = alt.ToString(), Border = notProbe, BorderColourIdentity = Colours.Identities.Custom, - CustomBorderColour = NotCDA, + CustomBorderColour = CustomColors.NotCDA, ForeColourIdentity = excludeConflict ? Colours.Identities.Custom : default, CustomForeColour = colour }; @@ -481,7 +451,7 @@ public CustomLabelItem GetCustomLabelItem(string itemType, Track track, FDR flig // }; // } - case LABEL_ITEM_RADAR_IND: + case LabelConstants.LABEL_ITEM_RADAR_IND: if (radarToggled) @@ -501,7 +471,7 @@ public CustomLabelItem GetCustomLabelItem(string itemType, Track track, FDR flig CustomForeColour = ExcludeConflictColor(track, flightDataRecord) }; - case LABEL_ITEM_INHIBIT_IND: + case LabelConstants.LABEL_ITEM_INHIBIT_IND: if (flightDataRecord.State == FDR.FDRStates.STATE_INHIBITED) @@ -518,7 +488,7 @@ public CustomLabelItem GetCustomLabelItem(string itemType, Track track, FDR flig }; - case LABEL_ITEM_FILED_SPEED: + case LabelConstants.LABEL_ITEM_FILED_SPEED: var mach = Conversions.CalculateMach(flightDataRecord.TAS, GRIB.FindTemperature(flightDataRecord.PRL, track.GetLocation(), true)); return new CustomLabelItem @@ -529,7 +499,7 @@ public CustomLabelItem GetCustomLabelItem(string itemType, Track track, FDR flig CustomForeColour = ExcludeConflictColor(track, flightDataRecord) }; - case LABEL_ITEM_3DIGIT_GROUNDSPEED: + case LabelConstants.LABEL_ITEM_3DIGIT_GROUNDSPEED: //get groundspeed value from either FDR or radarTrack if coupled var gs = radarTrack == null ? flightDataRecord.PredictedPosition.Groundspeed @@ -541,7 +511,7 @@ public CustomLabelItem GetCustomLabelItem(string itemType, Track track, FDR flig CustomForeColour = ExcludeConflictColor(track, flightDataRecord) }; - case LABEL_ITEM_DESTINATION: + case LabelConstants.LABEL_ITEM_DESTINATION: return new CustomLabelItem { @@ -661,8 +631,8 @@ private CustomColour GetDirectionColour(string callsign, FDR fdr) if (eastboundCallsigns.TryGetValue(callsign, out var east)) { if (east) - return EastboundColour; - return WestboundColour; + return CustomColors.EastboundColour; + return CustomColors.WestboundColour; } return default; @@ -671,8 +641,8 @@ private CustomColour GetDirectionColour(string callsign, FDR fdr) private CustomColour GetConflictColour(string callsign) { if (imminentConflict.Count % 2 == 0 && imminentConflict.TryGetValue(callsign, out _)) - return Imminent; - if (advisoryConflict.Count % 2 == 0 && advisoryConflict.TryGetValue(callsign, out _)) return Advisory; + return CustomColors.Imminent; + if (advisoryConflict.Count % 2 == 0 && advisoryConflict.TryGetValue(callsign, out _)) return CustomColors.Advisory; return default; } @@ -681,7 +651,7 @@ private CustomColour ExcludeConflictColor(Track track, FDR flightDataRecord) { if ((imminentConflict.Count > 0 || advisoryConflict.Count > 0) && track.State == MMI.HMIStates.Jurisdiction) return GetDirectionColour(flightDataRecord.Callsign, flightDataRecord); - if (imminentConflict.Count > 0 || advisoryConflict.Count > 0) return ApsBlue; + if (imminentConflict.Count > 0 || advisoryConflict.Count > 0) return CustomColors.ApsBlue; return default; } } diff --git a/AuroraLabelItemsPlugin.csproj b/AuroraLabelItemsPlugin.csproj index 5b60907..99e2f8e 100644 --- a/AuroraLabelItemsPlugin.csproj +++ b/AuroraLabelItemsPlugin.csproj @@ -50,6 +50,7 @@ + diff --git a/AuroraStripItemPlugin.cs b/AuroraStripItemPlugin.cs index 06eff03..28e44f7 100644 --- a/AuroraStripItemPlugin.cs +++ b/AuroraStripItemPlugin.cs @@ -2,6 +2,7 @@ using System.Collections.Concurrent; using System.ComponentModel.Composition; using System.Text.RegularExpressions; +using AuroraLabelItemsPlugin; using vatsys; using vatsys.Plugin; using static vatsys.FDP2; @@ -11,51 +12,6 @@ namespace AuroraStripItemsPlugin [Export(typeof(IPlugin))] public class AuroraStripItemsPlugin : IStripPlugin { - /// The name of the custom label item we've added to Labels - /// in the Profile - private const string LABEL_ITEM_ADSB_CPDLC = "AURORA_ADSB_CPDLC"; //field c(4) - - private const string STRIP_ITEM_CALLSIGN = "AURORA_CALLSIGN"; - private const string STRIP_ITEM_CTLSECTOR = "AURORA_CDA"; - private const string STRIP_ITEM_NXTSECTOR = "AURORA_NDA"; - private const string STRIP_ITEM_T10_FLAG = "AURORA_T10_FLAG"; - private const string STRIP_ITEM_MNT_FLAG = "AURORA_MNT_FLAG"; - private const string STRIP_ITEM_DIST_FLAG = "AURORA_DIST_FLAG"; - private const string STRIP_ITEM_RVSM_FLAG = "AURORA_RVSM_FLAG"; - private const string STRIP_ITEM_VMI = "AURORA_STRIP_VMI"; - private const string STRIP_ITEM_COMPLEX = "AURORA_STRIP_COMPLEX"; - private const string STRIP_ITEM_CLEARED_LEVEL = "AURORA_CLEARED_LEVEL"; - private const string STRIP_ITEM_REQUESTED_LEVEL = "AURORA_REQUESTED_LEVEL"; - private const string STRIP_ITEM_MAN_EST = "AURORA_MAN_EST"; - private const string STRIP_ITEM_POINT = "AURORA_POINT"; - private const string STRIP_ITEM_ROUTE = "AURORA_ROUTE_STRIP"; - private const string STRIP_ITEM_RADAR_IND = "AURORA_RADAR_IND"; - private const string STRIP_ITEM_ANNOT_IND = "AURORA_ANNOT_STRIP"; - private const string STRIP_ITEM_LATERAL_FLAG = "AURORA_LATERAL_FLAG"; - private const string STRIP_ITEM_RESTR = "AURORA_RESTR_STRIP"; - private const string STRIP_ITEM_CLRD_RTE = "AURORA_CLRD_RTE"; - private const string CPAR_ITEM_TYPE = "CPAR_TYP"; - private const string CPAR_ITEM_REQUIRED = "CPAR_REQUIRED"; - private const string CPAR_ITEM_INTRUDER = "CPAR_INT"; - private const string CPAR_ITEM_LOS = "CPAR_LOS"; - private const string CPAR_ITEM_ACTUAL = "CPAR_ACTUAL"; - private const string CPAR_ITEM_PASSING = "CPAR_PASSING"; - private const string CPAR_ITEM_CONF_SEG_START_1 = "CPAR_CONF_SEG_START_1"; - private const string CPAR_ITEM_CONF_SEG_START_2 = "CPAR_CONF_SEG_START_2"; - private const string CPAR_ITEM_CONF_SEG_END_1 = "CPAR_CONF_SEG_END_1"; - private const string CPAR_ITEM_CONF_SEG_END_2 = "CPAR_CONF_SEG_END_2"; - private const string CPAR_ITEM_STARTIME_1 = "CPAR_START_TIME_1"; - private const string CPAR_ITEM_STARTIME_2 = "CPAR_START_TIME_2"; - private const string CPAR_ITEM_ENDTIME_1 = "CPAR_END_TIME_1"; - private const string CPAR_ITEM_ENDTIME_2 = "CPAR_END_TIME_2"; - private const string CPAR_ITEM_AID_2 = "CPAR_AID_2"; - private const string CPAR_ITEM_TYP_2 = "CPAR_TYP_2"; - private const string CPAR_ITEM_SPD_2 = "CPAR_SPD_2"; - private const string CPAR_ITEM_ALT_2 = "CPAR_ALT_2"; - private static readonly CustomColour NonRVSM = new CustomColour(242, 133, 0); - private static readonly CustomColour SepFlags = new CustomColour(0, 196, 253); - private static readonly CustomColour Pending = new CustomColour(46, 139, 87); - private static readonly CustomColour NotCDA = new CustomColour(100, 0, 100); private readonly ConcurrentDictionary eastboundCallsigns = new ConcurrentDictionary(); @@ -121,7 +77,7 @@ public CustomStripItem GetCustomStripItem(string itemType, Track track, FDR flig switch (itemType) { - case STRIP_ITEM_CALLSIGN: + case StripConstants.STRIP_ITEM_CALLSIGN: if (isEastBound) @@ -138,7 +94,7 @@ public CustomStripItem GetCustomStripItem(string itemType, Track track, FDR flig Text = flightDataRecord.Callsign }; - case STRIP_ITEM_CTLSECTOR: + case StripConstants.STRIP_ITEM_CTLSECTOR: var pendingCoordination = flightDataRecord.State == (FDR.FDRStates.STATE_PREACTIVE | FDR.FDRStates.STATE_COORDINATED); @@ -150,13 +106,13 @@ public CustomStripItem GetCustomStripItem(string itemType, Track track, FDR flig return new CustomStripItem { ForeColourIdentity = pendingCoordination ? Colours.Identities.Custom : default, - CustomForeColour = Pending, + CustomForeColour = CustomColors.Pending, Text = sectorName }; } - case STRIP_ITEM_NXTSECTOR: + case StripConstants.STRIP_ITEM_NXTSECTOR: TOC toc; toc = new TOC(flightDataRecord); @@ -167,13 +123,13 @@ public CustomStripItem GetCustomStripItem(string itemType, Track track, FDR flig return new CustomStripItem { ForeColourIdentity = Colours.Identities.Custom, - CustomForeColour = Pending, + CustomForeColour = CustomColors.Pending, Text = firName }; } - case LABEL_ITEM_ADSB_CPDLC: + case StripConstants.LABEL_ITEM_ADSB_CPDLC: if (!isEastBound && !adsb && cpdlc) @@ -232,7 +188,7 @@ public CustomStripItem GetCustomStripItem(string itemType, Track track, FDR flig return null; - case STRIP_ITEM_T10_FLAG: + case StripConstants.STRIP_ITEM_T10_FLAG: if (flightDataRecord.PerformanceData?.IsJet ?? false) @@ -246,7 +202,7 @@ public CustomStripItem GetCustomStripItem(string itemType, Track track, FDR flig return null; - case STRIP_ITEM_MNT_FLAG: + case StripConstants.STRIP_ITEM_MNT_FLAG: if (flightDataRecord.PerformanceData?.IsJet ?? false) @@ -259,7 +215,7 @@ public CustomStripItem GetCustomStripItem(string itemType, Track track, FDR flig return null; - case STRIP_ITEM_DIST_FLAG: + case StripConstants.STRIP_ITEM_DIST_FLAG: if (adsc & cpdlc & (rnp4 || rnp10)) @@ -267,25 +223,25 @@ public CustomStripItem GetCustomStripItem(string itemType, Track track, FDR flig return new CustomStripItem { BackColourIdentity = Colours.Identities.Custom, - CustomBackColour = SepFlags, + CustomBackColour = CustomColors.SepFlags, Text = rnp4 ? "3" : "D" }; return null; - case STRIP_ITEM_RVSM_FLAG: + case StripConstants.STRIP_ITEM_RVSM_FLAG: if (rvsm) return new CustomStripItem { BackColourIdentity = Colours.Identities.Custom, - CustomBackColour = SepFlags, + CustomBackColour = CustomColors.SepFlags, Text = "W" }; return null; - case STRIP_ITEM_VMI: + case StripConstants.STRIP_ITEM_VMI: var vs = radarTrack == null ? flightDataRecord.PredictedPosition.VerticalSpeed : radarTrack.VerticalSpeed; @@ -312,7 +268,7 @@ public CustomStripItem GetCustomStripItem(string itemType, Track track, FDR flig return null; - case STRIP_ITEM_COMPLEX: + case StripConstants.STRIP_ITEM_COMPLEX: if (flightDataRecord.LabelOpData.Contains("AT ") || flightDataRecord.LabelOpData.Contains(" BY ") || flightDataRecord.LabelOpData.Contains("CLEARED TO ")) @@ -324,7 +280,7 @@ public CustomStripItem GetCustomStripItem(string itemType, Track track, FDR flig return null; - case STRIP_ITEM_CLEARED_LEVEL: + case StripConstants.STRIP_ITEM_CLEARED_LEVEL: if (cfl == 0) return new CustomStripItem @@ -337,7 +293,7 @@ public CustomStripItem GetCustomStripItem(string itemType, Track track, FDR flig Text = cfl.ToString() }; - case STRIP_ITEM_REQUESTED_LEVEL: + case StripConstants.STRIP_ITEM_REQUESTED_LEVEL: if (flightDataRecord.State == FDR.FDRStates.STATE_INACTIVE || flightDataRecord.State == FDR.FDRStates.STATE_INACTIVE) @@ -368,7 +324,7 @@ public CustomStripItem GetCustomStripItem(string itemType, Track track, FDR flig // { // Text = Conversions.ConvertToFlightplanLatLong() // }; - case STRIP_ITEM_ROUTE: + case StripConstants.STRIP_ITEM_ROUTE: return new CustomStripItem { @@ -377,7 +333,7 @@ public CustomStripItem GetCustomStripItem(string itemType, Track track, FDR flig }; - case STRIP_ITEM_RADAR_IND: + case StripConstants.STRIP_ITEM_RADAR_IND: return new CustomStripItem { @@ -386,7 +342,7 @@ public CustomStripItem GetCustomStripItem(string itemType, Track track, FDR flig }; - case STRIP_ITEM_ANNOT_IND: + case StripConstants.STRIP_ITEM_ANNOT_IND: var scratch = string.IsNullOrEmpty(flightDataRecord.LabelOpData); @@ -402,7 +358,7 @@ public CustomStripItem GetCustomStripItem(string itemType, Track track, FDR flig }; - case STRIP_ITEM_LATERAL_FLAG: + case StripConstants.STRIP_ITEM_LATERAL_FLAG: if (adsc & cpdlc & rnp4 || rnp10) @@ -410,13 +366,13 @@ public CustomStripItem GetCustomStripItem(string itemType, Track track, FDR flig return new CustomStripItem { BackColourIdentity = Colours.Identities.Custom, - CustomBackColour = SepFlags, + CustomBackColour = CustomColors.SepFlags, Text = rnp4 ? "4" : rnp10 ? "R" : "" //OnMouseClick = ItemMouseClick }; return null; - case STRIP_ITEM_RESTR: + case StripConstants.STRIP_ITEM_RESTR: if (flightDataRecord.LabelOpData.Contains("AT ") || flightDataRecord.LabelOpData.Contains(" BY ") || flightDataRecord.LabelOpData.Contains("CLEARED TO ")) diff --git a/Constants.cs b/Constants.cs new file mode 100644 index 0000000..8b21cfb --- /dev/null +++ b/Constants.cs @@ -0,0 +1,85 @@ +using vatsys.Plugin; + +namespace AuroraLabelItemsPlugin +{ + public static class CustomColors + { + public static readonly CustomColour NonRvsm = new CustomColour(242, 133, 0); + public static readonly CustomColour SepFlags = new CustomColour(0, 196, 253); + public static readonly CustomColour Pending = new CustomColour(46, 139, 87); + public static readonly CustomColour NotCda = new CustomColour(100, 0, 100); + public static readonly CustomColour EastboundColour = new CustomColour(240, 255, 255); + public static readonly CustomColour WestboundColour = new CustomColour(240, 231, 140); + public static readonly CustomColour NonRVSM = new CustomColour(242, 133, 0); + public static readonly CustomColour Probe = new CustomColour(0, 255, 0); + public static readonly CustomColour NotCDA = new CustomColour(100, 0, 100); + public static readonly CustomColour Advisory = new CustomColour(255, 165, 0); + public static readonly CustomColour Imminent = new CustomColour(255, 0, 0); + public static readonly CustomColour SpecialConditionCode = new CustomColour(255, 255, 0); + public static readonly CustomColour ApsBlue = new CustomColour(141, 182, 205); + } + + public static class StripConstants + { + public const string LABEL_ITEM_ADSB_CPDLC = "AURORA_ADSB_CPDLC"; //field c(4) + public const string STRIP_ITEM_CALLSIGN = "AURORA_CALLSIGN"; + public const string STRIP_ITEM_CTLSECTOR = "AURORA_CDA"; + public const string STRIP_ITEM_NXTSECTOR = "AURORA_NDA"; + public const string STRIP_ITEM_T10_FLAG = "AURORA_T10_FLAG"; + public const string STRIP_ITEM_MNT_FLAG = "AURORA_MNT_FLAG"; + public const string STRIP_ITEM_DIST_FLAG = "AURORA_DIST_FLAG"; + public const string STRIP_ITEM_RVSM_FLAG = "AURORA_RVSM_FLAG"; + public const string STRIP_ITEM_VMI = "AURORA_STRIP_VMI"; + public const string STRIP_ITEM_COMPLEX = "AURORA_STRIP_COMPLEX"; + public const string STRIP_ITEM_CLEARED_LEVEL = "AURORA_CLEARED_LEVEL"; + public const string STRIP_ITEM_REQUESTED_LEVEL = "AURORA_REQUESTED_LEVEL"; + public const string STRIP_ITEM_MAN_EST = "AURORA_MAN_EST"; + public const string STRIP_ITEM_POINT = "AURORA_POINT"; + public const string STRIP_ITEM_ROUTE = "AURORA_ROUTE_STRIP"; + public const string STRIP_ITEM_RADAR_IND = "AURORA_RADAR_IND"; + public const string STRIP_ITEM_ANNOT_IND = "AURORA_ANNOT_STRIP"; + public const string STRIP_ITEM_LATERAL_FLAG = "AURORA_LATERAL_FLAG"; + public const string STRIP_ITEM_RESTR = "AURORA_RESTR_STRIP"; + public const string STRIP_ITEM_CLRD_RTE = "AURORA_CLRD_RTE"; + public const string CPAR_ITEM_TYPE = "CPAR_TYP"; + public const string CPAR_ITEM_REQUIRED = "CPAR_REQUIRED"; + public const string CPAR_ITEM_INTRUDER = "CPAR_INT"; + public const string CPAR_ITEM_LOS = "CPAR_LOS"; + public const string CPAR_ITEM_ACTUAL = "CPAR_ACTUAL"; + public const string CPAR_ITEM_PASSING = "CPAR_PASSING"; + public const string CPAR_ITEM_CONF_SEG_START_1 = "CPAR_CONF_SEG_START_1"; + public const string CPAR_ITEM_CONF_SEG_START_2 = "CPAR_CONF_SEG_START_2"; + public const string CPAR_ITEM_CONF_SEG_END_1 = "CPAR_CONF_SEG_END_1"; + public const string CPAR_ITEM_CONF_SEG_END_2 = "CPAR_CONF_SEG_END_2"; + public const string CPAR_ITEM_STARTIME_1 = "CPAR_START_TIME_1"; + public const string CPAR_ITEM_STARTIME_2 = "CPAR_START_TIME_2"; + public const string CPAR_ITEM_ENDTIME_1 = "CPAR_END_TIME_1"; + public const string CPAR_ITEM_ENDTIME_2 = "CPAR_END_TIME_2"; + public const string CPAR_ITEM_AID_2 = "CPAR_AID_2"; + public const string CPAR_ITEM_TYP_2 = "CPAR_TYP_2"; + public const string CPAR_ITEM_SPD_2 = "CPAR_SPD_2"; + public const string CPAR_ITEM_ALT_2 = "CPAR_ALT_2"; + } + + public static class LabelConstants + { + public const string LABEL_ITEM_SELECT_HORI = "SELECT_HORI"; + public const string LABEL_ITEM_SELECT_VERT = "SELECT_VERT"; + public const string LABEL_ITEM_COMM_ICON = "AURORA_COMM_ICON"; //field a(2) + public const string LABEL_ITEM_ADSB_CPDLC = "AURORA_ADSB_CPDLC"; //field c(4) + public const string LABEL_ITEM_ADS_FLAGS = "AURORA_ADS_FLAGS"; //field c(4) + public const string LABEL_ITEM_MNT_FLAGS = "AURORA_MNT_FLAGS"; //field c(4) + public const string LABEL_ITEM_SCC = "AURORA_SCC"; //field d(5) + public const string LABEL_ITEM_ANNOT_IND = "AURORA_ANNOT_IND"; //field e(1) + public const string LABEL_ITEM_RESTR = "AURORA_RESTR"; //field f(1) + public const string LABEL_ITEM_LEVEL = "AURORA_LEVEL"; //field g(3) + public const string LABEL_ITEM_VMI = "AURORA_VMI"; //field h(1) + public const string LABEL_ITEM_CLEARED_LEVEL = "AURORA_CLEARED_LEVEL"; //field i(7) + public const string LABEL_ITEM_HANDOFF_IND = "AURORA_HO_IND"; //field j(4) + public const string LABEL_ITEM_RADAR_IND = "AURORA_RADAR_IND"; //field k(1) + public const string LABEL_ITEM_INHIBIT_IND = "AURORA_INHIBIT_IND"; //field l(1) + public const string LABEL_ITEM_FILED_SPEED = "AURORA_FILEDSPEED"; //field m(4) + public const string LABEL_ITEM_3DIGIT_GROUNDSPEED = "AURORA_GROUNDSPEED"; //field n(5) + public const string LABEL_ITEM_DESTINATION = "AURORA_DESTINATION"; //field o(4) + } +} \ No newline at end of file From 60860a363c7cba0f81d6a1e76d96378656c2c55d Mon Sep 17 00:00:00 2001 From: Maxim Salikhov Date: Mon, 12 Feb 2024 22:10:58 -0500 Subject: [PATCH 40/76] Update constant naming convention --- AuroraLabelItemsPlugin.cs | 42 +++++++------- AuroraStripItemPlugin.cs | 34 +++++------ Constants.cs | 118 +++++++++++++++++++------------------- 3 files changed, 96 insertions(+), 98 deletions(-) diff --git a/AuroraLabelItemsPlugin.cs b/AuroraLabelItemsPlugin.cs index c5428ed..193d80f 100644 --- a/AuroraLabelItemsPlugin.cs +++ b/AuroraLabelItemsPlugin.cs @@ -247,13 +247,13 @@ public CustomLabelItem GetCustomLabelItem(string itemType, Track track, FDR flig var notProbe = flightDataRecord.State == (FDR.FDRStates.STATE_PREACTIVE | FDR.FDRStates.STATE_COORDINATED) ? BorderFlags.All : BorderFlags.None; - var colour = !flightDataRecord.RVSM ? CustomColors.NonRVSM : ExcludeConflictColor(track, flightDataRecord); + var colour = !flightDataRecord.RVSM ? CustomColors.NonRvsm : ExcludeConflictColor(track, flightDataRecord); var excludeConflict = SelectASDTrackColour(track) == GetConflictColour(flightDataRecord.Callsign); switch (itemType) { - case LabelConstants.LABEL_ITEM_SELECT_HORI: + case LabelConstants.LabelItemSelectHori: if (MMI.SelectedTrack?.GetFDR()?.Callsign == track.GetFDR().Callsign) return new CustomLabelItem @@ -264,7 +264,7 @@ public CustomLabelItem GetCustomLabelItem(string itemType, Track track, FDR flig return null; - case LabelConstants.LABEL_ITEM_SELECT_VERT: + case LabelConstants.LabelItemSelectVert: if (MMI.SelectedTrack?.GetFDR()?.Callsign == track.GetFDR().Callsign) return new CustomLabelItem @@ -275,7 +275,7 @@ public CustomLabelItem GetCustomLabelItem(string itemType, Track track, FDR flig return null; - case LabelConstants.LABEL_ITEM_COMM_ICON: + case LabelConstants.LabelItemCommIcon: if (downLink) return new CustomLabelItem @@ -291,7 +291,7 @@ public CustomLabelItem GetCustomLabelItem(string itemType, Track track, FDR flig ForeColourIdentity = excludeConflict ? Colours.Identities.Custom : default, CustomForeColour = ExcludeConflictColor(track, flightDataRecord) }; - case LabelConstants.LABEL_ITEM_ADSB_CPDLC: + case LabelConstants.LabelItemAdsbCpdlc: var useCustomForeColour = flightDataRecord.State == (FDR.FDRStates.STATE_PREACTIVE | FDR.FDRStates.STATE_COORDINATED); @@ -300,7 +300,7 @@ public CustomLabelItem GetCustomLabelItem(string itemType, Track track, FDR flig return new CustomLabelItem { ForeColourIdentity = Colours.Identities.Custom, - CustomForeColour = CustomColors.NotCDA, + CustomForeColour = CustomColors.NotCda, Text = c1.ToString() }; return new CustomLabelItem @@ -310,7 +310,7 @@ public CustomLabelItem GetCustomLabelItem(string itemType, Track track, FDR flig CustomForeColour = ExcludeConflictColor(track, flightDataRecord) }; - case LabelConstants.LABEL_ITEM_ADS_FLAGS: + case LabelConstants.LabelItemAdsFlags: return new CustomLabelItem { @@ -320,7 +320,7 @@ public CustomLabelItem GetCustomLabelItem(string itemType, Track track, FDR flig }; - case LabelConstants.LABEL_ITEM_MNT_FLAGS: + case LabelConstants.LabelItemMntFlags: if (mntflagToggled) return new CustomLabelItem @@ -336,7 +336,7 @@ public CustomLabelItem GetCustomLabelItem(string itemType, Track track, FDR flig }; - case LabelConstants.LABEL_ITEM_SCC: + case LabelConstants.LabelItemScc: { return new CustomLabelItem @@ -348,7 +348,7 @@ public CustomLabelItem GetCustomLabelItem(string itemType, Track track, FDR flig } - case LabelConstants.LABEL_ITEM_ANNOT_IND: + case LabelConstants.LabelItemAnnotInd: var scratch = string.IsNullOrEmpty(flightDataRecord.LabelOpData); if (scratch) @@ -366,7 +366,7 @@ public CustomLabelItem GetCustomLabelItem(string itemType, Track track, FDR flig CustomForeColour = ExcludeConflictColor(track, flightDataRecord) }; - case LabelConstants.LABEL_ITEM_RESTR: + case LabelConstants.LabelItemRestr: if (flightDataRecord.LabelOpData.Contains("AT ") || flightDataRecord.LabelOpData.Contains(" BY ") || flightDataRecord.LabelOpData.Contains("CLEARED TO ")) @@ -380,7 +380,7 @@ public CustomLabelItem GetCustomLabelItem(string itemType, Track track, FDR flig return null; - case LabelConstants.LABEL_ITEM_LEVEL: + case LabelConstants.LabelItemLevel: var level = prl == -1 ? null : (radarTrack.CorrectedAltitude / 100).ToString(); @@ -390,12 +390,12 @@ public CustomLabelItem GetCustomLabelItem(string itemType, Track track, FDR flig Text = level, Border = notProbe, BorderColourIdentity = Colours.Identities.Custom, - CustomBorderColour = CustomColors.NotCDA, + CustomBorderColour = CustomColors.NotCda, ForeColourIdentity = excludeConflict ? Colours.Identities.Custom : default, CustomForeColour = colour }; - case LabelConstants.LABEL_ITEM_VMI: + case LabelConstants.LabelItemVmi: return new CustomLabelItem { @@ -405,7 +405,7 @@ public CustomLabelItem GetCustomLabelItem(string itemType, Track track, FDR flig }; - case LabelConstants.LABEL_ITEM_CLEARED_LEVEL: + case LabelConstants.LabelItemClearedLevel: if (radarTrack.ReachedCFL || prl == alt || Math.Abs(flightDataRecord.PRL - alt) < 300) @@ -419,7 +419,7 @@ public CustomLabelItem GetCustomLabelItem(string itemType, Track track, FDR flig Text = alt.ToString(), Border = notProbe, BorderColourIdentity = Colours.Identities.Custom, - CustomBorderColour = CustomColors.NotCDA, + CustomBorderColour = CustomColors.NotCda, ForeColourIdentity = excludeConflict ? Colours.Identities.Custom : default, CustomForeColour = colour }; @@ -451,7 +451,7 @@ public CustomLabelItem GetCustomLabelItem(string itemType, Track track, FDR flig // }; // } - case LabelConstants.LABEL_ITEM_RADAR_IND: + case LabelConstants.LabelItemRadarInd: if (radarToggled) @@ -471,7 +471,7 @@ public CustomLabelItem GetCustomLabelItem(string itemType, Track track, FDR flig CustomForeColour = ExcludeConflictColor(track, flightDataRecord) }; - case LabelConstants.LABEL_ITEM_INHIBIT_IND: + case LabelConstants.LabelItemInhibitInd: if (flightDataRecord.State == FDR.FDRStates.STATE_INHIBITED) @@ -488,7 +488,7 @@ public CustomLabelItem GetCustomLabelItem(string itemType, Track track, FDR flig }; - case LabelConstants.LABEL_ITEM_FILED_SPEED: + case LabelConstants.LabelItemFiledSpeed: var mach = Conversions.CalculateMach(flightDataRecord.TAS, GRIB.FindTemperature(flightDataRecord.PRL, track.GetLocation(), true)); return new CustomLabelItem @@ -499,7 +499,7 @@ public CustomLabelItem GetCustomLabelItem(string itemType, Track track, FDR flig CustomForeColour = ExcludeConflictColor(track, flightDataRecord) }; - case LabelConstants.LABEL_ITEM_3DIGIT_GROUNDSPEED: + case LabelConstants.LabelItem3DigitGroundspeed: //get groundspeed value from either FDR or radarTrack if coupled var gs = radarTrack == null ? flightDataRecord.PredictedPosition.Groundspeed @@ -511,7 +511,7 @@ public CustomLabelItem GetCustomLabelItem(string itemType, Track track, FDR flig CustomForeColour = ExcludeConflictColor(track, flightDataRecord) }; - case LabelConstants.LABEL_ITEM_DESTINATION: + case LabelConstants.LabelItemDestination: return new CustomLabelItem { diff --git a/AuroraStripItemPlugin.cs b/AuroraStripItemPlugin.cs index 28e44f7..7b04b45 100644 --- a/AuroraStripItemPlugin.cs +++ b/AuroraStripItemPlugin.cs @@ -77,7 +77,7 @@ public CustomStripItem GetCustomStripItem(string itemType, Track track, FDR flig switch (itemType) { - case StripConstants.STRIP_ITEM_CALLSIGN: + case StripConstants.StripItemCallsign: if (isEastBound) @@ -94,7 +94,7 @@ public CustomStripItem GetCustomStripItem(string itemType, Track track, FDR flig Text = flightDataRecord.Callsign }; - case StripConstants.STRIP_ITEM_CTLSECTOR: + case StripConstants.StripItemCtlsector: var pendingCoordination = flightDataRecord.State == (FDR.FDRStates.STATE_PREACTIVE | FDR.FDRStates.STATE_COORDINATED); @@ -112,7 +112,7 @@ public CustomStripItem GetCustomStripItem(string itemType, Track track, FDR flig } - case StripConstants.STRIP_ITEM_NXTSECTOR: + case StripConstants.StripItemNxtsector: TOC toc; toc = new TOC(flightDataRecord); @@ -129,7 +129,7 @@ public CustomStripItem GetCustomStripItem(string itemType, Track track, FDR flig } - case StripConstants.LABEL_ITEM_ADSB_CPDLC: + case StripConstants.LabelItemAdsbCpdlc: if (!isEastBound && !adsb && cpdlc) @@ -188,7 +188,7 @@ public CustomStripItem GetCustomStripItem(string itemType, Track track, FDR flig return null; - case StripConstants.STRIP_ITEM_T10_FLAG: + case StripConstants.StripItemT10Flag: if (flightDataRecord.PerformanceData?.IsJet ?? false) @@ -202,7 +202,7 @@ public CustomStripItem GetCustomStripItem(string itemType, Track track, FDR flig return null; - case StripConstants.STRIP_ITEM_MNT_FLAG: + case StripConstants.StripItemMntFlag: if (flightDataRecord.PerformanceData?.IsJet ?? false) @@ -215,7 +215,7 @@ public CustomStripItem GetCustomStripItem(string itemType, Track track, FDR flig return null; - case StripConstants.STRIP_ITEM_DIST_FLAG: + case StripConstants.StripItemDistFlag: if (adsc & cpdlc & (rnp4 || rnp10)) @@ -228,7 +228,7 @@ public CustomStripItem GetCustomStripItem(string itemType, Track track, FDR flig }; return null; - case StripConstants.STRIP_ITEM_RVSM_FLAG: + case StripConstants.StripItemRvsmFlag: if (rvsm) @@ -241,7 +241,7 @@ public CustomStripItem GetCustomStripItem(string itemType, Track track, FDR flig return null; - case StripConstants.STRIP_ITEM_VMI: + case StripConstants.StripItemVmi: var vs = radarTrack == null ? flightDataRecord.PredictedPosition.VerticalSpeed : radarTrack.VerticalSpeed; @@ -268,7 +268,7 @@ public CustomStripItem GetCustomStripItem(string itemType, Track track, FDR flig return null; - case StripConstants.STRIP_ITEM_COMPLEX: + case StripConstants.StripItemComplex: if (flightDataRecord.LabelOpData.Contains("AT ") || flightDataRecord.LabelOpData.Contains(" BY ") || flightDataRecord.LabelOpData.Contains("CLEARED TO ")) @@ -280,7 +280,7 @@ public CustomStripItem GetCustomStripItem(string itemType, Track track, FDR flig return null; - case StripConstants.STRIP_ITEM_CLEARED_LEVEL: + case StripConstants.StripItemClearedLevel: if (cfl == 0) return new CustomStripItem @@ -293,7 +293,7 @@ public CustomStripItem GetCustomStripItem(string itemType, Track track, FDR flig Text = cfl.ToString() }; - case StripConstants.STRIP_ITEM_REQUESTED_LEVEL: + case StripConstants.StripItemRequestedLevel: if (flightDataRecord.State == FDR.FDRStates.STATE_INACTIVE || flightDataRecord.State == FDR.FDRStates.STATE_INACTIVE) @@ -324,7 +324,7 @@ public CustomStripItem GetCustomStripItem(string itemType, Track track, FDR flig // { // Text = Conversions.ConvertToFlightplanLatLong() // }; - case StripConstants.STRIP_ITEM_ROUTE: + case StripConstants.StripItemRoute: return new CustomStripItem { @@ -333,7 +333,7 @@ public CustomStripItem GetCustomStripItem(string itemType, Track track, FDR flig }; - case StripConstants.STRIP_ITEM_RADAR_IND: + case StripConstants.StripItemRadarInd: return new CustomStripItem { @@ -342,7 +342,7 @@ public CustomStripItem GetCustomStripItem(string itemType, Track track, FDR flig }; - case StripConstants.STRIP_ITEM_ANNOT_IND: + case StripConstants.StripItemAnnotInd: var scratch = string.IsNullOrEmpty(flightDataRecord.LabelOpData); @@ -358,7 +358,7 @@ public CustomStripItem GetCustomStripItem(string itemType, Track track, FDR flig }; - case StripConstants.STRIP_ITEM_LATERAL_FLAG: + case StripConstants.StripItemLateralFlag: if (adsc & cpdlc & rnp4 || rnp10) @@ -372,7 +372,7 @@ public CustomStripItem GetCustomStripItem(string itemType, Track track, FDR flig }; return null; - case StripConstants.STRIP_ITEM_RESTR: + case StripConstants.StripItemRestr: if (flightDataRecord.LabelOpData.Contains("AT ") || flightDataRecord.LabelOpData.Contains(" BY ") || flightDataRecord.LabelOpData.Contains("CLEARED TO ")) diff --git a/Constants.cs b/Constants.cs index 8b21cfb..9a1e8d7 100644 --- a/Constants.cs +++ b/Constants.cs @@ -4,15 +4,13 @@ namespace AuroraLabelItemsPlugin { public static class CustomColors { - public static readonly CustomColour NonRvsm = new CustomColour(242, 133, 0); public static readonly CustomColour SepFlags = new CustomColour(0, 196, 253); public static readonly CustomColour Pending = new CustomColour(46, 139, 87); - public static readonly CustomColour NotCda = new CustomColour(100, 0, 100); public static readonly CustomColour EastboundColour = new CustomColour(240, 255, 255); public static readonly CustomColour WestboundColour = new CustomColour(240, 231, 140); - public static readonly CustomColour NonRVSM = new CustomColour(242, 133, 0); + public static readonly CustomColour NonRvsm = new CustomColour(242, 133, 0); public static readonly CustomColour Probe = new CustomColour(0, 255, 0); - public static readonly CustomColour NotCDA = new CustomColour(100, 0, 100); + public static readonly CustomColour NotCda = new CustomColour(100, 0, 100); public static readonly CustomColour Advisory = new CustomColour(255, 165, 0); public static readonly CustomColour Imminent = new CustomColour(255, 0, 0); public static readonly CustomColour SpecialConditionCode = new CustomColour(255, 255, 0); @@ -21,65 +19,65 @@ public static class CustomColors public static class StripConstants { - public const string LABEL_ITEM_ADSB_CPDLC = "AURORA_ADSB_CPDLC"; //field c(4) - public const string STRIP_ITEM_CALLSIGN = "AURORA_CALLSIGN"; - public const string STRIP_ITEM_CTLSECTOR = "AURORA_CDA"; - public const string STRIP_ITEM_NXTSECTOR = "AURORA_NDA"; - public const string STRIP_ITEM_T10_FLAG = "AURORA_T10_FLAG"; - public const string STRIP_ITEM_MNT_FLAG = "AURORA_MNT_FLAG"; - public const string STRIP_ITEM_DIST_FLAG = "AURORA_DIST_FLAG"; - public const string STRIP_ITEM_RVSM_FLAG = "AURORA_RVSM_FLAG"; - public const string STRIP_ITEM_VMI = "AURORA_STRIP_VMI"; - public const string STRIP_ITEM_COMPLEX = "AURORA_STRIP_COMPLEX"; - public const string STRIP_ITEM_CLEARED_LEVEL = "AURORA_CLEARED_LEVEL"; - public const string STRIP_ITEM_REQUESTED_LEVEL = "AURORA_REQUESTED_LEVEL"; - public const string STRIP_ITEM_MAN_EST = "AURORA_MAN_EST"; - public const string STRIP_ITEM_POINT = "AURORA_POINT"; - public const string STRIP_ITEM_ROUTE = "AURORA_ROUTE_STRIP"; - public const string STRIP_ITEM_RADAR_IND = "AURORA_RADAR_IND"; - public const string STRIP_ITEM_ANNOT_IND = "AURORA_ANNOT_STRIP"; - public const string STRIP_ITEM_LATERAL_FLAG = "AURORA_LATERAL_FLAG"; - public const string STRIP_ITEM_RESTR = "AURORA_RESTR_STRIP"; - public const string STRIP_ITEM_CLRD_RTE = "AURORA_CLRD_RTE"; - public const string CPAR_ITEM_TYPE = "CPAR_TYP"; - public const string CPAR_ITEM_REQUIRED = "CPAR_REQUIRED"; - public const string CPAR_ITEM_INTRUDER = "CPAR_INT"; - public const string CPAR_ITEM_LOS = "CPAR_LOS"; - public const string CPAR_ITEM_ACTUAL = "CPAR_ACTUAL"; - public const string CPAR_ITEM_PASSING = "CPAR_PASSING"; - public const string CPAR_ITEM_CONF_SEG_START_1 = "CPAR_CONF_SEG_START_1"; - public const string CPAR_ITEM_CONF_SEG_START_2 = "CPAR_CONF_SEG_START_2"; - public const string CPAR_ITEM_CONF_SEG_END_1 = "CPAR_CONF_SEG_END_1"; - public const string CPAR_ITEM_CONF_SEG_END_2 = "CPAR_CONF_SEG_END_2"; - public const string CPAR_ITEM_STARTIME_1 = "CPAR_START_TIME_1"; - public const string CPAR_ITEM_STARTIME_2 = "CPAR_START_TIME_2"; - public const string CPAR_ITEM_ENDTIME_1 = "CPAR_END_TIME_1"; - public const string CPAR_ITEM_ENDTIME_2 = "CPAR_END_TIME_2"; - public const string CPAR_ITEM_AID_2 = "CPAR_AID_2"; - public const string CPAR_ITEM_TYP_2 = "CPAR_TYP_2"; - public const string CPAR_ITEM_SPD_2 = "CPAR_SPD_2"; - public const string CPAR_ITEM_ALT_2 = "CPAR_ALT_2"; + public const string LabelItemAdsbCpdlc = "AURORA_ADSB_CPDLC"; //field c(4) + public const string StripItemCallsign = "AURORA_CALLSIGN"; + public const string StripItemCtlsector = "AURORA_CDA"; + public const string StripItemNxtsector = "AURORA_NDA"; + public const string StripItemT10Flag = "AURORA_T10_FLAG"; + public const string StripItemMntFlag = "AURORA_MNT_FLAG"; + public const string StripItemDistFlag = "AURORA_DIST_FLAG"; + public const string StripItemRvsmFlag = "AURORA_RVSM_FLAG"; + public const string StripItemVmi = "AURORA_STRIP_VMI"; + public const string StripItemComplex = "AURORA_STRIP_COMPLEX"; + public const string StripItemClearedLevel = "AURORA_CLEARED_LEVEL"; + public const string StripItemRequestedLevel = "AURORA_REQUESTED_LEVEL"; + public const string StripItemManEst = "AURORA_MAN_EST"; + public const string StripItemPoint = "AURORA_POINT"; + public const string StripItemRoute = "AURORA_ROUTE_STRIP"; + public const string StripItemRadarInd = "AURORA_RADAR_IND"; + public const string StripItemAnnotInd = "AURORA_ANNOT_STRIP"; + public const string StripItemLateralFlag = "AURORA_LATERAL_FLAG"; + public const string StripItemRestr = "AURORA_RESTR_STRIP"; + public const string StripItemClrdRte = "AURORA_CLRD_RTE"; + public const string CparItemType = "CPAR_TYP"; + public const string CparItemRequired = "CPAR_REQUIRED"; + public const string CparItemIntruder = "CPAR_INT"; + public const string CparItemLos = "CPAR_LOS"; + public const string CparItemActual = "CPAR_ACTUAL"; + public const string CparItemPassing = "CPAR_PASSING"; + public const string CparItemConfSegStart1 = "CPAR_CONF_SEG_START_1"; + public const string CparItemConfSegStart2 = "CPAR_CONF_SEG_START_2"; + public const string CparItemConfSegEnd1 = "CPAR_CONF_SEG_END_1"; + public const string CparItemConfSegEnd2 = "CPAR_CONF_SEG_END_2"; + public const string CparItemStartime1 = "CPAR_START_TIME_1"; + public const string CparItemStartime2 = "CPAR_START_TIME_2"; + public const string CparItemEndtime1 = "CPAR_END_TIME_1"; + public const string CparItemEndtime2 = "CPAR_END_TIME_2"; + public const string CparItemAid2 = "CPAR_AID_2"; + public const string CparItemTyp2 = "CPAR_TYP_2"; + public const string CparItemSpd2 = "CPAR_SPD_2"; + public const string CparItemAlt2 = "CPAR_ALT_2"; } public static class LabelConstants { - public const string LABEL_ITEM_SELECT_HORI = "SELECT_HORI"; - public const string LABEL_ITEM_SELECT_VERT = "SELECT_VERT"; - public const string LABEL_ITEM_COMM_ICON = "AURORA_COMM_ICON"; //field a(2) - public const string LABEL_ITEM_ADSB_CPDLC = "AURORA_ADSB_CPDLC"; //field c(4) - public const string LABEL_ITEM_ADS_FLAGS = "AURORA_ADS_FLAGS"; //field c(4) - public const string LABEL_ITEM_MNT_FLAGS = "AURORA_MNT_FLAGS"; //field c(4) - public const string LABEL_ITEM_SCC = "AURORA_SCC"; //field d(5) - public const string LABEL_ITEM_ANNOT_IND = "AURORA_ANNOT_IND"; //field e(1) - public const string LABEL_ITEM_RESTR = "AURORA_RESTR"; //field f(1) - public const string LABEL_ITEM_LEVEL = "AURORA_LEVEL"; //field g(3) - public const string LABEL_ITEM_VMI = "AURORA_VMI"; //field h(1) - public const string LABEL_ITEM_CLEARED_LEVEL = "AURORA_CLEARED_LEVEL"; //field i(7) - public const string LABEL_ITEM_HANDOFF_IND = "AURORA_HO_IND"; //field j(4) - public const string LABEL_ITEM_RADAR_IND = "AURORA_RADAR_IND"; //field k(1) - public const string LABEL_ITEM_INHIBIT_IND = "AURORA_INHIBIT_IND"; //field l(1) - public const string LABEL_ITEM_FILED_SPEED = "AURORA_FILEDSPEED"; //field m(4) - public const string LABEL_ITEM_3DIGIT_GROUNDSPEED = "AURORA_GROUNDSPEED"; //field n(5) - public const string LABEL_ITEM_DESTINATION = "AURORA_DESTINATION"; //field o(4) + public const string LabelItemSelectHori = "SELECT_HORI"; + public const string LabelItemSelectVert = "SELECT_VERT"; + public const string LabelItemCommIcon = "AURORA_COMM_ICON"; //field a(2) + public const string LabelItemAdsbCpdlc = "AURORA_ADSB_CPDLC"; //field c(4) + public const string LabelItemAdsFlags = "AURORA_ADS_FLAGS"; //field c(4) + public const string LabelItemMntFlags = "AURORA_MNT_FLAGS"; //field c(4) + public const string LabelItemScc = "AURORA_SCC"; //field d(5) + public const string LabelItemAnnotInd = "AURORA_ANNOT_IND"; //field e(1) + public const string LabelItemRestr = "AURORA_RESTR"; //field f(1) + public const string LabelItemLevel = "AURORA_LEVEL"; //field g(3) + public const string LabelItemVmi = "AURORA_VMI"; //field h(1) + public const string LabelItemClearedLevel = "AURORA_CLEARED_LEVEL"; //field i(7) + public const string LabelItemHandoffInd = "AURORA_HO_IND"; //field j(4) + public const string LabelItemRadarInd = "AURORA_RADAR_IND"; //field k(1) + public const string LabelItemInhibitInd = "AURORA_INHIBIT_IND"; //field l(1) + public const string LabelItemFiledSpeed = "AURORA_FILEDSPEED"; //field m(4) + public const string LabelItem3DigitGroundspeed = "AURORA_GROUNDSPEED"; //field n(5) + public const string LabelItemDestination = "AURORA_DESTINATION"; //field o(4) } } \ No newline at end of file From ac5c40bd1d134da538a613e37cf76000940e14d0 Mon Sep 17 00:00:00 2001 From: Maxim Salikhov Date: Thu, 15 Feb 2024 00:42:46 -0500 Subject: [PATCH 41/76] Add extended fdr state --- AuroraLabelItemsPlugin.csproj | 14 +++++++++++- AuroraStripItemPlugin.cs | 4 ---- Fdr/AltitudeBlock.cs | 18 ++++++++++++++++ Fdr/AltitudeCalculator.cs | 40 +++++++++++++++++++++++++++++++++++ Fdr/AltitudeFlag.cs | 16 ++++++++++++++ Fdr/DirectionOfFlight.cs | 23 ++++++++++++++++++++ Fdr/ExtendedFdrState.cs | 39 ++++++++++++++++++++++++++++++++++ Fdr/FdrExtensions.cs | 16 ++++++++++++++ Fdr/FdrManager.cs | 14 ++++++++++++ Fdr/FdrParser.cs | 31 +++++++++++++++++++++++++++ Fdr/ParsedFdrFields.cs | 8 +++++++ Fdr/SccFlag.cs | 16 ++++++++++++++ Fdr/SccFlagCalculator.cs | 31 +++++++++++++++++++++++++++ 13 files changed, 265 insertions(+), 5 deletions(-) create mode 100644 Fdr/AltitudeBlock.cs create mode 100644 Fdr/AltitudeCalculator.cs create mode 100644 Fdr/AltitudeFlag.cs create mode 100644 Fdr/DirectionOfFlight.cs create mode 100644 Fdr/ExtendedFdrState.cs create mode 100644 Fdr/FdrExtensions.cs create mode 100644 Fdr/FdrManager.cs create mode 100644 Fdr/FdrParser.cs create mode 100644 Fdr/ParsedFdrFields.cs create mode 100644 Fdr/SccFlag.cs create mode 100644 Fdr/SccFlagCalculator.cs diff --git a/AuroraLabelItemsPlugin.csproj b/AuroraLabelItemsPlugin.csproj index 99e2f8e..6641f3f 100644 --- a/AuroraLabelItemsPlugin.csproj +++ b/AuroraLabelItemsPlugin.csproj @@ -9,9 +9,10 @@ Properties AuroraLabelItemsPlugin AuroraLabelItemsPlugin - v4.7.2 + v4.8 512 true + 11 true @@ -52,6 +53,17 @@ + + + + + + + + + + + diff --git a/AuroraStripItemPlugin.cs b/AuroraStripItemPlugin.cs index 7b04b45..4cd62ec 100644 --- a/AuroraStripItemPlugin.cs +++ b/AuroraStripItemPlugin.cs @@ -17,10 +17,6 @@ public class AuroraStripItemsPlugin : IStripPlugin new ConcurrentDictionary(); private readonly ConcurrentDictionary flagtoggle = new ConcurrentDictionary(); - private CPAR cpar = new CPAR(); - - private AuroraLabelItemsPlugin.AuroraLabelItemsPlugin label = - new AuroraLabelItemsPlugin.AuroraLabelItemsPlugin(); /// Plugin Name public string Name => "Aurora Label Items"; diff --git a/Fdr/AltitudeBlock.cs b/Fdr/AltitudeBlock.cs new file mode 100644 index 0000000..c8e958f --- /dev/null +++ b/Fdr/AltitudeBlock.cs @@ -0,0 +1,18 @@ +using vatsys; + +namespace AuroraLabelItemsPlugin.Fdr; + +public record struct AltitudeBlock(int LowerAltitude, int UpperAltitude) +{ + public static AltitudeBlock ExtractAltitudeBlock(FDP2.FDR fdr) + { + var altitudeUpper = ExtractClearedOrRequestedValue(fdr.CFLUpper, fdr.RFL); + var altitudeLower = ExtractClearedOrRequestedValue(fdr.CFLLower, fdr.RFL); + return new AltitudeBlock(altitudeLower, altitudeUpper); + } + + private static int ExtractClearedOrRequestedValue(int clearedValue, int requestedValue) + { + return clearedValue == -1 ? requestedValue : clearedValue; + } +} \ No newline at end of file diff --git a/Fdr/AltitudeCalculator.cs b/Fdr/AltitudeCalculator.cs new file mode 100644 index 0000000..a71f0fd --- /dev/null +++ b/Fdr/AltitudeCalculator.cs @@ -0,0 +1,40 @@ +#nullable enable +using vatsys; + +namespace AuroraLabelItemsPlugin.Fdr; + +public static class AltitudeCalculator +{ + private const int LevelFlightThreshold = 300; + + public static bool CalculateAltitudeChangePending(FDP2.FDR updatedFdr, AltitudeBlock previousBlock, + bool wasPreviouslyPending) + { + var newBlock = AltitudeBlock.ExtractAltitudeBlock(updatedFdr); + return (newBlock != previousBlock || wasPreviouslyPending) + && !IsWithinThreshold(updatedFdr.PRL, newBlock); + } + + public static AltitudeFlag? CalculateAltitudeFlag(FDP2.FDR fdr, bool pendingAltitudeChange) + { + var altitudeBlock = AltitudeBlock.ExtractAltitudeBlock(fdr); + var (altitudeLower, altitudeUpper) = altitudeBlock; + var isOutsideThreshold = !IsWithinThreshold(fdr.PRL, altitudeBlock); + + return isOutsideThreshold switch + { + true when pendingAltitudeChange && fdr.PRL < altitudeLower => AltitudeFlag.Climbing, + true when pendingAltitudeChange && fdr.PRL > altitudeUpper => AltitudeFlag.Descending, + true when !pendingAltitudeChange && fdr.PRL < altitudeLower => AltitudeFlag.DeviatingBelow, + true when !pendingAltitudeChange && fdr.PRL > altitudeUpper => AltitudeFlag.DeviatingAbove, + _ => null + }; + } + + private static bool IsWithinThreshold(int pilotReportedAltitude, AltitudeBlock altitudeBlock) + { + var lowerWithThreshold = altitudeBlock.LowerAltitude - LevelFlightThreshold; + var upperWithThreshold = altitudeBlock.UpperAltitude + LevelFlightThreshold; + return pilotReportedAltitude > lowerWithThreshold && pilotReportedAltitude < upperWithThreshold; + } +} \ No newline at end of file diff --git a/Fdr/AltitudeFlag.cs b/Fdr/AltitudeFlag.cs new file mode 100644 index 0000000..0c58bd2 --- /dev/null +++ b/Fdr/AltitudeFlag.cs @@ -0,0 +1,16 @@ +namespace AuroraLabelItemsPlugin.Fdr; + +public class AltitudeFlag +{ + private AltitudeFlag(string value) + { + Value = value; + } + + public string Value { get; private set; } + + public static AltitudeFlag Climbing => new("↑"); + public static AltitudeFlag Descending => new("↓"); + public static AltitudeFlag DeviatingAbove => new("+"); + public static AltitudeFlag DeviatingBelow => new("-"); +} \ No newline at end of file diff --git a/Fdr/DirectionOfFlight.cs b/Fdr/DirectionOfFlight.cs new file mode 100644 index 0000000..3ac727b --- /dev/null +++ b/Fdr/DirectionOfFlight.cs @@ -0,0 +1,23 @@ +using vatsys; + +namespace AuroraLabelItemsPlugin.Fdr; + +public enum DirectionOfFlight +{ + Eastbound, + Westbound, + Undetermined +} + +public static class DirectionOfFlightCalculator +{ + public static DirectionOfFlight GetDirectionOfFlight(FDP2.FDR fdr) + { + if (fdr.ParsedRoute.Count <= 1) return DirectionOfFlight.Undetermined; + + var track = Conversions.CalculateTrack(fdr.ParsedRoute.First().Intersection.LatLong, + fdr.ParsedRoute.Last().Intersection.LatLong); + + return track is >= 0.0 and < 180.0 ? DirectionOfFlight.Eastbound : DirectionOfFlight.Westbound; + } +} \ No newline at end of file diff --git a/Fdr/ExtendedFdrState.cs b/Fdr/ExtendedFdrState.cs new file mode 100644 index 0000000..3512403 --- /dev/null +++ b/Fdr/ExtendedFdrState.cs @@ -0,0 +1,39 @@ +#nullable enable +using vatsys; + +namespace AuroraLabelItemsPlugin.Fdr; + +public class ExtendedFdrState +{ + public ExtendedFdrState(FDP2.FDR fdr) + { + UpdateFromFdr(fdr); + DownlinkIndicator = false; + RadarToggleIndicator = false; + } + + public ParsedFdrFields ParsedFdrFields { get; private set; } + public DirectionOfFlight DirectionOfFlight { get; private set; } + public SccFlag? HighestSccFlag { get; private set; } + public AltitudeFlag? AltitudeFlag { get; private set; } + public bool DownlinkIndicator { get; set; } + public bool RadarToggleIndicator { get; set; } + + private bool PendingAltitudeChange { get; set; } + private AltitudeBlock PreviousAltitudeBlock { get; set; } + + public void UpdateFromFdr(FDP2.FDR updatedFdr) + { + ParsedFdrFields = FdrParser.ParseFdrFields(updatedFdr); + DirectionOfFlight = DirectionOfFlightCalculator.GetDirectionOfFlight(updatedFdr); + HighestSccFlag = SccFlagCalculator.CalculateHighestPriorityFlag(updatedFdr); + + // ensure the bool for altitude change is calculated first since it is used in the altitude flag calculation + PendingAltitudeChange = + AltitudeCalculator.CalculateAltitudeChangePending(updatedFdr, PreviousAltitudeBlock, PendingAltitudeChange); + AltitudeFlag = AltitudeCalculator.CalculateAltitudeFlag(updatedFdr, PendingAltitudeChange); + + // update this last since so we have the previous value for the next update + PreviousAltitudeBlock = AltitudeBlock.ExtractAltitudeBlock(updatedFdr); + } +} \ No newline at end of file diff --git a/Fdr/FdrExtensions.cs b/Fdr/FdrExtensions.cs new file mode 100644 index 0000000..a29648e --- /dev/null +++ b/Fdr/FdrExtensions.cs @@ -0,0 +1,16 @@ +using vatsys; + +namespace AuroraLabelItemsPlugin.Fdr; + +public static class FdrExtensions +{ + public static ExtendedFdrState GetExtendedState(this FDP2.FDR fdr) + { + return FdrManager.GetExtendedFdrState(fdr.Callsign); + } + + public static int? GetTransponderCode(this FDP2.FDR fdr) + { + return fdr.CoupledTrack?.ActualAircraft.TransponderCode; + } +} \ No newline at end of file diff --git a/Fdr/FdrManager.cs b/Fdr/FdrManager.cs new file mode 100644 index 0000000..32afb08 --- /dev/null +++ b/Fdr/FdrManager.cs @@ -0,0 +1,14 @@ +using System.Collections.Concurrent; + +namespace AuroraLabelItemsPlugin.Fdr; + +public static class FdrManager +{ + private static readonly ConcurrentDictionary ExtendedFdrStates = new(); + + public static ExtendedFdrState GetExtendedFdrState(string callsign) + { + var found = ExtendedFdrStates.TryGetValue(callsign, out var state); + return found ? state : null; + } +} \ No newline at end of file diff --git a/Fdr/FdrParser.cs b/Fdr/FdrParser.cs new file mode 100644 index 0000000..208dbb6 --- /dev/null +++ b/Fdr/FdrParser.cs @@ -0,0 +1,31 @@ +using System.Linq; +using System.Text.RegularExpressions; +using vatsys; + +namespace AuroraLabelItemsPlugin.Fdr; + +public static class FdrParser +{ + private const string Rnp10Pbn = "A1"; + private const string Rnp4Pbn = "L1"; + + private const string AdscSurvEquip = "D1"; + + private static readonly string[] CpdlcEquip = + { + "J5", "J7" + }; + + public static ParsedFdrFields ParseFdrFields(FDP2.FDR fdr) + { + // TODO(msalikhov): can we pull from fdr.PBNCapability + var pbn = Regex.Match(fdr.Remarks, @"PBN\/\w+\s").Value; + + return new ParsedFdrFields( + pbn.Contains(Rnp4Pbn), + pbn.Contains(Rnp10Pbn), + CpdlcEquip.Any(cpdlcVal => fdr.AircraftEquip.Contains(cpdlcVal)), + fdr.AircraftSurvEquip.Contains(AdscSurvEquip) + ); + } +} \ No newline at end of file diff --git a/Fdr/ParsedFdrFields.cs b/Fdr/ParsedFdrFields.cs new file mode 100644 index 0000000..91ad488 --- /dev/null +++ b/Fdr/ParsedFdrFields.cs @@ -0,0 +1,8 @@ +namespace AuroraLabelItemsPlugin.Fdr; + +public record struct ParsedFdrFields( + bool Rnp4, + bool Rnp10, + bool Cpdlc, + bool Adsc +); \ No newline at end of file diff --git a/Fdr/SccFlag.cs b/Fdr/SccFlag.cs new file mode 100644 index 0000000..b8598d7 --- /dev/null +++ b/Fdr/SccFlag.cs @@ -0,0 +1,16 @@ +namespace AuroraLabelItemsPlugin.Fdr; + +public class SccFlag +{ + private SccFlag(string value) + { + Value = value; + } + + public string Value { get; private set; } + + public static SccFlag Rnp => new("RNP"); + public static SccFlag Emg => new("EMG"); + public static SccFlag Rcf => new("RCF"); + public static SccFlag Mti => new("MTI"); +} \ No newline at end of file diff --git a/Fdr/SccFlagCalculator.cs b/Fdr/SccFlagCalculator.cs new file mode 100644 index 0000000..741d7b2 --- /dev/null +++ b/Fdr/SccFlagCalculator.cs @@ -0,0 +1,31 @@ +#nullable enable +using vatsys; + +namespace AuroraLabelItemsPlugin.Fdr; + +public static class SccFlagCalculator +{ + private const int RadioFailureCode = 7600; + private const int EmergencyCode = 7700; + private const int MilitaryInterceptCode = 7777; + + public static SccFlag? CalculateHighestPriorityFlag(FDP2.FDR fdr) + { + var parsedFdrFields = fdr.GetExtendedState().ParsedFdrFields; + + var transponderCode = fdr.GetTransponderCode(); + switch (transponderCode) + { + case EmergencyCode: + return SccFlag.Emg; + case RadioFailureCode: + return SccFlag.Rcf; + case MilitaryInterceptCode: + return SccFlag.Mti; + } + + if (!parsedFdrFields.Rnp4 || !parsedFdrFields.Rnp10) return SccFlag.Rnp; + + return null; + } +} \ No newline at end of file From 9ce772742f85d241c7db0421cdd85e1704a57192 Mon Sep 17 00:00:00 2001 From: Maxim Salikhov Date: Sat, 17 Feb 2024 20:51:48 -0500 Subject: [PATCH 42/76] Clean up conflict probe code --- AuroraLabelItemsPlugin.csproj | 7 +- CPAR.cs | 482 ----------------------------- Conflict/ConflictAreaCalculator.cs | 194 ++++++++++++ Conflict/ConflictProbe.cs | 151 +++++++++ Conflict/ConflictType.cs | 8 + Conflict/MinimaCalculator.cs | 103 ++++++ Fdr/AltitudeBlock.cs | 18 -- Fdr/AltitudeCalculator.cs | 1 + Fdr/ExtendedFdrState.cs | 1 + Fdr/FdrParser.cs | 14 +- Fdr/ParsedFdrFields.cs | 3 +- Models/AltitudeBlock.cs | 56 ++++ 12 files changed, 532 insertions(+), 506 deletions(-) delete mode 100644 CPAR.cs create mode 100644 Conflict/ConflictAreaCalculator.cs create mode 100644 Conflict/ConflictProbe.cs create mode 100644 Conflict/ConflictType.cs create mode 100644 Conflict/MinimaCalculator.cs delete mode 100644 Fdr/AltitudeBlock.cs create mode 100644 Models/AltitudeBlock.cs diff --git a/AuroraLabelItemsPlugin.csproj b/AuroraLabelItemsPlugin.csproj index 6641f3f..6707116 100644 --- a/AuroraLabelItemsPlugin.csproj +++ b/AuroraLabelItemsPlugin.csproj @@ -51,9 +51,11 @@ + + + + - - @@ -66,6 +68,7 @@ + diff --git a/CPAR.cs b/CPAR.cs deleted file mode 100644 index e574e82..0000000 --- a/CPAR.cs +++ /dev/null @@ -1,482 +0,0 @@ -// Decompiled with JetBrains decompiler -// Type: vatsys.LATC -// Assembly: vatSys, Version=0.4.8114.34539, Culture=neutral, PublicKeyToken=null -// MVID: E82FB2F8-DAB0-42FD-91AA-1C44F8E62564 -// Assembly location: E:\vatsys\bin\vatSys.exe -// XML documentation location: E:\vatsys\bin\vatSys.xml - -using System; -using System.Collections.Generic; -using System.Linq; -using AuroraLabelItemsPlugin; - -namespace vatsys -{ - public class CPAR - { - private readonly GEO label = new GEO(); - public List Segments1 = new List(); - public List Segments2 = new List(); - public DateTime Timeout = DateTime.MaxValue; - - public CPAR(FDP2.FDR fdr1, FDP2.FDR fdr2, int value) - { - CalculateLATC(fdr1, fdr2, value); - } - - public CPAR() - { - } - - private void CalculateLATC(FDP2.FDR fdr1, FDP2.FDR fdr2, int value) - { - if (fdr1 == null || fdr2 == null) - return; - Segments1.AddRange(CalculateAreaOfConflict(fdr1, fdr2, value)); - Segments2.AddRange(CalculateAreaOfConflict(fdr2, fdr1, value)); - } - - private static List CalculateAreaOfConflict(FDP2.FDR fdr1, FDP2.FDR fdr2, int value) - { - var segs = new List(); - var route1waypoints = fdr1.ParsedRoute.ToList() - .Where(s => s.Type == FDP2.FDR.ExtractedRoute.Segment.SegmentTypes.WAYPOINT).ToList(); - var route2waypoints = fdr2.ParsedRoute.ToList() - .Where(s => s.Type == FDP2.FDR.ExtractedRoute.Segment.SegmentTypes.WAYPOINT).ToList(); - for (var wp1index = 1; wp1index < route1waypoints.Count; ++wp1index) - { - var route1Segment = CreatePolygon(route1waypoints[wp1index - 1].Intersection.LatLong, - route1waypoints[wp1index].Intersection.LatLong, value); - for (var wp2index = 1; wp2index < route2waypoints.Count; wp2index++) - { - var source = new List(); - var intersectionPoints = new List(); - source.AddRange(CalculatePolygonIntersections(route1Segment, - route2waypoints[wp2index - 1].Intersection.LatLong, - route2waypoints[wp2index].Intersection.LatLong)); - var num1 = 0; - var num2 = 0; - foreach (var coordinate in source.ToList()) - if (Conversions.IsLatLonOnGC(route2waypoints[wp2index - 1].Intersection.LatLong, - route2waypoints[wp2index].Intersection.LatLong, coordinate)) - { - intersectionPoints.Add(coordinate); - } - else - { - var track = Conversions.CalculateTrack(route2waypoints[wp2index - 1].Intersection.LatLong, - route2waypoints[wp2index].Intersection.LatLong); - if (Math.Abs(track - - Conversions.CalculateTrack(route2waypoints[wp2index - 1].Intersection.LatLong, - coordinate)) > 90.0) - ++num1; - if (Math.Abs(track - Conversions.CalculateTrack(coordinate, - route2waypoints[wp2index].Intersection.LatLong)) > 90.0) - ++num2; - } - - if (num1 % 2 != 0 && num2 % 2 != 0) - { - intersectionPoints.Clear(); - intersectionPoints.Add(route2waypoints[wp2index - 1].Intersection.LatLong); - intersectionPoints.Add(route2waypoints[wp2index].Intersection.LatLong); - } - else if (num2 % 2 != 0) - { - intersectionPoints.Add(route2waypoints[wp2index].Intersection.LatLong); - } - else if (num1 % 2 != 0) - { - intersectionPoints.Add(route2waypoints[wp2index - 1].Intersection.LatLong); - } - - intersectionPoints.Sort((x, y) => - Conversions.CalculateDistance(route2waypoints[wp2index - 1].Intersection.LatLong, x) - .CompareTo(Conversions.CalculateDistance(route2waypoints[wp2index - 1].Intersection.LatLong, - y))); - for (var ipIndex = 1; ipIndex < intersectionPoints.Count; ipIndex += 2) - { - var seg = new Segment(); - seg.startLatlong = intersectionPoints[ipIndex - 1]; - seg.endLatlong = intersectionPoints[ipIndex]; - var conflictSegments = segs.Where(s => s.routeSegment == route2waypoints[wp2index]).Where(s => - (Conversions.CalculateDistance(s.startLatlong, - route2waypoints[wp2index - 1].Intersection.LatLong) < - Conversions.CalculateDistance(seg.startLatlong, - route2waypoints[wp2index - 1].Intersection.LatLong) && - Conversions.CalculateDistance(s.endLatlong, - route2waypoints[wp2index - 1].Intersection.LatLong) > - Conversions.CalculateDistance(seg.startLatlong, - route2waypoints[wp2index - 1].Intersection.LatLong)) || - (Conversions.CalculateDistance(s.endLatlong, - route2waypoints[wp2index - 1].Intersection.LatLong) > - Conversions.CalculateDistance(seg.endLatlong, - route2waypoints[wp2index - 1].Intersection.LatLong) && - Conversions.CalculateDistance(s.startLatlong, - route2waypoints[wp2index - 1].Intersection.LatLong) < - Conversions.CalculateDistance(seg.endLatlong, - route2waypoints[wp2index - 1].Intersection.LatLong)) || - (Conversions.CalculateDistance(s.startLatlong, - route2waypoints[wp2index - 1].Intersection.LatLong) > - Conversions.CalculateDistance(seg.startLatlong, - route2waypoints[wp2index - 1].Intersection.LatLong) && - Conversions.CalculateDistance(s.endLatlong, - route2waypoints[wp2index - 1].Intersection.LatLong) < - Conversions.CalculateDistance(seg.endLatlong, - route2waypoints[wp2index - 1].Intersection.LatLong)) || - Conversions.CalculateDistance(s.startLatlong, seg.startLatlong) < 0.01 || - Conversions.CalculateDistance(s.endLatlong, seg.endLatlong) < 0.01).ToList(); - if (conflictSegments.Count > 0) - { - foreach (var segment in conflictSegments) - { - if (Conversions.CalculateDistance(segment.endLatlong, - route2waypoints[wp2index - 1].Intersection.LatLong) < - Conversions.CalculateDistance(seg.endLatlong, - route2waypoints[wp2index - 1].Intersection.LatLong)) - segment.endLatlong = seg.endLatlong; - if (Conversions.CalculateDistance(seg.startLatlong, - route2waypoints[wp2index - 1].Intersection.LatLong) < - Conversions.CalculateDistance(segment.startLatlong, - route2waypoints[wp2index - 1].Intersection.LatLong)) - segment.startLatlong = seg.startLatlong; - } - } - else - { - seg.callsign = fdr2.Callsign; - seg.routeSegment = route2waypoints[wp2index]; - segs.Add(seg); - } - } - } - } - - for (var i = 0; i < segs.Count; i++) - { - if (!segs.Exists(s => Conversions.CalculateDistance(segs[i].startLatlong, s.endLatlong) < 0.01)) - segs[i].startTime = - FDP2.GetSystemEstimateAtPosition(fdr2, segs[i].startLatlong, segs[i].routeSegment); - if (!segs.Exists(s => Conversions.CalculateDistance(segs[i].endLatlong, s.startLatlong) < 0.01)) - segs[i].endTime = FDP2.GetSystemEstimateAtPosition(fdr2, segs[i].endLatlong, segs[i].routeSegment); - } - - return segs; - } - - private static List CreatePolygon(Coordinate point1, Coordinate point2, int value) - { - var polygon = new List(); - var track = Conversions.CalculateTrack(point1, point2); - var num1 = track - 90.0; - for (var index = 0; index <= 180; index += 10) - { - var heading = num1 - index; - var fromBearingRange = Conversions.CalculateLLFromBearingRange(point1, value, heading); - polygon.Add(fromBearingRange); - } - - var num2 = track + 90.0; - for (var index = 0; index <= 180; index += 10) - { - var heading = num2 - index; - var fromBearingRange = Conversions.CalculateLLFromBearingRange(point2, value, heading); - polygon.Add(fromBearingRange); - } - - polygon.Add(polygon[0]); - return polygon; - } - - private static List CalculatePolygonIntersections( - List polygon, - Coordinate point1, - Coordinate point2) - { - var polygonIntersections = new List(); - for (var index = 1; index < polygon.Count; ++index) - { - var gcIntersectionLl = - Conversions.CalculateAllGCIntersectionLL(polygon[index - 1], polygon[index], point1, point2); - if (gcIntersectionLl != null) - polygonIntersections.AddRange(gcIntersectionLl); - } - - for (var index = 0; index < polygonIntersections.Count; ++index) - { - var intsect = polygonIntersections[index]; - polygonIntersections.RemoveAll(c => c != intsect && Conversions.CalculateDistance(intsect, c) < 0.01); - } - - return polygonIntersections; - } - - public void ConflictProbe(FDP2.FDR fdr, int latSep) - { - var conDict = new List(); - var fpap = new FPAP(); - - if (fdr == null || !MMI.IsMySectorConcerned(fdr)) return; - var cfl = fdr.CFLUpper; - var rfl = fdr.RFL; - var alt = cfl == -1 ? rfl : cfl; - var isRvsm = fdr.RVSM; - for (var i = 0; i < conDict.Count; i++) - foreach (var fdr2 in FDP2.GetFDRs) - { - if (fdr2 == null || fdr.Callsign == fdr2.Callsign || !MMI.IsMySectorConcerned(fdr2)) continue; - var data = new ConflictData(); - var rte = fdr.ParsedRoute; - var rte2 = fdr2.ParsedRoute; - var trk = Conversions.CalculateTrack(rte.First().Intersection.LatLong, - rte.Last().Intersection.LatLong); - var trk2 = Conversions.CalculateTrack(rte2.First().Intersection.LatLong, - rte2.Last().Intersection.LatLong); - data.trkAngle = Math.Abs(trk2 - trk); - var sameDir = data.trkAngle < 45; - var crossing = (data.trkAngle >= 45 && data.trkAngle <= 135) || - (data.trkAngle >= 315 && data.trkAngle <= 225); - var oppoDir = data.trkAngle > 135 && data.trkAngle < 225; - var cfl2 = fdr2.CFLUpper; - var rfl2 = fdr2.RFL; - var alt2 = cfl2 == -1 ? rfl2 : cfl2; - var isRvsm2 = fdr2.RVSM; - data.verticalAct = Math.Abs(alt - alt2); - data.verticalSep = alt > 45000 && alt < 60000 - ? 4000 - : alt > 60000 - ? 5000 - : alt2 > 45000 && alt2 < 60000 - ? 4000 - : alt2 > 60000 - ? 5000 - : (alt > FDP2.RVSM_BAND_LOWER && !isRvsm) || - (alt2 > FDP2.RVSM_BAND_LOWER && !isRvsm2) || alt > FDP2.RVSM_BAND_UPPER || - alt2 > FDP2.RVSM_BAND_UPPER - ? 2000 - : 1000; - - if (data.verticalAct < data.verticalSep) - { - //data.latSep = latSep1; - - if (fpap.rnp4 && fpap.pbcs && fpap.adsc && fpap.cpdlc) - data.latSep = Math.Max(latSep, 23); - - - else if (fpap.rnp10 || fpap.rnp4) - data.latSep = Math.Max(latSep, 50); - - else if (!fpap.rnp10 && !fpap.rnp4) - data.latSep = Math.Max(latSep, 100); - - else if (data.latSep != 100 && data.latSep == 100) ; - { - data.latSep = (50 + 100) / 2; - } - - var cpar = new CPAR(fdr2, fdr, data.latSep); - var segments1 = cpar.Segments1; - var segments2 = cpar.Segments2; - - segments1.Sort((s, t) => s.startTime.CompareTo(t.startTime)); //sort by first conflict time - segments2.Sort((s, t) => s.startTime.CompareTo(t.startTime)); - - var firstConflictTime = segments1.FirstOrDefault(); - var firstConflictTime2 = segments2.FirstOrDefault(); - var failedLateral = segments1.Count > 0; - if (firstConflictTime == null || firstConflictTime2 == null) continue; - - data.mnt = sameDir && fpap.jet; - data.longTimesep = data.mnt ? new TimeSpan(0, 0, 10, 0) : new TimeSpan(0, 0, 15, 0); - data.longTimeact = (firstConflictTime2.startTime - firstConflictTime.startTime).Duration(); - data.longDistsep = fpap.jet && fpap.rnp4 && fpap.pbcs && fpap.cpdlc && fpap.adsc ? 30 : - fpap.jet && fpap.rnp10 && fpap.pbcs && fpap.cpdlc && fpap.adsc ? 50 : default; - data.longDistact = Conversions.CalculateDistance(firstConflictTime.startLatlong, - firstConflictTime2.startLatlong); - data.timeLongsame = sameDir && failedLateral && firstConflictTime.endTime > DateTime.UtcNow - && data.longTimeact < - data.longTimesep; //check time based longitudinal for same direction - data.timeLongcross = crossing && failedLateral && firstConflictTime.endTime > DateTime.UtcNow - && (firstConflictTime2.startTime - firstConflictTime.startTime) - .Duration() < new TimeSpan(0, 0, 15, 0); - data.distLongsame = sameDir && failedLateral && firstConflictTime.endTime > DateTime.UtcNow - && data.longDistact < data.longDistsep; - - data.timeLongopposite = false; - data.top = null; - - if (failedLateral && oppoDir) - { - try - { - data.top = new TimeOfPassing(fdr, fdr2); - } - - catch (Exception e) - { - return; - } - - data.timeLongopposite = data.top.Time > DateTime.UtcNow - && data.top.Time.Add(new TimeSpan(0, 0, 10, 0)) > DateTime.UtcNow && - data.top.Time.Subtract(new TimeSpan(0, 0, 10, 0)) < DateTime.UtcNow; - } - - data.longType = fpap.adsc && fpap.cpdlc && (fpap.rnp4 || fpap.rnp10) && fpap.pbcs - ? data.distLongsame - : data.timeLongsame; - - var lossOfSep = data.longType || data.timeLongcross || data.timeLongopposite; - data.conflictType = lossOfSep && sameDir ? "same" : - lossOfSep && crossing ? "crossing" : - lossOfSep && oppoDir ? "opposite" : null; - data.earliestLOS = failedLateral && oppoDir - ? data.top.Time.Subtract(new TimeSpan(0, 0, 10, 0)) - : DateTime.Compare(firstConflictTime.startTime, firstConflictTime2.startTime) < 0 - ? firstConflictTime.startTime - : firstConflictTime2.startTime; - - data.actualConflicts = failedLateral && oppoDir && data.verticalAct < data.verticalSep - ? new TimeSpan(0, 0, 1, 0, 0) >= data.earliestLOS.Subtract(DateTime.UtcNow).Duration() - : (lossOfSep && new TimeSpan(0, 0, 1, 0, 0) >= - data.earliestLOS.Subtract(DateTime.UtcNow).Duration()) || - data.earliestLOS < DateTime.UtcNow; - - data.imminentConflicts = failedLateral && oppoDir && data.verticalAct < data.verticalSep - ? new TimeSpan(0, 0, 30, 0, 0) >= data.earliestLOS.Subtract(DateTime.UtcNow).Duration() - : lossOfSep && new TimeSpan(0, 0, 30, 0, 0) >= - data.earliestLOS.Subtract(DateTime.UtcNow).Duration(); //check if timediff < 30 min - - data.advisoryConflicts = failedLateral && oppoDir && data.verticalAct < data.verticalSep - ? new TimeSpan(0, 2, 0, 0, 0) > data.earliestLOS.Subtract(DateTime.UtcNow).Duration() - && data.earliestLOS.Subtract(DateTime.UtcNow).Duration() >= new TimeSpan(0, 0, 30, 0, 0) - : lossOfSep && new TimeSpan(0, 2, 0, 0, 0) > - data.earliestLOS.Subtract(DateTime.UtcNow).Duration() - && data.earliestLOS.Subtract(DateTime.UtcNow).Duration() >= - new TimeSpan(0, 0, 30, 0, 0); //check if 2 hours > timediff > 30 mins - - - if (data.actualConflicts || data.imminentConflicts) - { - label.imminentConflict.AddOrUpdate(fdr.Callsign, - new HashSet(new[] { fdr2.Callsign }), - (k, v) => - { - v.Add(fdr2.Callsign); - return v; - }); - - conDict.Add(data); - } - else - { - HashSet maybeSet; - var exists = label.imminentConflict.TryGetValue(fdr.Callsign, out maybeSet); - if (exists) maybeSet.Clear(); - - - var emptyImminentConflicts = label.imminentConflict.Where(pair => pair.Value.Count == 0) - .Select(pair => pair.Key) - .ToList(); - foreach (var callsign in emptyImminentConflicts) - label.imminentConflict.TryRemove(callsign, out _); - - - if (data.advisoryConflicts) - { - label.advisoryConflict.AddOrUpdate(fdr.Callsign, - new HashSet(new[] { fdr2.Callsign }), - (k, v) => - { - v.Add(fdr2.Callsign); - return v; - }); - } - else - { - HashSet admaybeSet; - var adexists = label.advisoryConflict.TryGetValue(fdr.Callsign, out admaybeSet); - if (adexists) admaybeSet.Clear(); - - var emptyAdvisoryConflicts = label.advisoryConflict.Where(pair => pair.Value.Count == 0) - .Select(pair => pair.Key) - .ToList(); - foreach (var callsign in emptyAdvisoryConflicts) - label.advisoryConflict.TryRemove(callsign, out _); - } - } - } - else - { - HashSet - maybeSet; // defines an uninitialized variable for the result of the below method to get placed in - HashSet admaybeSet; - var adexists = label.advisoryConflict.TryGetValue(fdr.Callsign, out admaybeSet); - var exists = - label.imminentConflict.TryGetValue(fdr.Callsign, - out maybeSet); // tries to get the set of conflicts corresponding to a callsign, places it in the `maybeSet` variable if it exists. The bool `exists` represents whether there was a set of conflicts for that callsign - if (exists) - maybeSet.Remove(fdr2 - .Callsign); // remove the fdr2 (which is the one we are currently evaluating for conflicts against fdr) from the set of conflicts - if (adexists) - admaybeSet.Remove(fdr2 - .Callsign); // remove the fdr2 (which is the one we are currently evaluating for conflicts against fdr) from the set of conflicts - - var emptyAdvisoryConflicts = label.advisoryConflict.Where(pair => pair.Value.Count == 0) - .Select(pair => pair.Key) - .ToList(); - foreach (var callsign in emptyAdvisoryConflicts) - label.advisoryConflict.TryRemove(callsign, out _); - var emptyImminentConflicts = label.imminentConflict.Where(pair => pair.Value.Count == 0) - .Select(pair => pair.Key) - .ToList(); - foreach (var callsign in emptyImminentConflicts) - label.imminentConflict.TryRemove(callsign, out _); - } - } - } - - - public class Segment - { - public string callsign; - public Coordinate endLatlong; - public DateTime endTime = DateTime.MaxValue; - public FDP2.FDR.ExtractedRoute.Segment routeSegment; - public Coordinate startLatlong; - public DateTime startTime = DateTime.MaxValue; - } - - public class ConflictData - { - public bool actualConflicts; - public bool advisoryConflicts; - public string conflictType; - public bool distLongsame; - public DateTime earliestLOS; - public Segment endLatlong; - public Segment endTime; - public FDP2.FDR fdr; - public FDP2.FDR fdr2; - public bool imminentConflicts; - public int latAct; - public int latSep; - public double longDistact; - public double longDistsep; - public TimeSpan longTimeact; - public TimeSpan longTimesep; - public bool longType; - public bool mnt; - public Segment startLatlong; - public Segment startTime; - public bool timeLongcross; - public bool timeLongopposite; - public bool timeLongsame; - public TimeOfPassing top; - public double trkAngle; - public int verticalAct; - public int verticalSep; - } - } -} \ No newline at end of file diff --git a/Conflict/ConflictAreaCalculator.cs b/Conflict/ConflictAreaCalculator.cs new file mode 100644 index 0000000..5e23365 --- /dev/null +++ b/Conflict/ConflictAreaCalculator.cs @@ -0,0 +1,194 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using vatsys; + +namespace AuroraLabelItemsPlugin.Conflict; + +public static class ConflictAreaCalculator +{ + public static List CalculateAreaOfConflict(FDP2.FDR fdr1, FDP2.FDR fdr2, int value) + { + var fdr2SegmentsConflictingWithFdr1 = new List(); + var route1Waypoints = fdr1.ParsedRoute.ToList() + .Where(s => s.Type == FDP2.FDR.ExtractedRoute.Segment.SegmentTypes.WAYPOINT).ToList(); + var route2Waypoints = fdr2.ParsedRoute.ToList() + .Where(s => s.Type == FDP2.FDR.ExtractedRoute.Segment.SegmentTypes.WAYPOINT).ToList(); + for (var wp1Index = 1; wp1Index < route1Waypoints.Count; ++wp1Index) + { + var route1ProtectedAirspace = CreatePolygon(route1Waypoints[wp1Index - 1].Intersection.LatLong, + route1Waypoints[wp1Index].Intersection.LatLong, value); + for (var wp2Index = 1; wp2Index < route2Waypoints.Count; wp2Index++) + { + var prevRoute2LatLong = route2Waypoints[wp2Index - 1].Intersection.LatLong; + var currRoute2LatLong = route2Waypoints[wp2Index].Intersection.LatLong; + var protectedAirspacePenetrations = CalculatePolygonIntersections(route1ProtectedAirspace, + prevRoute2LatLong, + currRoute2LatLong); + var intersectionPoints = new List(); + var num1 = 0; + var num2 = 0; + foreach (var penetration in protectedAirspacePenetrations) + if (Conversions.IsLatLonOnGC(prevRoute2LatLong, currRoute2LatLong, penetration)) + { + intersectionPoints.Add(penetration); + } + else + { + var route2Track = Conversions.CalculateTrack(prevRoute2LatLong, currRoute2LatLong); + if (Math.Abs(route2Track - Conversions.CalculateTrack(prevRoute2LatLong, penetration)) > 90.0) + ++num1; + if (Math.Abs(route2Track - Conversions.CalculateTrack(penetration, currRoute2LatLong)) > 90.0) + ++num2; + } + + if (num1 % 2 != 0 && num2 % 2 != 0) + { + intersectionPoints.Clear(); + intersectionPoints.Add(prevRoute2LatLong); + intersectionPoints.Add(currRoute2LatLong); + } + else if (num2 % 2 != 0) + { + intersectionPoints.Add(currRoute2LatLong); + } + else if (num1 % 2 != 0) + { + intersectionPoints.Add(prevRoute2LatLong); + } + + intersectionPoints.Sort((x, y) => + Conversions.CalculateDistance(prevRoute2LatLong, x) + .CompareTo(Conversions.CalculateDistance(currRoute2LatLong, y))); + for (var ipIndex = 1; ipIndex < intersectionPoints.Count; ipIndex += 2) + { + var seg = new ConflictSegment(); + seg.StartLatlong = intersectionPoints[ipIndex - 1]; + seg.EndLatlong = intersectionPoints[ipIndex]; + var conflictSegments = fdr2SegmentsConflictingWithFdr1 + .Where(s => s.RouteSegment == route2Waypoints[wp2Index]).Where(s => + (Conversions.CalculateDistance(s.StartLatlong, + prevRoute2LatLong) < + Conversions.CalculateDistance(seg.StartLatlong, + prevRoute2LatLong) && + Conversions.CalculateDistance(s.EndLatlong, + prevRoute2LatLong) > + Conversions.CalculateDistance(seg.StartLatlong, + prevRoute2LatLong)) || + (Conversions.CalculateDistance(s.EndLatlong, + prevRoute2LatLong) > + Conversions.CalculateDistance(seg.EndLatlong, + prevRoute2LatLong) && + Conversions.CalculateDistance(s.StartLatlong, + prevRoute2LatLong) < + Conversions.CalculateDistance(seg.EndLatlong, + prevRoute2LatLong)) || + (Conversions.CalculateDistance(s.StartLatlong, + prevRoute2LatLong) > + Conversions.CalculateDistance(seg.StartLatlong, + prevRoute2LatLong) && + Conversions.CalculateDistance(s.EndLatlong, + prevRoute2LatLong) < + Conversions.CalculateDistance(seg.EndLatlong, + prevRoute2LatLong)) || + Conversions.CalculateDistance(s.StartLatlong, seg.StartLatlong) < 0.01 || + Conversions.CalculateDistance(s.EndLatlong, seg.EndLatlong) < 0.01).ToList(); + if (conflictSegments.Count > 0) + { + foreach (var segment in conflictSegments) + { + if (Conversions.CalculateDistance(segment.EndLatlong, + prevRoute2LatLong) < + Conversions.CalculateDistance(seg.EndLatlong, + prevRoute2LatLong)) + segment.EndLatlong = seg.EndLatlong; + if (Conversions.CalculateDistance(seg.StartLatlong, + prevRoute2LatLong) < + Conversions.CalculateDistance(segment.StartLatlong, + prevRoute2LatLong)) + segment.StartLatlong = seg.StartLatlong; + } + } + else + { + seg.Callsign = fdr2.Callsign; + seg.RouteSegment = route2Waypoints[wp2Index]; + fdr2SegmentsConflictingWithFdr1.Add(seg); + } + } + } + } + + foreach (var segment in fdr2SegmentsConflictingWithFdr1) + { + if (!fdr2SegmentsConflictingWithFdr1.Exists(s => + Conversions.CalculateDistance(segment.StartLatlong, s.EndLatlong) < 0.01)) + segment.StartTime = + FDP2.GetSystemEstimateAtPosition(fdr2, segment.StartLatlong, segment.RouteSegment); + if (!fdr2SegmentsConflictingWithFdr1.Exists(s => + Conversions.CalculateDistance(segment.EndLatlong, s.StartLatlong) < 0.01)) + segment.EndTime = FDP2.GetSystemEstimateAtPosition(fdr2, segment.EndLatlong, segment.RouteSegment); + } + + return fdr2SegmentsConflictingWithFdr1; + } + + + private static List CreatePolygon(Coordinate point1, Coordinate point2, int value) + { + var polygon = new List(); + var track = Conversions.CalculateTrack(point1, point2); + var num1 = track - 90.0; + for (var index = 0; index <= 180; index += 10) + { + var heading = num1 - index; + var fromBearingRange = Conversions.CalculateLLFromBearingRange(point1, value, heading); + polygon.Add(fromBearingRange); + } + + var num2 = track + 90.0; + for (var index = 0; index <= 180; index += 10) + { + var heading = num2 - index; + var fromBearingRange = Conversions.CalculateLLFromBearingRange(point2, value, heading); + polygon.Add(fromBearingRange); + } + + polygon.Add(polygon[0]); + return polygon; + } + + private static List CalculatePolygonIntersections( + List polygon, + Coordinate point1, + Coordinate point2) + { + var polygonIntersections = new List(); + for (var index = 1; index < polygon.Count; ++index) + { + var gcIntersectionLl = + Conversions.CalculateAllGCIntersectionLL(polygon[index - 1], polygon[index], point1, point2); + if (gcIntersectionLl != null) + polygonIntersections.AddRange(gcIntersectionLl); + } + + for (var index = 0; index < polygonIntersections.Count; ++index) + { + var intsect = polygonIntersections[index]; + polygonIntersections.RemoveAll(c => + !Equals(c, intsect) && Conversions.CalculateDistance(intsect, c) < 0.01); + } + + return polygonIntersections; + } +} + +public class ConflictSegment +{ + public string Callsign; + public Coordinate EndLatlong; + public DateTime EndTime = DateTime.MaxValue; + public FDP2.FDR.ExtractedRoute.Segment RouteSegment; + public Coordinate StartLatlong; + public DateTime StartTime = DateTime.MaxValue; +} \ No newline at end of file diff --git a/Conflict/ConflictProbe.cs b/Conflict/ConflictProbe.cs new file mode 100644 index 0000000..a6de53e --- /dev/null +++ b/Conflict/ConflictProbe.cs @@ -0,0 +1,151 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using AuroraLabelItemsPlugin.Models; +using vatsys; + +namespace AuroraLabelItemsPlugin.Conflict; + +public class ConflictProbe +{ + public List Probe(FDP2.FDR fdr) + { + if (!MMI.IsMySectorConcerned(fdr)) return null; + + var discoveredConflicts = new List(); + + var block1 = AltitudeBlock.ExtractAltitudeBlock(fdr); + foreach (var fdr2 in FDP2.GetFDRs.Where(fdr2 => + fdr2 != null && fdr.Callsign != fdr2.Callsign && MMI.IsMySectorConcerned(fdr2))) + { + var data = new ConflictData + { + Fdr2 = fdr2 + }; + var rte = fdr.ParsedRoute; + var rte2 = fdr2.ParsedRoute; + var trk = Conversions.CalculateTrack(rte.First().Intersection.LatLong, + rte.Last().Intersection.LatLong); + var trk2 = Conversions.CalculateTrack(rte2.First().Intersection.LatLong, + rte2.Last().Intersection.LatLong); + data.TrkAngle = Math.Abs(trk2 - trk); + var sameDir = data.TrkAngle < 45; + var crossing = (data.TrkAngle >= 45 && data.TrkAngle <= 135) || + (data.TrkAngle >= 315 && data.TrkAngle <= 225); + var oppoDir = data.TrkAngle > 135 && data.TrkAngle < 225; + var block2 = AltitudeBlock.ExtractAltitudeBlock(fdr2); + + data.VerticalAct = AltitudeBlock.Difference(block1, block2); + data.VerticalSep = MinimaCalculator.GetVerticalMinima(fdr, fdr2); + + if (data.VerticalAct >= data.VerticalSep) continue; + + data.LatSep = MinimaCalculator.GetLateralMinima(fdr, fdr2); + + // TODO(msalikhov): figure out what this was trying to do - it had no effect + // else if (data.latSep != 100 && data.latSep == 100) ; + // { + // data.latSep = (50 + 100) / 2; + // } + + var conflictSegments1 = ConflictAreaCalculator.CalculateAreaOfConflict(fdr, fdr2, data.LatSep); + var conflictSegments2 = ConflictAreaCalculator.CalculateAreaOfConflict(fdr2, fdr, data.LatSep); + + conflictSegments1.Sort((s, t) => s.StartTime.CompareTo(t.StartTime)); //sort by first conflict time + conflictSegments2.Sort((s, t) => s.StartTime.CompareTo(t.StartTime)); //sort by first conflict time + + var firstConflictTime = conflictSegments1.FirstOrDefault(); + var firstConflictTime2 = conflictSegments2.FirstOrDefault(); + var failedLateral = conflictSegments1.Count > 0; + if (firstConflictTime == null || firstConflictTime2 == null) continue; + + data.LongTimesep = MinimaCalculator.GetLongitudinalTime(fdr, fdr2); + data.LongTimeact = (firstConflictTime2.StartTime - firstConflictTime.StartTime).Duration(); + data.LongDistsep = MinimaCalculator.GetLongitudinalDistance(fdr, fdr2); + data.LongDistact = Conversions.CalculateDistance(firstConflictTime.StartLatlong, + firstConflictTime2.StartLatlong); + data.TimeLongsame = sameDir && failedLateral && firstConflictTime.EndTime > DateTime.UtcNow + && data.LongTimeact < + data.LongTimesep; //check time based longitudinal for same direction + data.TimeLongcross = crossing && failedLateral && firstConflictTime.EndTime > DateTime.UtcNow + && (firstConflictTime2.StartTime - firstConflictTime.StartTime) + .Duration() < new TimeSpan(0, 0, 15, 0); + data.DistLongsame = sameDir && failedLateral && firstConflictTime.EndTime > DateTime.UtcNow + && data.LongDistact < data.LongDistsep; + + data.TimeLongopposite = false; + data.Top = null; + + if (failedLateral && oppoDir) + { + data.Top = new TimeOfPassing(fdr, fdr2); + data.TimeLongopposite = data.Top.Time > DateTime.UtcNow + && data.Top.Time.Add(data.LongTimesep) > DateTime.UtcNow && + data.Top.Time.Subtract(data.LongTimesep) < DateTime.UtcNow; + } + + data.LongType = data.LongDistsep == null + ? data.TimeLongsame + : data.DistLongsame; + + var lossOfSep = data.LongType || data.TimeLongcross || data.TimeLongopposite; + data.ConflictType = lossOfSep && sameDir ? ConflictType.SameDirection : + lossOfSep && crossing ? ConflictType.Crossing : + lossOfSep && oppoDir ? ConflictType.OppositeDirection : null; + data.EarliestLos = failedLateral && oppoDir + ? data.Top.Time.Subtract(new TimeSpan(0, 0, 10, 0)) + : DateTime.Compare(firstConflictTime.StartTime, firstConflictTime2.StartTime) < 0 + ? firstConflictTime.StartTime + : firstConflictTime2.StartTime; + + data.ActualConflicts = failedLateral && oppoDir && data.VerticalAct < data.VerticalSep + ? new TimeSpan(0, 0, 1, 0, 0) >= data.EarliestLos.Subtract(DateTime.UtcNow).Duration() + : (lossOfSep && new TimeSpan(0, 0, 1, 0, 0) >= + data.EarliestLos.Subtract(DateTime.UtcNow).Duration()) || + data.EarliestLos < DateTime.UtcNow; + + data.ImminentConflicts = failedLateral && oppoDir && data.VerticalAct < data.VerticalSep + ? new TimeSpan(0, 0, 30, 0, 0) >= data.EarliestLos.Subtract(DateTime.UtcNow).Duration() + : lossOfSep && new TimeSpan(0, 0, 30, 0, 0) >= + data.EarliestLos.Subtract(DateTime.UtcNow).Duration(); //check if timediff < 30 min + + data.AdvisoryConflicts = failedLateral && oppoDir && data.VerticalAct < data.VerticalSep + ? new TimeSpan(0, 2, 0, 0, 0) > data.EarliestLos.Subtract(DateTime.UtcNow).Duration() + && data.EarliestLos.Subtract(DateTime.UtcNow).Duration() >= new TimeSpan(0, 0, 30, 0, 0) + : lossOfSep && new TimeSpan(0, 2, 0, 0, 0) > + data.EarliestLos.Subtract(DateTime.UtcNow).Duration() + && data.EarliestLos.Subtract(DateTime.UtcNow).Duration() >= + new TimeSpan(0, 0, 30, 0, 0); //check if 2 hours > timediff > 30 mins + if (data.ActualConflicts || data.ImminentConflicts || data.AdvisoryConflicts) + { + discoveredConflicts.Add(data); + } + } + + return discoveredConflicts; + } + + public record ConflictData + { + public bool ActualConflicts; + public bool AdvisoryConflicts; + public ConflictType? ConflictType; + public bool DistLongsame; + public DateTime EarliestLos; + public FDP2.FDR Fdr2; + public bool ImminentConflicts; + public int LatSep; + public double LongDistact; + public int? LongDistsep; + public TimeSpan LongTimeact; + public TimeSpan LongTimesep; + public bool LongType; + public bool TimeLongcross; + public bool TimeLongopposite; + public bool TimeLongsame; + public TimeOfPassing Top; + public double TrkAngle; + public int VerticalAct; + public int VerticalSep; + } +} \ No newline at end of file diff --git a/Conflict/ConflictType.cs b/Conflict/ConflictType.cs new file mode 100644 index 0000000..6c26180 --- /dev/null +++ b/Conflict/ConflictType.cs @@ -0,0 +1,8 @@ +namespace AuroraLabelItemsPlugin.Conflict; + +public enum ConflictType +{ + SameDirection, + OppositeDirection, + Crossing +} \ No newline at end of file diff --git a/Conflict/MinimaCalculator.cs b/Conflict/MinimaCalculator.cs new file mode 100644 index 0000000..2167b04 --- /dev/null +++ b/Conflict/MinimaCalculator.cs @@ -0,0 +1,103 @@ +using System; +using AuroraLabelItemsPlugin.Fdr; +using AuroraLabelItemsPlugin.Models; +using vatsys; + +namespace AuroraLabelItemsPlugin.Conflict; + +public static class MinimaCalculator +{ + private const int Rnp4Lateral = 23; + private const int Rnp10Lateral = 50; + private const int StandardLateral = 100; + + private const int StandardVertical = 1000; + private const int NonRvsmVertical = 2000; + private const int SupersonicVertical = 4000; + private const int Above600Vertical = 5000; + + private const int TimeLongitudinal = 15; + private const int JetLongitudinal = 10; + private const int DistanceLongitudinal = 50; + private const int Rnp4Longitudinal = 30; + + public static int GetLateralMinima(FDP2.FDR fdr1, FDP2.FDR fdr2) + { + if (CanApplyRnp4(fdr1) && CanApplyRnp4(fdr2)) + { + return Rnp4Lateral; + } + + if (CanApplyRnp10(fdr1) && CanApplyRnp10(fdr2)) + { + return Rnp10Lateral; + } + + return StandardLateral; + } + + public static int GetVerticalMinima(FDP2.FDR fdr1, FDP2.FDR fdr2) + { + var block1 = AltitudeBlock.ExtractAltitudeBlock(fdr1); + var block2 = AltitudeBlock.ExtractAltitudeBlock(fdr2); + + if (block1.IsAbove600() || block2.IsAbove600()) // technically this only applies if they are military + { + return Above600Vertical; + } + + if (block1.IsAbove450() || block2.IsAbove450()) // technically this only applies if one is supersonic + { + return SupersonicVertical; + } + + if (!(block1.IsBelowRvsm() || block2.IsBelowRvsm()) && (block1.IsAboveRvsm() || block2.IsAboveRvsm())) + { + return NonRvsmVertical; + } + + return StandardVertical; + } + + public static TimeSpan GetLongitudinalTime(FDP2.FDR fdr1, FDP2.FDR fdr2) + { + return IsJet(fdr1) && IsJet(fdr2) + ? new TimeSpan(0, JetLongitudinal, 0) + : new TimeSpan(0, TimeLongitudinal, 0); + } + + public static int? GetLongitudinalDistance(FDP2.FDR fdr1, FDP2.FDR fdr2) + { + if (CanApplyRnp4(fdr1) && CanApplyRnp4(fdr2)) + { + return Rnp4Longitudinal; + } + + if (HasDatalink(fdr1) && HasDatalink(fdr2) && CanApplyRnp10(fdr1) && CanApplyRnp10(fdr2)) + { + return DistanceLongitudinal; + } + + return null; + } + + private static bool HasDatalink(FDP2.FDR fdr) + { + return fdr.GetExtendedState().ParsedFdrFields is { Pbcs: true, Adsc: true, Cpdlc: true }; + } + + private static bool CanApplyRnp4(FDP2.FDR fdr) + { + return HasDatalink(fdr) && fdr.GetExtendedState().ParsedFdrFields.Rnp4; + } + + private static bool CanApplyRnp10(FDP2.FDR fdr) + { + return fdr.GetExtendedState().ParsedFdrFields is { Rnp10: true }; + } + + private static bool IsJet(FDP2.FDR fdr) + { + return fdr.PerformanceData.IsJet; + } +} \ No newline at end of file diff --git a/Fdr/AltitudeBlock.cs b/Fdr/AltitudeBlock.cs deleted file mode 100644 index c8e958f..0000000 --- a/Fdr/AltitudeBlock.cs +++ /dev/null @@ -1,18 +0,0 @@ -using vatsys; - -namespace AuroraLabelItemsPlugin.Fdr; - -public record struct AltitudeBlock(int LowerAltitude, int UpperAltitude) -{ - public static AltitudeBlock ExtractAltitudeBlock(FDP2.FDR fdr) - { - var altitudeUpper = ExtractClearedOrRequestedValue(fdr.CFLUpper, fdr.RFL); - var altitudeLower = ExtractClearedOrRequestedValue(fdr.CFLLower, fdr.RFL); - return new AltitudeBlock(altitudeLower, altitudeUpper); - } - - private static int ExtractClearedOrRequestedValue(int clearedValue, int requestedValue) - { - return clearedValue == -1 ? requestedValue : clearedValue; - } -} \ No newline at end of file diff --git a/Fdr/AltitudeCalculator.cs b/Fdr/AltitudeCalculator.cs index a71f0fd..f7944f9 100644 --- a/Fdr/AltitudeCalculator.cs +++ b/Fdr/AltitudeCalculator.cs @@ -1,4 +1,5 @@ #nullable enable +using AuroraLabelItemsPlugin.Models; using vatsys; namespace AuroraLabelItemsPlugin.Fdr; diff --git a/Fdr/ExtendedFdrState.cs b/Fdr/ExtendedFdrState.cs index 3512403..00aa6d7 100644 --- a/Fdr/ExtendedFdrState.cs +++ b/Fdr/ExtendedFdrState.cs @@ -1,4 +1,5 @@ #nullable enable +using AuroraLabelItemsPlugin.Models; using vatsys; namespace AuroraLabelItemsPlugin.Fdr; diff --git a/Fdr/FdrParser.cs b/Fdr/FdrParser.cs index 208dbb6..276c777 100644 --- a/Fdr/FdrParser.cs +++ b/Fdr/FdrParser.cs @@ -9,8 +9,12 @@ public static class FdrParser private const string Rnp10Pbn = "A1"; private const string Rnp4Pbn = "L1"; + private const string Rsp180Sur = "RSP180"; + private const string AdscSurvEquip = "D1"; + private const string Rcp240SurvEquip = "P2"; + private const string PbnEquip = "R"; private static readonly string[] CpdlcEquip = { "J5", "J7" @@ -20,12 +24,16 @@ public static ParsedFdrFields ParseFdrFields(FDP2.FDR fdr) { // TODO(msalikhov): can we pull from fdr.PBNCapability var pbn = Regex.Match(fdr.Remarks, @"PBN\/\w+\s").Value; + var sur = Regex.Match(fdr.Remarks, @"SUR\/\w+\s").Value; + + var isPbn = fdr.AircraftEquip.Contains(PbnEquip); return new ParsedFdrFields( - pbn.Contains(Rnp4Pbn), - pbn.Contains(Rnp10Pbn), + isPbn && pbn.Contains(Rnp4Pbn), + isPbn && pbn.Contains(Rnp10Pbn), CpdlcEquip.Any(cpdlcVal => fdr.AircraftEquip.Contains(cpdlcVal)), - fdr.AircraftSurvEquip.Contains(AdscSurvEquip) + fdr.AircraftSurvEquip.Contains(AdscSurvEquip), + sur.Contains(Rsp180Sur) && fdr.AircraftSurvEquip.Contains(Rcp240SurvEquip) ); } } \ No newline at end of file diff --git a/Fdr/ParsedFdrFields.cs b/Fdr/ParsedFdrFields.cs index 91ad488..b91e70f 100644 --- a/Fdr/ParsedFdrFields.cs +++ b/Fdr/ParsedFdrFields.cs @@ -4,5 +4,6 @@ public record struct ParsedFdrFields( bool Rnp4, bool Rnp10, bool Cpdlc, - bool Adsc + bool Adsc, + bool Pbcs ); \ No newline at end of file diff --git a/Models/AltitudeBlock.cs b/Models/AltitudeBlock.cs new file mode 100644 index 0000000..4207f13 --- /dev/null +++ b/Models/AltitudeBlock.cs @@ -0,0 +1,56 @@ +using vatsys; + +namespace AuroraLabelItemsPlugin.Models; + +public record struct AltitudeBlock(int LowerAltitude, int UpperAltitude) +{ + private const int Fl450 = 45000; + private const int Fl600 = 60000; + + public bool IsBelowRvsm() + { + return UpperAltitude <= FDP2.RVSM_BAND_LOWER; + } + + public bool IsAbove450() + { + return UpperAltitude > Fl450 || LowerAltitude > Fl450; + } + + public bool IsAbove600() + { + return UpperAltitude > Fl600 || LowerAltitude > Fl600; + } + + public bool IsAboveRvsm() + { + return UpperAltitude > FDP2.RVSM_BAND_UPPER || LowerAltitude > FDP2.RVSM_BAND_UPPER; + } + + public static int Difference(AltitudeBlock block1, AltitudeBlock block2) + { + // check for intersection + if (block1.LowerAltitude <= block2.UpperAltitude && block2.LowerAltitude <= block1.UpperAltitude) + { + return 0; + } + + var isBlock1Lower = block1.UpperAltitude < block2.LowerAltitude; + + return isBlock1Lower + ? block2.LowerAltitude - block1.UpperAltitude + : block1.LowerAltitude - block2.UpperAltitude; + } + + public static AltitudeBlock ExtractAltitudeBlock(FDP2.FDR fdr) + { + var altitudeUpper = ExtractClearedOrRequestedValue(fdr.CFLUpper, fdr.RFL); + var altitudeLower = ExtractClearedOrRequestedValue(fdr.CFLLower, fdr.RFL); + return new AltitudeBlock(altitudeLower, altitudeUpper); + } + + private static int ExtractClearedOrRequestedValue(int clearedValue, int requestedValue) + { + return clearedValue == -1 ? requestedValue : clearedValue; + } +} \ No newline at end of file From 4e8dcc1b750d66ca0e2f1fb1d8062aaa8c527b21 Mon Sep 17 00:00:00 2001 From: Maxim Salikhov Date: Sun, 18 Feb 2024 16:59:51 -0500 Subject: [PATCH 43/76] Setup basic plugin dataflow --- AtopPlugin.cs | 50 ++++++++++++++++++++++++++ AuroraLabelItemsPlugin.csproj | 6 ++++ Constants.cs | 25 +++++++++++++ Display/LabelItem.cs | 6 ++++ Display/LabelItemRenderer.cs | 33 +++++++++++++++++ Display/StripItemRenderer.cs | 32 +++++++++++++++++ Display/TrackColorRenderer.cs | 33 +++++++++++++++++ Fdr/AltitudeFlag.cs | 8 ++--- Fdr/FdrManager.cs | 17 +++++++++ State/PrivateMessagesChangedHandler.cs | 13 +++++++ 10 files changed, 219 insertions(+), 4 deletions(-) create mode 100644 AtopPlugin.cs create mode 100644 Display/LabelItem.cs create mode 100644 Display/LabelItemRenderer.cs create mode 100644 Display/StripItemRenderer.cs create mode 100644 Display/TrackColorRenderer.cs create mode 100644 State/PrivateMessagesChangedHandler.cs diff --git a/AtopPlugin.cs b/AtopPlugin.cs new file mode 100644 index 0000000..97b67e3 --- /dev/null +++ b/AtopPlugin.cs @@ -0,0 +1,50 @@ +using System.ComponentModel.Composition; +using AuroraLabelItemsPlugin.Display; +using AuroraLabelItemsPlugin.Fdr; +using AuroraLabelItemsPlugin.State; +using vatsys; +using vatsys.Plugin; + +namespace AuroraLabelItemsPlugin; + +[Export(typeof(IPlugin))] +public class AtopPlugin : ILabelPlugin, IStripPlugin +{ + public string Name => "ATOP Plugin"; + + public AtopPlugin() + { + Network.PrivateMessagesChanged += PrivateMessagesChangedHandler.Handle; + } + + public void OnFDRUpdate(FDP2.FDR updated) + { + FdrManager.UpdateFdrState(updated); + } + + public void OnRadarTrackUpdate(RDP.RadarTrack updated) + { + } + + public CustomStripItem GetCustomStripItem(string itemType, Track track, FDP2.FDR flightDataRecord, + RDP.RadarTrack radarTrack) + { + return StripItemRenderer.RenderStripItem(itemType, track, flightDataRecord, radarTrack); + } + + public CustomLabelItem GetCustomLabelItem(string itemType, Track track, FDP2.FDR flightDataRecord, + RDP.RadarTrack radarTrack) + { + return LabelItemRenderer.RenderLabelItem(itemType, track, flightDataRecord, radarTrack); + } + + public CustomColour SelectASDTrackColour(Track track) + { + return TrackColorRenderer.GetAsdColor(track); + } + + public CustomColour SelectGroundTrackColour(Track track) + { + return null; + } +} \ No newline at end of file diff --git a/AuroraLabelItemsPlugin.csproj b/AuroraLabelItemsPlugin.csproj index 6707116..2019771 100644 --- a/AuroraLabelItemsPlugin.csproj +++ b/AuroraLabelItemsPlugin.csproj @@ -49,6 +49,7 @@ + @@ -56,6 +57,10 @@ + + + + @@ -70,6 +75,7 @@ + diff --git a/Constants.cs b/Constants.cs index 9a1e8d7..a42afb0 100644 --- a/Constants.cs +++ b/Constants.cs @@ -16,6 +16,31 @@ public static class CustomColors public static readonly CustomColour SpecialConditionCode = new CustomColour(255, 255, 0); public static readonly CustomColour ApsBlue = new CustomColour(141, 182, 205); } + + public static class Symbols + { + public const string NoCpdlcNoAdsb = "⎕"; + public const string CpdlcNoAdsb = "⧆"; + public const string CpdlcAndAdsb = "✱"; + + public const string D30 = "3"; + public const string D50 = "D"; + public const string T10 = "M"; + public const string Mnt = "R"; + public const string Rvsm = "W"; + + public const string CommDownlink = "▼"; + public const string CommEmpty = "⬜"; + + public const string RadarFlag = "★"; + public const string UntoggledFlag = "◦"; + + public const string Climbing = "↑"; + public const string Descending = "↓"; + public const string DeviatingAbove = "+"; + public const string DeviatingBelow = "-"; + + } public static class StripConstants { diff --git a/Display/LabelItem.cs b/Display/LabelItem.cs new file mode 100644 index 0000000..434a4e2 --- /dev/null +++ b/Display/LabelItem.cs @@ -0,0 +1,6 @@ +namespace AuroraLabelItemsPlugin.Display; + +public class LabelItem +{ + +} \ No newline at end of file diff --git a/Display/LabelItemRenderer.cs b/Display/LabelItemRenderer.cs new file mode 100644 index 0000000..d38c0f8 --- /dev/null +++ b/Display/LabelItemRenderer.cs @@ -0,0 +1,33 @@ +#nullable enable +using vatsys; +using vatsys.Plugin; + +namespace AuroraLabelItemsPlugin.Display; + +public static class LabelItemRenderer +{ + public static CustomLabelItem? RenderLabelItem(string itemType, Track track, FDP2.FDR fdr, RDP.RadarTrack radarTrack) + { + return itemType switch + { + LabelConstants.LabelItemSelectHori => null, + LabelConstants.LabelItemSelectVert => null, + LabelConstants.LabelItemCommIcon => null, + LabelConstants.LabelItemAdsbCpdlc => null, + LabelConstants.LabelItemAdsFlags => null, + LabelConstants.LabelItemMntFlags => null, + LabelConstants.LabelItemScc => null, + LabelConstants.LabelItemAnnotInd => null, + LabelConstants.LabelItemRestr => null, + LabelConstants.LabelItemLevel => null, + LabelConstants.LabelItemVmi => null, + LabelConstants.LabelItemClearedLevel => null, + LabelConstants.LabelItemRadarInd => null, + LabelConstants.LabelItemInhibitInd => null, + LabelConstants.LabelItemFiledSpeed => null, + LabelConstants.LabelItem3DigitGroundspeed => null, + LabelConstants.LabelItemDestination => null, + _ => null + }; + } +} \ No newline at end of file diff --git a/Display/StripItemRenderer.cs b/Display/StripItemRenderer.cs new file mode 100644 index 0000000..5c97a6d --- /dev/null +++ b/Display/StripItemRenderer.cs @@ -0,0 +1,32 @@ +using vatsys; +using vatsys.Plugin; + +namespace AuroraLabelItemsPlugin.Display; + +public static class StripItemRenderer +{ + public static CustomStripItem RenderStripItem(string itemType, Track track, FDP2.FDR fdr, RDP.RadarTrack radarTrack) + { + return itemType switch + { + StripConstants.StripItemCallsign => null, + StripConstants.StripItemCtlsector => null, + StripConstants.StripItemNxtsector => null, + StripConstants.LabelItemAdsbCpdlc => null, + StripConstants.StripItemT10Flag => null, + StripConstants.StripItemMntFlag => null, + StripConstants.StripItemDistFlag => null, + StripConstants.StripItemRvsmFlag => null, + StripConstants.StripItemVmi => null, + StripConstants.StripItemComplex => null, + StripConstants.StripItemClearedLevel => null, + StripConstants.StripItemRequestedLevel => null, + StripConstants.StripItemRoute => null, + StripConstants.StripItemRadarInd => null, + StripConstants.StripItemAnnotInd => null, + StripConstants.StripItemLateralFlag => null, + StripConstants.StripItemRestr => null, + _ => null + }; + } +} \ No newline at end of file diff --git a/Display/TrackColorRenderer.cs b/Display/TrackColorRenderer.cs new file mode 100644 index 0000000..71ae0d7 --- /dev/null +++ b/Display/TrackColorRenderer.cs @@ -0,0 +1,33 @@ +using AuroraLabelItemsPlugin.Fdr; +using vatsys; +using vatsys.Plugin; + +namespace AuroraLabelItemsPlugin.Display; + +public static class TrackColorRenderer +{ + public static CustomColour GetAsdColor(Track track) + { + var fdr = track.GetFDR(); + + if (fdr == null) return null; + + // TODO(msalikhov): render conflict color + return IsInJurisdiction(track) ? GetDirectionColour(fdr) : null; + } + + private static CustomColour GetDirectionColour(FDP2.FDR fdr) + { + return fdr.GetExtendedState().DirectionOfFlight switch + { + DirectionOfFlight.Eastbound => CustomColors.EastboundColour, + DirectionOfFlight.Westbound => CustomColors.WestboundColour, + _ => null + }; + } + + private static bool IsInJurisdiction(Track track) + { + return track.State == MMI.HMIStates.Jurisdiction; + } +} \ No newline at end of file diff --git a/Fdr/AltitudeFlag.cs b/Fdr/AltitudeFlag.cs index 0c58bd2..6e2c3cd 100644 --- a/Fdr/AltitudeFlag.cs +++ b/Fdr/AltitudeFlag.cs @@ -9,8 +9,8 @@ private AltitudeFlag(string value) public string Value { get; private set; } - public static AltitudeFlag Climbing => new("↑"); - public static AltitudeFlag Descending => new("↓"); - public static AltitudeFlag DeviatingAbove => new("+"); - public static AltitudeFlag DeviatingBelow => new("-"); + public static AltitudeFlag Climbing => new(Symbols.Climbing); + public static AltitudeFlag Descending => new(Symbols.Descending); + public static AltitudeFlag DeviatingAbove => new(Symbols.DeviatingAbove); + public static AltitudeFlag DeviatingBelow => new(Symbols.DeviatingBelow); } \ No newline at end of file diff --git a/Fdr/FdrManager.cs b/Fdr/FdrManager.cs index 32afb08..d5e0a28 100644 --- a/Fdr/FdrManager.cs +++ b/Fdr/FdrManager.cs @@ -1,9 +1,11 @@ using System.Collections.Concurrent; +using vatsys; namespace AuroraLabelItemsPlugin.Fdr; public static class FdrManager { + private static readonly ConcurrentDictionary ExtendedFdrStates = new(); public static ExtendedFdrState GetExtendedFdrState(string callsign) @@ -11,4 +13,19 @@ public static ExtendedFdrState GetExtendedFdrState(string callsign) var found = ExtendedFdrStates.TryGetValue(callsign, out var state); return found ? state : null; } + + public static void UpdateFdrState(FDP2.FDR updated) + { + var callsign = updated.Callsign; + var extendedFdrState = GetExtendedFdrState(callsign); + + if (extendedFdrState == null) + { + ExtendedFdrStates.TryAdd(callsign, new ExtendedFdrState(updated)); + } + else + { + extendedFdrState.UpdateFromFdr(updated); + } + } } \ No newline at end of file diff --git a/State/PrivateMessagesChangedHandler.cs b/State/PrivateMessagesChangedHandler.cs new file mode 100644 index 0000000..e16353e --- /dev/null +++ b/State/PrivateMessagesChangedHandler.cs @@ -0,0 +1,13 @@ +using AuroraLabelItemsPlugin.Fdr; +using vatsys; + +namespace AuroraLabelItemsPlugin.State; + +public static class PrivateMessagesChangedHandler +{ + public static void Handle(object sender, Network.GenericMessageEventArgs eventArgs) + { + var extendedFdrState = FdrManager.GetExtendedFdrState(eventArgs.Message.Address); + extendedFdrState.DownlinkIndicator = !eventArgs.Message.Sent; + } +} \ No newline at end of file From 8c171ce97b07029c336aac35675d51691fb15a9f Mon Sep 17 00:00:00 2001 From: Maxim Salikhov Date: Sun, 18 Feb 2024 17:11:06 -0500 Subject: [PATCH 44/76] Reorganize structure --- AtopPlugin.cs | 3 +- AuroraLabelItemsPlugin.csproj | 23 +++++++------- Conflict/MinimaCalculator.cs | 7 ++--- Display/LabelItem.cs | 6 ---- Display/TrackColorRenderer.cs | 4 +-- Extensions.cs | 17 ++++++++++ Fdr/FdrExtensions.cs | 16 ---------- Fdr/FdrManager.cs | 31 ------------------- Fdr/ParsedFdrFields.cs | 9 ------ {Fdr => Logic}/AltitudeCalculator.cs | 2 +- .../FlightDataCalculator.cs | 9 +++--- {Fdr => Logic}/SccFlagCalculator.cs | 5 +-- {Fdr => Models}/AltitudeFlag.cs | 2 +- Models/CalculatedFlightData.cs | 9 ++++++ {Conflict => Models}/ConflictType.cs | 2 +- {Fdr => Models}/DirectionOfFlight.cs | 2 +- {Fdr => Models}/SccFlag.cs | 2 +- .../AtopAircraftState.cs | 11 ++++--- State/AtopPluginStateManager.cs | 31 +++++++++++++++++++ State/PrivateMessagesChangedHandler.cs | 5 ++- 20 files changed, 95 insertions(+), 101 deletions(-) delete mode 100644 Display/LabelItem.cs create mode 100644 Extensions.cs delete mode 100644 Fdr/FdrExtensions.cs delete mode 100644 Fdr/FdrManager.cs delete mode 100644 Fdr/ParsedFdrFields.cs rename {Fdr => Logic}/AltitudeCalculator.cs (97%) rename Fdr/FdrParser.cs => Logic/FlightDataCalculator.cs (81%) rename {Fdr => Logic}/SccFlagCalculator.cs (83%) rename {Fdr => Models}/AltitudeFlag.cs (90%) create mode 100644 Models/CalculatedFlightData.cs rename {Conflict => Models}/ConflictType.cs (64%) rename {Fdr => Models}/DirectionOfFlight.cs (93%) rename {Fdr => Models}/SccFlag.cs (87%) rename Fdr/ExtendedFdrState.cs => State/AtopAircraftState.cs (81%) create mode 100644 State/AtopPluginStateManager.cs diff --git a/AtopPlugin.cs b/AtopPlugin.cs index 97b67e3..d68bfce 100644 --- a/AtopPlugin.cs +++ b/AtopPlugin.cs @@ -1,6 +1,5 @@ using System.ComponentModel.Composition; using AuroraLabelItemsPlugin.Display; -using AuroraLabelItemsPlugin.Fdr; using AuroraLabelItemsPlugin.State; using vatsys; using vatsys.Plugin; @@ -19,7 +18,7 @@ public AtopPlugin() public void OnFDRUpdate(FDP2.FDR updated) { - FdrManager.UpdateFdrState(updated); + AtopPluginStateManager.UpdateState(updated); } public void OnRadarTrackUpdate(RDP.RadarTrack updated) diff --git a/AuroraLabelItemsPlugin.csproj b/AuroraLabelItemsPlugin.csproj index 2019771..6675302 100644 --- a/AuroraLabelItemsPlugin.csproj +++ b/AuroraLabelItemsPlugin.csproj @@ -54,27 +54,26 @@ - - - - - - - - - - - - + + + + + + + + + + + diff --git a/Conflict/MinimaCalculator.cs b/Conflict/MinimaCalculator.cs index 2167b04..be743a4 100644 --- a/Conflict/MinimaCalculator.cs +++ b/Conflict/MinimaCalculator.cs @@ -1,5 +1,4 @@ using System; -using AuroraLabelItemsPlugin.Fdr; using AuroraLabelItemsPlugin.Models; using vatsys; @@ -83,17 +82,17 @@ public static TimeSpan GetLongitudinalTime(FDP2.FDR fdr1, FDP2.FDR fdr2) private static bool HasDatalink(FDP2.FDR fdr) { - return fdr.GetExtendedState().ParsedFdrFields is { Pbcs: true, Adsc: true, Cpdlc: true }; + return fdr.GetAtopState().CalculatedFlightData is { Pbcs: true, Adsc: true, Cpdlc: true }; } private static bool CanApplyRnp4(FDP2.FDR fdr) { - return HasDatalink(fdr) && fdr.GetExtendedState().ParsedFdrFields.Rnp4; + return HasDatalink(fdr) && fdr.GetAtopState().CalculatedFlightData.Rnp4; } private static bool CanApplyRnp10(FDP2.FDR fdr) { - return fdr.GetExtendedState().ParsedFdrFields is { Rnp10: true }; + return fdr.GetAtopState().CalculatedFlightData is { Rnp10: true }; } private static bool IsJet(FDP2.FDR fdr) diff --git a/Display/LabelItem.cs b/Display/LabelItem.cs deleted file mode 100644 index 434a4e2..0000000 --- a/Display/LabelItem.cs +++ /dev/null @@ -1,6 +0,0 @@ -namespace AuroraLabelItemsPlugin.Display; - -public class LabelItem -{ - -} \ No newline at end of file diff --git a/Display/TrackColorRenderer.cs b/Display/TrackColorRenderer.cs index 71ae0d7..5b72abe 100644 --- a/Display/TrackColorRenderer.cs +++ b/Display/TrackColorRenderer.cs @@ -1,4 +1,4 @@ -using AuroraLabelItemsPlugin.Fdr; +using AuroraLabelItemsPlugin.Models; using vatsys; using vatsys.Plugin; @@ -18,7 +18,7 @@ public static CustomColour GetAsdColor(Track track) private static CustomColour GetDirectionColour(FDP2.FDR fdr) { - return fdr.GetExtendedState().DirectionOfFlight switch + return fdr.GetAtopState().DirectionOfFlight switch { DirectionOfFlight.Eastbound => CustomColors.EastboundColour, DirectionOfFlight.Westbound => CustomColors.WestboundColour, diff --git a/Extensions.cs b/Extensions.cs new file mode 100644 index 0000000..5e9d5da --- /dev/null +++ b/Extensions.cs @@ -0,0 +1,17 @@ +using AuroraLabelItemsPlugin.State; +using vatsys; + +namespace AuroraLabelItemsPlugin; + +public static class Extensions +{ + public static AtopAircraftState GetAtopState(this FDP2.FDR fdr) + { + return AtopPluginStateManager.GetState(fdr.Callsign); + } + + public static int? GetTransponderCode(this FDP2.FDR fdr) + { + return fdr.CoupledTrack?.ActualAircraft.TransponderCode; + } +} \ No newline at end of file diff --git a/Fdr/FdrExtensions.cs b/Fdr/FdrExtensions.cs deleted file mode 100644 index a29648e..0000000 --- a/Fdr/FdrExtensions.cs +++ /dev/null @@ -1,16 +0,0 @@ -using vatsys; - -namespace AuroraLabelItemsPlugin.Fdr; - -public static class FdrExtensions -{ - public static ExtendedFdrState GetExtendedState(this FDP2.FDR fdr) - { - return FdrManager.GetExtendedFdrState(fdr.Callsign); - } - - public static int? GetTransponderCode(this FDP2.FDR fdr) - { - return fdr.CoupledTrack?.ActualAircraft.TransponderCode; - } -} \ No newline at end of file diff --git a/Fdr/FdrManager.cs b/Fdr/FdrManager.cs deleted file mode 100644 index d5e0a28..0000000 --- a/Fdr/FdrManager.cs +++ /dev/null @@ -1,31 +0,0 @@ -using System.Collections.Concurrent; -using vatsys; - -namespace AuroraLabelItemsPlugin.Fdr; - -public static class FdrManager -{ - - private static readonly ConcurrentDictionary ExtendedFdrStates = new(); - - public static ExtendedFdrState GetExtendedFdrState(string callsign) - { - var found = ExtendedFdrStates.TryGetValue(callsign, out var state); - return found ? state : null; - } - - public static void UpdateFdrState(FDP2.FDR updated) - { - var callsign = updated.Callsign; - var extendedFdrState = GetExtendedFdrState(callsign); - - if (extendedFdrState == null) - { - ExtendedFdrStates.TryAdd(callsign, new ExtendedFdrState(updated)); - } - else - { - extendedFdrState.UpdateFromFdr(updated); - } - } -} \ No newline at end of file diff --git a/Fdr/ParsedFdrFields.cs b/Fdr/ParsedFdrFields.cs deleted file mode 100644 index b91e70f..0000000 --- a/Fdr/ParsedFdrFields.cs +++ /dev/null @@ -1,9 +0,0 @@ -namespace AuroraLabelItemsPlugin.Fdr; - -public record struct ParsedFdrFields( - bool Rnp4, - bool Rnp10, - bool Cpdlc, - bool Adsc, - bool Pbcs -); \ No newline at end of file diff --git a/Fdr/AltitudeCalculator.cs b/Logic/AltitudeCalculator.cs similarity index 97% rename from Fdr/AltitudeCalculator.cs rename to Logic/AltitudeCalculator.cs index f7944f9..dd189ca 100644 --- a/Fdr/AltitudeCalculator.cs +++ b/Logic/AltitudeCalculator.cs @@ -2,7 +2,7 @@ using AuroraLabelItemsPlugin.Models; using vatsys; -namespace AuroraLabelItemsPlugin.Fdr; +namespace AuroraLabelItemsPlugin.Logic; public static class AltitudeCalculator { diff --git a/Fdr/FdrParser.cs b/Logic/FlightDataCalculator.cs similarity index 81% rename from Fdr/FdrParser.cs rename to Logic/FlightDataCalculator.cs index 276c777..f2ba69e 100644 --- a/Fdr/FdrParser.cs +++ b/Logic/FlightDataCalculator.cs @@ -1,10 +1,11 @@ using System.Linq; using System.Text.RegularExpressions; +using AuroraLabelItemsPlugin.Models; using vatsys; -namespace AuroraLabelItemsPlugin.Fdr; +namespace AuroraLabelItemsPlugin.Logic; -public static class FdrParser +public static class FlightDataCalculator { private const string Rnp10Pbn = "A1"; private const string Rnp4Pbn = "L1"; @@ -20,7 +21,7 @@ public static class FdrParser "J5", "J7" }; - public static ParsedFdrFields ParseFdrFields(FDP2.FDR fdr) + public static CalculatedFlightData GetCalculatedFlightData(FDP2.FDR fdr) { // TODO(msalikhov): can we pull from fdr.PBNCapability var pbn = Regex.Match(fdr.Remarks, @"PBN\/\w+\s").Value; @@ -28,7 +29,7 @@ public static ParsedFdrFields ParseFdrFields(FDP2.FDR fdr) var isPbn = fdr.AircraftEquip.Contains(PbnEquip); - return new ParsedFdrFields( + return new CalculatedFlightData( isPbn && pbn.Contains(Rnp4Pbn), isPbn && pbn.Contains(Rnp10Pbn), CpdlcEquip.Any(cpdlcVal => fdr.AircraftEquip.Contains(cpdlcVal)), diff --git a/Fdr/SccFlagCalculator.cs b/Logic/SccFlagCalculator.cs similarity index 83% rename from Fdr/SccFlagCalculator.cs rename to Logic/SccFlagCalculator.cs index 741d7b2..2820590 100644 --- a/Fdr/SccFlagCalculator.cs +++ b/Logic/SccFlagCalculator.cs @@ -1,7 +1,8 @@ #nullable enable +using AuroraLabelItemsPlugin.Models; using vatsys; -namespace AuroraLabelItemsPlugin.Fdr; +namespace AuroraLabelItemsPlugin.Logic; public static class SccFlagCalculator { @@ -11,7 +12,7 @@ public static class SccFlagCalculator public static SccFlag? CalculateHighestPriorityFlag(FDP2.FDR fdr) { - var parsedFdrFields = fdr.GetExtendedState().ParsedFdrFields; + var parsedFdrFields = fdr.GetAtopState().CalculatedFlightData; var transponderCode = fdr.GetTransponderCode(); switch (transponderCode) diff --git a/Fdr/AltitudeFlag.cs b/Models/AltitudeFlag.cs similarity index 90% rename from Fdr/AltitudeFlag.cs rename to Models/AltitudeFlag.cs index 6e2c3cd..f883fd9 100644 --- a/Fdr/AltitudeFlag.cs +++ b/Models/AltitudeFlag.cs @@ -1,4 +1,4 @@ -namespace AuroraLabelItemsPlugin.Fdr; +namespace AuroraLabelItemsPlugin.Models; public class AltitudeFlag { diff --git a/Models/CalculatedFlightData.cs b/Models/CalculatedFlightData.cs new file mode 100644 index 0000000..95a2a91 --- /dev/null +++ b/Models/CalculatedFlightData.cs @@ -0,0 +1,9 @@ +namespace AuroraLabelItemsPlugin.Models; + +public record struct CalculatedFlightData( + bool Rnp4, + bool Rnp10, + bool Cpdlc, + bool Adsc, + bool Pbcs +); \ No newline at end of file diff --git a/Conflict/ConflictType.cs b/Models/ConflictType.cs similarity index 64% rename from Conflict/ConflictType.cs rename to Models/ConflictType.cs index 6c26180..35f9a2d 100644 --- a/Conflict/ConflictType.cs +++ b/Models/ConflictType.cs @@ -1,4 +1,4 @@ -namespace AuroraLabelItemsPlugin.Conflict; +namespace AuroraLabelItemsPlugin.Models; public enum ConflictType { diff --git a/Fdr/DirectionOfFlight.cs b/Models/DirectionOfFlight.cs similarity index 93% rename from Fdr/DirectionOfFlight.cs rename to Models/DirectionOfFlight.cs index 3ac727b..d6c6178 100644 --- a/Fdr/DirectionOfFlight.cs +++ b/Models/DirectionOfFlight.cs @@ -1,6 +1,6 @@ using vatsys; -namespace AuroraLabelItemsPlugin.Fdr; +namespace AuroraLabelItemsPlugin.Models; public enum DirectionOfFlight { diff --git a/Fdr/SccFlag.cs b/Models/SccFlag.cs similarity index 87% rename from Fdr/SccFlag.cs rename to Models/SccFlag.cs index b8598d7..ad484d7 100644 --- a/Fdr/SccFlag.cs +++ b/Models/SccFlag.cs @@ -1,4 +1,4 @@ -namespace AuroraLabelItemsPlugin.Fdr; +namespace AuroraLabelItemsPlugin.Models; public class SccFlag { diff --git a/Fdr/ExtendedFdrState.cs b/State/AtopAircraftState.cs similarity index 81% rename from Fdr/ExtendedFdrState.cs rename to State/AtopAircraftState.cs index 00aa6d7..7e04681 100644 --- a/Fdr/ExtendedFdrState.cs +++ b/State/AtopAircraftState.cs @@ -1,19 +1,20 @@ #nullable enable +using AuroraLabelItemsPlugin.Logic; using AuroraLabelItemsPlugin.Models; using vatsys; -namespace AuroraLabelItemsPlugin.Fdr; +namespace AuroraLabelItemsPlugin.State; -public class ExtendedFdrState +public class AtopAircraftState { - public ExtendedFdrState(FDP2.FDR fdr) + public AtopAircraftState(FDP2.FDR fdr) { UpdateFromFdr(fdr); DownlinkIndicator = false; RadarToggleIndicator = false; } - public ParsedFdrFields ParsedFdrFields { get; private set; } + public CalculatedFlightData CalculatedFlightData { get; private set; } public DirectionOfFlight DirectionOfFlight { get; private set; } public SccFlag? HighestSccFlag { get; private set; } public AltitudeFlag? AltitudeFlag { get; private set; } @@ -25,7 +26,7 @@ public ExtendedFdrState(FDP2.FDR fdr) public void UpdateFromFdr(FDP2.FDR updatedFdr) { - ParsedFdrFields = FdrParser.ParseFdrFields(updatedFdr); + CalculatedFlightData = FlightDataCalculator.GetCalculatedFlightData(updatedFdr); DirectionOfFlight = DirectionOfFlightCalculator.GetDirectionOfFlight(updatedFdr); HighestSccFlag = SccFlagCalculator.CalculateHighestPriorityFlag(updatedFdr); diff --git a/State/AtopPluginStateManager.cs b/State/AtopPluginStateManager.cs new file mode 100644 index 0000000..c039d1d --- /dev/null +++ b/State/AtopPluginStateManager.cs @@ -0,0 +1,31 @@ +using System.Collections.Concurrent; +using vatsys; + +namespace AuroraLabelItemsPlugin.State; + +public static class AtopPluginStateManager +{ + + private static readonly ConcurrentDictionary ExtendedFdrStates = new(); + + public static AtopAircraftState GetState(string callsign) + { + var found = ExtendedFdrStates.TryGetValue(callsign, out var state); + return found ? state : null; + } + + public static void UpdateState(FDP2.FDR updated) + { + var callsign = updated.Callsign; + var extendedFdrState = GetState(callsign); + + if (extendedFdrState == null) + { + ExtendedFdrStates.TryAdd(callsign, new AtopAircraftState(updated)); + } + else + { + extendedFdrState.UpdateFromFdr(updated); + } + } +} \ No newline at end of file diff --git a/State/PrivateMessagesChangedHandler.cs b/State/PrivateMessagesChangedHandler.cs index e16353e..a0c26e4 100644 --- a/State/PrivateMessagesChangedHandler.cs +++ b/State/PrivateMessagesChangedHandler.cs @@ -1,5 +1,4 @@ -using AuroraLabelItemsPlugin.Fdr; -using vatsys; +using vatsys; namespace AuroraLabelItemsPlugin.State; @@ -7,7 +6,7 @@ public static class PrivateMessagesChangedHandler { public static void Handle(object sender, Network.GenericMessageEventArgs eventArgs) { - var extendedFdrState = FdrManager.GetExtendedFdrState(eventArgs.Message.Address); + var extendedFdrState = AtopPluginStateManager.GetState(eventArgs.Message.Address); extendedFdrState.DownlinkIndicator = !eventArgs.Message.Sent; } } \ No newline at end of file From 769edfe35e32e0396b912b29e11da26940431faf Mon Sep 17 00:00:00 2001 From: Maxim Salikhov Date: Sun, 18 Feb 2024 17:53:57 -0500 Subject: [PATCH 45/76] Implement basic label rendering --- AuroraLabelItemsPlugin.csproj | 1 + Constants.cs | 3 ++ Display/LabelItemRenderer.cs | 53 ++++++++++++++++++++++++++++----- Extensions.cs | 5 ++++ State/AtopAircraftState.cs | 4 +-- State/RadarFlagToggleHandler.cs | 13 ++++++++ 6 files changed, 69 insertions(+), 10 deletions(-) create mode 100644 State/RadarFlagToggleHandler.cs diff --git a/AuroraLabelItemsPlugin.csproj b/AuroraLabelItemsPlugin.csproj index 6675302..1797300 100644 --- a/AuroraLabelItemsPlugin.csproj +++ b/AuroraLabelItemsPlugin.csproj @@ -75,6 +75,7 @@ + diff --git a/Constants.cs b/Constants.cs index a42afb0..3210830 100644 --- a/Constants.cs +++ b/Constants.cs @@ -19,6 +19,8 @@ public static class CustomColors public static class Symbols { + public const string Empty = ""; + public const string NoCpdlcNoAdsb = "⎕"; public const string CpdlcNoAdsb = "⧆"; public const string CpdlcAndAdsb = "✱"; @@ -40,6 +42,7 @@ public static class Symbols public const string DeviatingAbove = "+"; public const string DeviatingBelow = "-"; + public const string Inhibited = "^"; } public static class StripConstants diff --git a/Display/LabelItemRenderer.cs b/Display/LabelItemRenderer.cs index d38c0f8..70cddef 100644 --- a/Display/LabelItemRenderer.cs +++ b/Display/LabelItemRenderer.cs @@ -1,4 +1,5 @@ #nullable enable +using AuroraLabelItemsPlugin.State; using vatsys; using vatsys.Plugin; @@ -6,27 +7,63 @@ namespace AuroraLabelItemsPlugin.Display; public static class LabelItemRenderer { - public static CustomLabelItem? RenderLabelItem(string itemType, Track track, FDP2.FDR fdr, RDP.RadarTrack radarTrack) + public static CustomLabelItem? RenderLabelItem(string itemType, Track track, FDP2.FDR? fdr, + RDP.RadarTrack _) { + if (fdr == null) return null; + return itemType switch { - LabelConstants.LabelItemSelectHori => null, - LabelConstants.LabelItemSelectVert => null, - LabelConstants.LabelItemCommIcon => null, + LabelConstants.LabelItemSelectHori => track.IsSelected() + ? new CustomLabelItem() { Text = Symbols.Empty, Border = BorderFlags.Bottom } + : null, + + LabelConstants.LabelItemSelectVert => track.IsSelected() + ? new CustomLabelItem() { Text = Symbols.Empty, Border = BorderFlags.Left } + : null, + + LabelConstants.LabelItemCommIcon => fdr.GetAtopState().DownlinkIndicator + ? new CustomLabelItem() { Text = Symbols.CommDownlink, Border = BorderFlags.All } + : new CustomLabelItem() { Text = Symbols.CommEmpty }, + LabelConstants.LabelItemAdsbCpdlc => null, + LabelConstants.LabelItemAdsFlags => null, + LabelConstants.LabelItemMntFlags => null, - LabelConstants.LabelItemScc => null, + + LabelConstants.LabelItemScc => fdr.GetAtopState().HighestSccFlag != null + ? new CustomLabelItem() + { + Text = fdr.GetAtopState().HighestSccFlag!.Value, ForeColourIdentity = Colours.Identities.Custom, + CustomForeColour = CustomColors.SpecialConditionCode + } + : null, + LabelConstants.LabelItemAnnotInd => null, + LabelConstants.LabelItemRestr => null, + LabelConstants.LabelItemLevel => null, + LabelConstants.LabelItemVmi => null, + LabelConstants.LabelItemClearedLevel => null, - LabelConstants.LabelItemRadarInd => null, - LabelConstants.LabelItemInhibitInd => null, + + LabelConstants.LabelItemRadarInd => fdr.GetAtopState().RadarToggleIndicator + ? new CustomLabelItem() { Text = Symbols.RadarFlag, OnMouseClick = RadarFlagToggleHandler.Handle } + : new CustomLabelItem() { Text = Symbols.UntoggledFlag, OnMouseClick = RadarFlagToggleHandler.Handle }, + + LabelConstants.LabelItemInhibitInd => fdr.State == FDP2.FDR.FDRStates.STATE_INHIBITED + ? new CustomLabelItem() { Text = Symbols.Inhibited } + : null, + LabelConstants.LabelItemFiledSpeed => null, + LabelConstants.LabelItem3DigitGroundspeed => null, - LabelConstants.LabelItemDestination => null, + + LabelConstants.LabelItemDestination => new CustomLabelItem() { Text = fdr.DesAirport }, + _ => null }; } diff --git a/Extensions.cs b/Extensions.cs index 5e9d5da..bff6742 100644 --- a/Extensions.cs +++ b/Extensions.cs @@ -14,4 +14,9 @@ public static AtopAircraftState GetAtopState(this FDP2.FDR fdr) { return fdr.CoupledTrack?.ActualAircraft.TransponderCode; } + + public static bool IsSelected(this Track track) + { + return MMI.SelectedTrack == track; + } } \ No newline at end of file diff --git a/State/AtopAircraftState.cs b/State/AtopAircraftState.cs index 7e04681..3353539 100644 --- a/State/AtopAircraftState.cs +++ b/State/AtopAircraftState.cs @@ -20,8 +20,8 @@ public AtopAircraftState(FDP2.FDR fdr) public AltitudeFlag? AltitudeFlag { get; private set; } public bool DownlinkIndicator { get; set; } public bool RadarToggleIndicator { get; set; } - - private bool PendingAltitudeChange { get; set; } + public bool PendingAltitudeChange { get; private set; } + private AltitudeBlock PreviousAltitudeBlock { get; set; } public void UpdateFromFdr(FDP2.FDR updatedFdr) diff --git a/State/RadarFlagToggleHandler.cs b/State/RadarFlagToggleHandler.cs new file mode 100644 index 0000000..ad19cbf --- /dev/null +++ b/State/RadarFlagToggleHandler.cs @@ -0,0 +1,13 @@ +using vatsys.Plugin; + +namespace AuroraLabelItemsPlugin.State; + +public static class RadarFlagToggleHandler +{ + public static void Handle(CustomLabelItemMouseClickEventArgs eventArgs) + { + var atopState = eventArgs.Track.GetFDR().GetAtopState(); + atopState.RadarToggleIndicator = !atopState.RadarToggleIndicator; + eventArgs.Handled = true; + } +} \ No newline at end of file From 641c279727c0d002968f91bcec1f4cc1f981673a Mon Sep 17 00:00:00 2001 From: Maxim Salikhov Date: Sun, 18 Feb 2024 18:21:56 -0500 Subject: [PATCH 46/76] Implement basic strip rendering --- Display/LabelItemRenderer.cs | 18 ++++---- Display/StripItemRenderer.cs | 83 +++++++++++++++++++++++++++++++++--- 2 files changed, 85 insertions(+), 16 deletions(-) diff --git a/Display/LabelItemRenderer.cs b/Display/LabelItemRenderer.cs index 70cddef..0857ab4 100644 --- a/Display/LabelItemRenderer.cs +++ b/Display/LabelItemRenderer.cs @@ -15,16 +15,16 @@ public static class LabelItemRenderer return itemType switch { LabelConstants.LabelItemSelectHori => track.IsSelected() - ? new CustomLabelItem() { Text = Symbols.Empty, Border = BorderFlags.Bottom } + ? new CustomLabelItem { Text = Symbols.Empty, Border = BorderFlags.Bottom } : null, LabelConstants.LabelItemSelectVert => track.IsSelected() - ? new CustomLabelItem() { Text = Symbols.Empty, Border = BorderFlags.Left } + ? new CustomLabelItem { Text = Symbols.Empty, Border = BorderFlags.Left } : null, LabelConstants.LabelItemCommIcon => fdr.GetAtopState().DownlinkIndicator - ? new CustomLabelItem() { Text = Symbols.CommDownlink, Border = BorderFlags.All } - : new CustomLabelItem() { Text = Symbols.CommEmpty }, + ? new CustomLabelItem { Text = Symbols.CommDownlink, Border = BorderFlags.All } + : new CustomLabelItem { Text = Symbols.CommEmpty }, LabelConstants.LabelItemAdsbCpdlc => null, @@ -33,7 +33,7 @@ public static class LabelItemRenderer LabelConstants.LabelItemMntFlags => null, LabelConstants.LabelItemScc => fdr.GetAtopState().HighestSccFlag != null - ? new CustomLabelItem() + ? new CustomLabelItem { Text = fdr.GetAtopState().HighestSccFlag!.Value, ForeColourIdentity = Colours.Identities.Custom, CustomForeColour = CustomColors.SpecialConditionCode @@ -51,18 +51,18 @@ public static class LabelItemRenderer LabelConstants.LabelItemClearedLevel => null, LabelConstants.LabelItemRadarInd => fdr.GetAtopState().RadarToggleIndicator - ? new CustomLabelItem() { Text = Symbols.RadarFlag, OnMouseClick = RadarFlagToggleHandler.Handle } - : new CustomLabelItem() { Text = Symbols.UntoggledFlag, OnMouseClick = RadarFlagToggleHandler.Handle }, + ? new CustomLabelItem { Text = Symbols.RadarFlag, OnMouseClick = RadarFlagToggleHandler.Handle } + : new CustomLabelItem { Text = Symbols.UntoggledFlag, OnMouseClick = RadarFlagToggleHandler.Handle }, LabelConstants.LabelItemInhibitInd => fdr.State == FDP2.FDR.FDRStates.STATE_INHIBITED - ? new CustomLabelItem() { Text = Symbols.Inhibited } + ? new CustomLabelItem { Text = Symbols.Inhibited } : null, LabelConstants.LabelItemFiledSpeed => null, LabelConstants.LabelItem3DigitGroundspeed => null, - LabelConstants.LabelItemDestination => new CustomLabelItem() { Text = fdr.DesAirport }, + LabelConstants.LabelItemDestination => new CustomLabelItem { Text = fdr.DesAirport }, _ => null }; diff --git a/Display/StripItemRenderer.cs b/Display/StripItemRenderer.cs index 5c97a6d..aa557fe 100644 --- a/Display/StripItemRenderer.cs +++ b/Display/StripItemRenderer.cs @@ -1,32 +1,101 @@ -using vatsys; +#nullable enable +using AuroraLabelItemsPlugin.Models; +using vatsys; using vatsys.Plugin; namespace AuroraLabelItemsPlugin.Display; public static class StripItemRenderer { - public static CustomStripItem RenderStripItem(string itemType, Track track, FDP2.FDR fdr, RDP.RadarTrack radarTrack) + public static CustomStripItem? RenderStripItem(string itemType, Track track, FDP2.FDR? fdr, + RDP.RadarTrack radarTrack) { + if (fdr == null) return null; + return itemType switch { - StripConstants.StripItemCallsign => null, - StripConstants.StripItemCtlsector => null, + StripConstants.StripItemCallsign => RenderCallsignStripItem(fdr), + StripConstants.StripItemCtlsector => RenderCtlSectorStripItem(fdr), StripConstants.StripItemNxtsector => null, + StripConstants.LabelItemAdsbCpdlc => null, - StripConstants.StripItemT10Flag => null, - StripConstants.StripItemMntFlag => null, + + StripConstants.StripItemT10Flag => fdr.PerformanceData.IsJet + ? new CustomStripItem { Text = Symbols.T10 } + : null, + + StripConstants.StripItemMntFlag => fdr.PerformanceData.IsJet + ? new CustomStripItem { Text = Symbols.Mnt } + : null, + StripConstants.StripItemDistFlag => null, - StripConstants.StripItemRvsmFlag => null, + + StripConstants.StripItemRvsmFlag => fdr.RVSM + ? new CustomStripItem + { + Text = Symbols.Rvsm, BackColourIdentity = Colours.Identities.Custom, + CustomBackColour = CustomColors.SepFlags, + } + : null, + StripConstants.StripItemVmi => null, + StripConstants.StripItemComplex => null, + StripConstants.StripItemClearedLevel => null, + StripConstants.StripItemRequestedLevel => null, + StripConstants.StripItemRoute => null, + StripConstants.StripItemRadarInd => null, + StripConstants.StripItemAnnotInd => null, + StripConstants.StripItemLateralFlag => null, + StripConstants.StripItemRestr => null, + _ => null }; } + + private static CustomStripItem RenderCallsignStripItem(FDP2.FDR fdr) + { + var stripItem = GetStripItemWithColorsForDirection(fdr.GetAtopState().DirectionOfFlight); + stripItem.Text = fdr.Callsign; + return stripItem; + } + + private static CustomStripItem RenderCtlSectorStripItem(FDP2.FDR fdr) + { + var pendingCoordination = + fdr.State is FDP2.FDR.FDRStates.STATE_PREACTIVE or FDP2.FDR.FDRStates.STATE_COORDINATED; + var sectorName = fdr.ControllingSector?.Name ?? Symbols.Empty; + + var stripItem = new CustomStripItem { Text = sectorName }; + + if (pendingCoordination) + { + stripItem.ForeColourIdentity = Colours.Identities.Custom; + stripItem.CustomForeColour = CustomColors.Pending; + } + + return stripItem; + } + + private static CustomStripItem GetStripItemWithColorsForDirection(DirectionOfFlight directionOfFlight) + { + var foreColorIdentity = directionOfFlight == DirectionOfFlight.Eastbound + ? Colours.Identities.StripBackground + : Colours.Identities.StripText; + var backColorIdentity = directionOfFlight == DirectionOfFlight.Eastbound + ? Colours.Identities.StripText + : Colours.Identities.StripBackground; + return new CustomStripItem + { + ForeColourIdentity = foreColorIdentity, + BackColourIdentity = backColorIdentity + }; + } } \ No newline at end of file From 9039ff7e123a413bbdd879294bf68f7e91cb1eb8 Mon Sep 17 00:00:00 2001 From: Maxim Salikhov Date: Sat, 24 Feb 2024 16:30:01 -0500 Subject: [PATCH 47/76] Setup basic auto-assume/drop --- AtopPlugin.cs | 1 + AuroraLabelItemsPlugin.csproj | 1 + State/AtopAircraftState.cs | 4 +++- State/JurisdictionManager.cs | 26 ++++++++++++++++++++++++++ 4 files changed, 31 insertions(+), 1 deletion(-) create mode 100644 State/JurisdictionManager.cs diff --git a/AtopPlugin.cs b/AtopPlugin.cs index d68bfce..988bbe8 100644 --- a/AtopPlugin.cs +++ b/AtopPlugin.cs @@ -19,6 +19,7 @@ public AtopPlugin() public void OnFDRUpdate(FDP2.FDR updated) { AtopPluginStateManager.UpdateState(updated); + JurisdictionManager.HandleFdrUpdate(updated); } public void OnRadarTrackUpdate(RDP.RadarTrack updated) diff --git a/AuroraLabelItemsPlugin.csproj b/AuroraLabelItemsPlugin.csproj index 1797300..3222b71 100644 --- a/AuroraLabelItemsPlugin.csproj +++ b/AuroraLabelItemsPlugin.csproj @@ -74,6 +74,7 @@ + diff --git a/State/AtopAircraftState.cs b/State/AtopAircraftState.cs index 3353539..74fb9dc 100644 --- a/State/AtopAircraftState.cs +++ b/State/AtopAircraftState.cs @@ -12,6 +12,7 @@ public AtopAircraftState(FDP2.FDR fdr) UpdateFromFdr(fdr); DownlinkIndicator = false; RadarToggleIndicator = false; + PreviouslyTracked = false; } public CalculatedFlightData CalculatedFlightData { get; private set; } @@ -20,8 +21,9 @@ public AtopAircraftState(FDP2.FDR fdr) public AltitudeFlag? AltitudeFlag { get; private set; } public bool DownlinkIndicator { get; set; } public bool RadarToggleIndicator { get; set; } + public bool PreviouslyTracked { get; set; } public bool PendingAltitudeChange { get; private set; } - + private AltitudeBlock PreviousAltitudeBlock { get; set; } public void UpdateFromFdr(FDP2.FDR updatedFdr) diff --git a/State/JurisdictionManager.cs b/State/JurisdictionManager.cs new file mode 100644 index 0000000..4acda2e --- /dev/null +++ b/State/JurisdictionManager.cs @@ -0,0 +1,26 @@ +using System.Linq; +using vatsys; + +namespace AuroraLabelItemsPlugin.State; + +public static class JurisdictionManager +{ + public static void HandleFdrUpdate(FDP2.FDR fdr) + { + var isInSector = MMI.SectorsControlled.ToList().Exists(sector => sector.IsInSector(fdr.GetLocation(), fdr.PRL)); + + switch (isInSector) + { + // check if aircraft previously tracked to avoid re-tracking manually dropped/handed off tracks + case true when !fdr.IsTracked && !fdr.GetAtopState().PreviouslyTracked: + MMI.AcceptJurisdiction(fdr); + fdr.GetAtopState().PreviouslyTracked = true; + break; + + // if they're outside sector and currently, tracked, drop them + case false when fdr.IsTrackedByMe: + MMI.HandoffToNone(fdr); + break; + } + } +} \ No newline at end of file From 5e213b9db88e34388a4978def4aa0814b3a12d00 Mon Sep 17 00:00:00 2001 From: Maxim Salikhov Date: Sat, 24 Feb 2024 16:33:54 -0500 Subject: [PATCH 48/76] Remove plugin state when FDR purged --- AtopPlugin.cs | 2 +- State/AtopPluginStateManager.cs | 11 ++++++++++- 2 files changed, 11 insertions(+), 2 deletions(-) diff --git a/AtopPlugin.cs b/AtopPlugin.cs index 988bbe8..d6a0021 100644 --- a/AtopPlugin.cs +++ b/AtopPlugin.cs @@ -18,7 +18,7 @@ public AtopPlugin() public void OnFDRUpdate(FDP2.FDR updated) { - AtopPluginStateManager.UpdateState(updated); + AtopPluginStateManager.ProcessStateUpdate(updated); JurisdictionManager.HandleFdrUpdate(updated); } diff --git a/State/AtopPluginStateManager.cs b/State/AtopPluginStateManager.cs index c039d1d..9bdd2aa 100644 --- a/State/AtopPluginStateManager.cs +++ b/State/AtopPluginStateManager.cs @@ -5,6 +5,8 @@ namespace AuroraLabelItemsPlugin.State; public static class AtopPluginStateManager { + + private const int MissingFromFdpState = -1; private static readonly ConcurrentDictionary ExtendedFdrStates = new(); @@ -14,9 +16,16 @@ public static AtopAircraftState GetState(string callsign) return found ? state : null; } - public static void UpdateState(FDP2.FDR updated) + public static void ProcessStateUpdate(FDP2.FDR updated) { var callsign = updated.Callsign; + + if (FDP2.GetFDRIndex(callsign) == MissingFromFdpState) + { + ExtendedFdrStates.TryRemove(callsign, out _); + return; + } + var extendedFdrState = GetState(callsign); if (extendedFdrState == null) From 4a135f8734ddf235542b53133012fb963ddc4056 Mon Sep 17 00:00:00 2001 From: Maxim Salikhov Date: Sun, 25 Feb 2024 00:06:14 -0500 Subject: [PATCH 49/76] Finish label rendering logic --- AuroraLabelItemsPlugin.csproj | 47 +++--- Constants.cs | 202 +++++++++++++------------ Display/LabelItemRenderer.cs | 78 ++++++++-- Extensions.cs | 7 +- Logic/AltitudeCalculator.cs | 2 +- Models/AltitudeBlock.cs | 14 +- State/AtopAircraftDisplayState.cs | 112 ++++++++++++++ State/AtopAircraftState.cs | 4 + State/AtopPluginStateManager.cs | 38 +++-- State/PrivateMessagesChangedHandler.cs | 2 +- 10 files changed, 348 insertions(+), 158 deletions(-) create mode 100644 State/AtopAircraftDisplayState.cs diff --git a/AuroraLabelItemsPlugin.csproj b/AuroraLabelItemsPlugin.csproj index 3222b71..170c050 100644 --- a/AuroraLabelItemsPlugin.csproj +++ b/AuroraLabelItemsPlugin.csproj @@ -49,34 +49,35 @@ - + - - - - - - - - + + + + + + + + - - - - - - - - - + + + + + + + + + - - - - - + + + + + + diff --git a/Constants.cs b/Constants.cs index 3210830..a639ecc 100644 --- a/Constants.cs +++ b/Constants.cs @@ -1,111 +1,113 @@ using vatsys.Plugin; -namespace AuroraLabelItemsPlugin +namespace AuroraLabelItemsPlugin; + +public static class CustomColors +{ + public static readonly CustomColour SepFlags = new(0, 196, 253); + public static readonly CustomColour Pending = new(46, 139, 87); + public static readonly CustomColour EastboundColour = new(240, 255, 255); + public static readonly CustomColour WestboundColour = new(240, 231, 140); + public static readonly CustomColour NonRvsm = new(242, 133, 0); + public static readonly CustomColour Probe = new(0, 255, 0); + public static readonly CustomColour NotCda = new(100, 0, 100); + public static readonly CustomColour Advisory = new(255, 165, 0); + public static readonly CustomColour Imminent = new(255, 0, 0); + public static readonly CustomColour SpecialConditionCode = new(255, 255, 0); + public static readonly CustomColour ApsBlue = new(141, 182, 205); +} + +public static class Symbols { - public static class CustomColors - { - public static readonly CustomColour SepFlags = new CustomColour(0, 196, 253); - public static readonly CustomColour Pending = new CustomColour(46, 139, 87); - public static readonly CustomColour EastboundColour = new CustomColour(240, 255, 255); - public static readonly CustomColour WestboundColour = new CustomColour(240, 231, 140); - public static readonly CustomColour NonRvsm = new CustomColour(242, 133, 0); - public static readonly CustomColour Probe = new CustomColour(0, 255, 0); - public static readonly CustomColour NotCda = new CustomColour(100, 0, 100); - public static readonly CustomColour Advisory = new CustomColour(255, 165, 0); - public static readonly CustomColour Imminent = new CustomColour(255, 0, 0); - public static readonly CustomColour SpecialConditionCode = new CustomColour(255, 255, 0); - public static readonly CustomColour ApsBlue = new CustomColour(141, 182, 205); - } + public const string Empty = ""; - public static class Symbols - { - public const string Empty = ""; - - public const string NoCpdlcNoAdsb = "⎕"; - public const string CpdlcNoAdsb = "⧆"; - public const string CpdlcAndAdsb = "✱"; + public const string NoCpdlcNoAdsb = "⎕"; + public const string CpdlcNoAdsb = "⧆"; + public const string CpdlcAndAdsb = "✱"; - public const string D30 = "3"; - public const string D50 = "D"; - public const string T10 = "M"; - public const string Mnt = "R"; - public const string Rvsm = "W"; + public const string D30 = "3"; + public const string D50 = "D"; + public const string T10 = "M"; + public const string Mnt = "R"; + public const string Rvsm = "W"; - public const string CommDownlink = "▼"; - public const string CommEmpty = "⬜"; + public const string CommDownlink = "▼"; + public const string CommEmpty = "⬜"; - public const string RadarFlag = "★"; - public const string UntoggledFlag = "◦"; + public const string RadarFlag = "★"; + public const string UntoggledFlag = "◦"; + public const string ScratchpadFlag = "&"; + public const string MntFlag = "M"; + public const string RestrictionsFlag = "x"; - public const string Climbing = "↑"; - public const string Descending = "↓"; - public const string DeviatingAbove = "+"; - public const string DeviatingBelow = "-"; + public const string Climbing = "↑"; + public const string Descending = "↓"; + public const string DeviatingAbove = "+"; + public const string DeviatingBelow = "-"; - public const string Inhibited = "^"; - } - - public static class StripConstants - { - public const string LabelItemAdsbCpdlc = "AURORA_ADSB_CPDLC"; //field c(4) - public const string StripItemCallsign = "AURORA_CALLSIGN"; - public const string StripItemCtlsector = "AURORA_CDA"; - public const string StripItemNxtsector = "AURORA_NDA"; - public const string StripItemT10Flag = "AURORA_T10_FLAG"; - public const string StripItemMntFlag = "AURORA_MNT_FLAG"; - public const string StripItemDistFlag = "AURORA_DIST_FLAG"; - public const string StripItemRvsmFlag = "AURORA_RVSM_FLAG"; - public const string StripItemVmi = "AURORA_STRIP_VMI"; - public const string StripItemComplex = "AURORA_STRIP_COMPLEX"; - public const string StripItemClearedLevel = "AURORA_CLEARED_LEVEL"; - public const string StripItemRequestedLevel = "AURORA_REQUESTED_LEVEL"; - public const string StripItemManEst = "AURORA_MAN_EST"; - public const string StripItemPoint = "AURORA_POINT"; - public const string StripItemRoute = "AURORA_ROUTE_STRIP"; - public const string StripItemRadarInd = "AURORA_RADAR_IND"; - public const string StripItemAnnotInd = "AURORA_ANNOT_STRIP"; - public const string StripItemLateralFlag = "AURORA_LATERAL_FLAG"; - public const string StripItemRestr = "AURORA_RESTR_STRIP"; - public const string StripItemClrdRte = "AURORA_CLRD_RTE"; - public const string CparItemType = "CPAR_TYP"; - public const string CparItemRequired = "CPAR_REQUIRED"; - public const string CparItemIntruder = "CPAR_INT"; - public const string CparItemLos = "CPAR_LOS"; - public const string CparItemActual = "CPAR_ACTUAL"; - public const string CparItemPassing = "CPAR_PASSING"; - public const string CparItemConfSegStart1 = "CPAR_CONF_SEG_START_1"; - public const string CparItemConfSegStart2 = "CPAR_CONF_SEG_START_2"; - public const string CparItemConfSegEnd1 = "CPAR_CONF_SEG_END_1"; - public const string CparItemConfSegEnd2 = "CPAR_CONF_SEG_END_2"; - public const string CparItemStartime1 = "CPAR_START_TIME_1"; - public const string CparItemStartime2 = "CPAR_START_TIME_2"; - public const string CparItemEndtime1 = "CPAR_END_TIME_1"; - public const string CparItemEndtime2 = "CPAR_END_TIME_2"; - public const string CparItemAid2 = "CPAR_AID_2"; - public const string CparItemTyp2 = "CPAR_TYP_2"; - public const string CparItemSpd2 = "CPAR_SPD_2"; - public const string CparItemAlt2 = "CPAR_ALT_2"; - } + public const string Inhibited = "^"; +} - public static class LabelConstants - { - public const string LabelItemSelectHori = "SELECT_HORI"; - public const string LabelItemSelectVert = "SELECT_VERT"; - public const string LabelItemCommIcon = "AURORA_COMM_ICON"; //field a(2) - public const string LabelItemAdsbCpdlc = "AURORA_ADSB_CPDLC"; //field c(4) - public const string LabelItemAdsFlags = "AURORA_ADS_FLAGS"; //field c(4) - public const string LabelItemMntFlags = "AURORA_MNT_FLAGS"; //field c(4) - public const string LabelItemScc = "AURORA_SCC"; //field d(5) - public const string LabelItemAnnotInd = "AURORA_ANNOT_IND"; //field e(1) - public const string LabelItemRestr = "AURORA_RESTR"; //field f(1) - public const string LabelItemLevel = "AURORA_LEVEL"; //field g(3) - public const string LabelItemVmi = "AURORA_VMI"; //field h(1) - public const string LabelItemClearedLevel = "AURORA_CLEARED_LEVEL"; //field i(7) - public const string LabelItemHandoffInd = "AURORA_HO_IND"; //field j(4) - public const string LabelItemRadarInd = "AURORA_RADAR_IND"; //field k(1) - public const string LabelItemInhibitInd = "AURORA_INHIBIT_IND"; //field l(1) - public const string LabelItemFiledSpeed = "AURORA_FILEDSPEED"; //field m(4) - public const string LabelItem3DigitGroundspeed = "AURORA_GROUNDSPEED"; //field n(5) - public const string LabelItemDestination = "AURORA_DESTINATION"; //field o(4) - } +public static class StripConstants +{ + public const string LabelItemAdsbCpdlc = "AURORA_ADSB_CPDLC"; //field c(4) + public const string StripItemCallsign = "AURORA_CALLSIGN"; + public const string StripItemCtlsector = "AURORA_CDA"; + public const string StripItemNxtsector = "AURORA_NDA"; + public const string StripItemT10Flag = "AURORA_T10_FLAG"; + public const string StripItemMntFlag = "AURORA_MNT_FLAG"; + public const string StripItemDistFlag = "AURORA_DIST_FLAG"; + public const string StripItemRvsmFlag = "AURORA_RVSM_FLAG"; + public const string StripItemVmi = "AURORA_STRIP_VMI"; + public const string StripItemComplex = "AURORA_STRIP_COMPLEX"; + public const string StripItemClearedLevel = "AURORA_CLEARED_LEVEL"; + public const string StripItemRequestedLevel = "AURORA_REQUESTED_LEVEL"; + public const string StripItemManEst = "AURORA_MAN_EST"; + public const string StripItemPoint = "AURORA_POINT"; + public const string StripItemRoute = "AURORA_ROUTE_STRIP"; + public const string StripItemRadarInd = "AURORA_RADAR_IND"; + public const string StripItemAnnotInd = "AURORA_ANNOT_STRIP"; + public const string StripItemLateralFlag = "AURORA_LATERAL_FLAG"; + public const string StripItemRestr = "AURORA_RESTR_STRIP"; + public const string StripItemClrdRte = "AURORA_CLRD_RTE"; + public const string CparItemType = "CPAR_TYP"; + public const string CparItemRequired = "CPAR_REQUIRED"; + public const string CparItemIntruder = "CPAR_INT"; + public const string CparItemLos = "CPAR_LOS"; + public const string CparItemActual = "CPAR_ACTUAL"; + public const string CparItemPassing = "CPAR_PASSING"; + public const string CparItemConfSegStart1 = "CPAR_CONF_SEG_START_1"; + public const string CparItemConfSegStart2 = "CPAR_CONF_SEG_START_2"; + public const string CparItemConfSegEnd1 = "CPAR_CONF_SEG_END_1"; + public const string CparItemConfSegEnd2 = "CPAR_CONF_SEG_END_2"; + public const string CparItemStartime1 = "CPAR_START_TIME_1"; + public const string CparItemStartime2 = "CPAR_START_TIME_2"; + public const string CparItemEndtime1 = "CPAR_END_TIME_1"; + public const string CparItemEndtime2 = "CPAR_END_TIME_2"; + public const string CparItemAid2 = "CPAR_AID_2"; + public const string CparItemTyp2 = "CPAR_TYP_2"; + public const string CparItemSpd2 = "CPAR_SPD_2"; + public const string CparItemAlt2 = "CPAR_ALT_2"; +} + +public static class LabelConstants +{ + public const string LabelItemSelectHori = "SELECT_HORI"; + public const string LabelItemSelectVert = "SELECT_VERT"; + public const string LabelItemCommIcon = "AURORA_COMM_ICON"; //field a(2) + public const string LabelItemAdsbCpdlc = "AURORA_ADSB_CPDLC"; //field c(4) + public const string LabelItemAdsFlags = "AURORA_ADS_FLAGS"; //field c(4) + public const string LabelItemMntFlags = "AURORA_MNT_FLAGS"; //field c(4) + public const string LabelItemScc = "AURORA_SCC"; //field d(5) + public const string LabelItemAnnotInd = "AURORA_ANNOT_IND"; //field e(1) + public const string LabelItemRestr = "AURORA_RESTR"; //field f(1) + public const string LabelItemLevel = "AURORA_LEVEL"; //field g(3) + public const string LabelItemVmi = "AURORA_VMI"; //field h(1) + public const string LabelItemClearedLevel = "AURORA_CLEARED_LEVEL"; //field i(7) + public const string LabelItemHandoffInd = "AURORA_HO_IND"; //field j(4) + public const string LabelItemRadarInd = "AURORA_RADAR_IND"; //field k(1) + public const string LabelItemInhibitInd = "AURORA_INHIBIT_IND"; //field l(1) + public const string LabelItemFiledSpeed = "AURORA_FILEDSPEED"; //field m(4) + public const string LabelItem3DigitGroundspeed = "AURORA_GROUNDSPEED"; //field n(5) + public const string LabelItemDestination = "AURORA_DESTINATION"; //field o(4) } \ No newline at end of file diff --git a/Display/LabelItemRenderer.cs b/Display/LabelItemRenderer.cs index 0857ab4..b3ce6b0 100644 --- a/Display/LabelItemRenderer.cs +++ b/Display/LabelItemRenderer.cs @@ -12,6 +12,9 @@ public static class LabelItemRenderer { if (fdr == null) return null; + var atopState = fdr.GetAtopState(); + var displayState = fdr.GetDisplayState(); + return itemType switch { LabelConstants.LabelItemSelectHori => track.IsSelected() @@ -22,35 +25,79 @@ public static class LabelItemRenderer ? new CustomLabelItem { Text = Symbols.Empty, Border = BorderFlags.Left } : null, - LabelConstants.LabelItemCommIcon => fdr.GetAtopState().DownlinkIndicator + LabelConstants.LabelItemCommIcon => atopState.DownlinkIndicator ? new CustomLabelItem { Text = Symbols.CommDownlink, Border = BorderFlags.All } : new CustomLabelItem { Text = Symbols.CommEmpty }, - LabelConstants.LabelItemAdsbCpdlc => null, + LabelConstants.LabelItemAdsbCpdlc => fdr.State is FDP2.FDR.FDRStates.STATE_PREACTIVE or + FDP2.FDR.FDRStates.STATE_COORDINATED + ? new CustomLabelItem + { + Text = displayState.CpdlcAdsbSymbol, ForeColourIdentity = Colours.Identities.Custom, + CustomForeColour = CustomColors.NotCda + } + : new CustomLabelItem { Text = displayState.CpdlcAdsbSymbol }, - LabelConstants.LabelItemAdsFlags => null, + LabelConstants.LabelItemAdsFlags => new CustomLabelItem { Text = displayState.AdsFlag }, - LabelConstants.LabelItemMntFlags => null, + LabelConstants.LabelItemMntFlags => displayState.IsMntFlagToggled + ? new CustomLabelItem { Text = Symbols.MntFlag } + : null, - LabelConstants.LabelItemScc => fdr.GetAtopState().HighestSccFlag != null + LabelConstants.LabelItemScc => atopState.HighestSccFlag != null ? new CustomLabelItem { - Text = fdr.GetAtopState().HighestSccFlag!.Value, ForeColourIdentity = Colours.Identities.Custom, + Text = atopState.HighestSccFlag!.Value, ForeColourIdentity = Colours.Identities.Custom, CustomForeColour = CustomColors.SpecialConditionCode } : null, - LabelConstants.LabelItemAnnotInd => null, - - LabelConstants.LabelItemRestr => null, + LabelConstants.LabelItemAnnotInd => new CustomLabelItem + { Text = displayState.AnnotationIndicator }, - LabelConstants.LabelItemLevel => null, + LabelConstants.LabelItemRestr => displayState.IsRestrictionsIndicatorToggled + ? new CustomLabelItem { Text = Symbols.RestrictionsFlag } + : null, - LabelConstants.LabelItemVmi => null, + LabelConstants.LabelItemLevel => displayState.AltitudeColor == null + ? new CustomLabelItem + { + Text = displayState.CurrentLevel, + Border = displayState.AltitudeBorderFlags, + BorderColourIdentity = Colours.Identities.Custom, + CustomBorderColour = CustomColors.NotCda + } + : new CustomLabelItem + { + Text = displayState.CurrentLevel, + Border = displayState.AltitudeBorderFlags, + BorderColourIdentity = Colours.Identities.Custom, + CustomBorderColour = CustomColors.NotCda, + ForeColourIdentity = Colours.Identities.Custom, + CustomForeColour = displayState.AltitudeColor + }, - LabelConstants.LabelItemClearedLevel => null, + LabelConstants.LabelItemVmi => new CustomLabelItem { Text = atopState.AltitudeFlag?.Value ?? "" }, - LabelConstants.LabelItemRadarInd => fdr.GetAtopState().RadarToggleIndicator + LabelConstants.LabelItemClearedLevel => displayState.AltitudeColor == null + ? new CustomLabelItem + { + Text = displayState.ClearedLevel, + Border = displayState.AltitudeBorderFlags, + BorderColourIdentity = Colours.Identities.Custom, + CustomBorderColour = CustomColors.NotCda + } + : new CustomLabelItem + { + Text = displayState.ClearedLevel, + Border = displayState.AltitudeBorderFlags, + BorderColourIdentity = Colours.Identities.Custom, + CustomBorderColour = CustomColors.NotCda, + ForeColourIdentity = Colours.Identities.Custom, + CustomForeColour = displayState.AltitudeColor + }, + + LabelConstants.LabelItemRadarInd => atopState.RadarToggleIndicator ? new CustomLabelItem { Text = Symbols.RadarFlag, OnMouseClick = RadarFlagToggleHandler.Handle } : new CustomLabelItem { Text = Symbols.UntoggledFlag, OnMouseClick = RadarFlagToggleHandler.Handle }, @@ -58,9 +105,10 @@ public static class LabelItemRenderer ? new CustomLabelItem { Text = Symbols.Inhibited } : null, - LabelConstants.LabelItemFiledSpeed => null, + LabelConstants.LabelItemFiledSpeed => new CustomLabelItem { Text = displayState.FiledSpeed }, - LabelConstants.LabelItem3DigitGroundspeed => null, + LabelConstants.LabelItem3DigitGroundspeed => new CustomLabelItem + { Text = displayState.GroundSpeed }, LabelConstants.LabelItemDestination => new CustomLabelItem { Text = fdr.DesAirport }, diff --git a/Extensions.cs b/Extensions.cs index bff6742..fec5bfe 100644 --- a/Extensions.cs +++ b/Extensions.cs @@ -7,7 +7,12 @@ public static class Extensions { public static AtopAircraftState GetAtopState(this FDP2.FDR fdr) { - return AtopPluginStateManager.GetState(fdr.Callsign); + return AtopPluginStateManager.GetAircraftState(fdr.Callsign); + } + + public static AtopAircraftDisplayState GetDisplayState(this FDP2.FDR fdr) + { + return AtopPluginStateManager.GetDisplayState(fdr.Callsign); } public static int? GetTransponderCode(this FDP2.FDR fdr) diff --git a/Logic/AltitudeCalculator.cs b/Logic/AltitudeCalculator.cs index dd189ca..f724f5e 100644 --- a/Logic/AltitudeCalculator.cs +++ b/Logic/AltitudeCalculator.cs @@ -32,7 +32,7 @@ public static bool CalculateAltitudeChangePending(FDP2.FDR updatedFdr, AltitudeB }; } - private static bool IsWithinThreshold(int pilotReportedAltitude, AltitudeBlock altitudeBlock) + public static bool IsWithinThreshold(int pilotReportedAltitude, AltitudeBlock altitudeBlock) { var lowerWithThreshold = altitudeBlock.LowerAltitude - LevelFlightThreshold; var upperWithThreshold = altitudeBlock.UpperAltitude + LevelFlightThreshold; diff --git a/Models/AltitudeBlock.cs b/Models/AltitudeBlock.cs index 4207f13..4619cae 100644 --- a/Models/AltitudeBlock.cs +++ b/Models/AltitudeBlock.cs @@ -30,10 +30,7 @@ public bool IsAboveRvsm() public static int Difference(AltitudeBlock block1, AltitudeBlock block2) { // check for intersection - if (block1.LowerAltitude <= block2.UpperAltitude && block2.LowerAltitude <= block1.UpperAltitude) - { - return 0; - } + if (block1.LowerAltitude <= block2.UpperAltitude && block2.LowerAltitude <= block1.UpperAltitude) return 0; var isBlock1Lower = block1.UpperAltitude < block2.LowerAltitude; @@ -41,7 +38,7 @@ public static int Difference(AltitudeBlock block1, AltitudeBlock block2) ? block2.LowerAltitude - block1.UpperAltitude : block1.LowerAltitude - block2.UpperAltitude; } - + public static AltitudeBlock ExtractAltitudeBlock(FDP2.FDR fdr) { var altitudeUpper = ExtractClearedOrRequestedValue(fdr.CFLUpper, fdr.RFL); @@ -53,4 +50,11 @@ private static int ExtractClearedOrRequestedValue(int clearedValue, int requeste { return clearedValue == -1 ? requestedValue : clearedValue; } + + public override string ToString() + { + if (LowerAltitude == UpperAltitude) return (UpperAltitude / 100).ToString(); + + return LowerAltitude / 100 + "B" + UpperAltitude / 100; + } } \ No newline at end of file diff --git a/State/AtopAircraftDisplayState.cs b/State/AtopAircraftDisplayState.cs new file mode 100644 index 0000000..41cd7dc --- /dev/null +++ b/State/AtopAircraftDisplayState.cs @@ -0,0 +1,112 @@ +#nullable enable +using System.Linq; +using AuroraLabelItemsPlugin.Logic; +using AuroraLabelItemsPlugin.Models; +using vatsys; +using vatsys.Plugin; + +namespace AuroraLabelItemsPlugin.State; + +public class AtopAircraftDisplayState +{ + private static readonly string[] RestrictionLabels = { "AT ", " BY ", "CLEARED TO " }; + + public AtopAircraftDisplayState(AtopAircraftState atopAircraftState) + { + UpdateFromAtopState(atopAircraftState); + } + + public string CpdlcAdsbSymbol { get; private set; } + public string AdsFlag { get; private set; } + public bool IsMntFlagToggled { get; private set; } + public string AnnotationIndicator { get; private set; } + public bool IsRestrictionsIndicatorToggled { get; private set; } + public string CurrentLevel { get; private set; } + public string ClearedLevel { get; private set; } + public BorderFlags AltitudeBorderFlags { get; private set; } + public CustomColour? AltitudeColor { get; private set; } + public string FiledSpeed { get; private set; } + public string GroundSpeed { get; private set; } + + public void UpdateFromAtopState(AtopAircraftState atopAircraftState) + { + CpdlcAdsbSymbol = GetCpdlcAdsbSymbol(atopAircraftState); + AdsFlag = GetAdsFlag(atopAircraftState); + IsMntFlagToggled = atopAircraftState.Fdr.PerformanceData.IsJet; + AnnotationIndicator = GetAnnotationIndicator(atopAircraftState); + IsRestrictionsIndicatorToggled = GetRestrictionsIndicatorToggled(atopAircraftState); + CurrentLevel = (atopAircraftState.Fdr.PRL / 100).ToString(); + ClearedLevel = GetClearedLevel(atopAircraftState); + AltitudeBorderFlags = GetAltitudeBorderFlags(atopAircraftState); + AltitudeColor = atopAircraftState.Fdr.RVSM ? null : CustomColors.NonRvsm; + FiledSpeed = GetFiledSpeed(atopAircraftState); + GroundSpeed = GetGroundSpeed(atopAircraftState); + } + + private static string GetCpdlcAdsbSymbol(AtopAircraftState atopAircraftState) + { + var adsb = atopAircraftState.Fdr.ADSB; + var cpdlc = atopAircraftState.CalculatedFlightData.Cpdlc; + return (adsb, cpdlc) switch + { + { adsb: true, cpdlc: true } => Symbols.CpdlcAndAdsb, + { adsb: true, cpdlc: false } => Symbols.Empty, + { adsb: false, cpdlc: true } => Symbols.CpdlcNoAdsb, + { adsb: false, cpdlc: false } => Symbols.NoCpdlcNoAdsb + }; + } + + private static string GetAdsFlag(AtopAircraftState atopAircraftState) + { + return atopAircraftState.CalculatedFlightData switch + { + { Adsc: true, Cpdlc: true, Rnp4: true } => Symbols.D30, + { Adsc: true, Cpdlc: true, Rnp10: true } => Symbols.D50, + _ => Symbols.Empty + }; + } + + private static string GetAnnotationIndicator(AtopAircraftState atopAircraftState) + { + return string.IsNullOrEmpty(atopAircraftState.Fdr.LabelOpData) ? Symbols.UntoggledFlag : Symbols.ScratchpadFlag; + } + + private static bool GetRestrictionsIndicatorToggled(AtopAircraftState atopAircraftState) + { + return RestrictionLabels.Any(label => atopAircraftState.Fdr.LabelOpData.Contains(label)); + } + + private static string GetClearedLevel(AtopAircraftState atopAircraftState) + { + var fdr = atopAircraftState.Fdr; + var altitudeBlock = AltitudeBlock.ExtractAltitudeBlock(fdr); + + if (!atopAircraftState.PendingAltitudeChange || + AltitudeCalculator.IsWithinThreshold(fdr.PRL, altitudeBlock)) + return Symbols.Empty; + + return altitudeBlock.ToString(); + } + + private static BorderFlags GetAltitudeBorderFlags(AtopAircraftState atopAircraftState) + { + return atopAircraftState.Fdr.State switch + { + FDP2.FDR.FDRStates.STATE_PREACTIVE or FDP2.FDR.FDRStates.STATE_COORDINATED => BorderFlags.All, + _ => BorderFlags.None + }; + } + + private static string GetFiledSpeed(AtopAircraftState atopAircraftState) + { + var temperature = GRIB.FindTemperature(atopAircraftState.Fdr.PRL, atopAircraftState.Fdr.GetLocation(), true); + var mach = Conversions.CalculateMach(atopAircraftState.Fdr.TAS, temperature); + return "M" + mach.ToString("F2").Replace(".", ""); + } + + private static string GetGroundSpeed(AtopAircraftState atopAircraftState) + { + var gs = atopAircraftState.Fdr.PredictedPosition.Groundspeed; + return "N" + gs.ToString("000"); + } +} \ No newline at end of file diff --git a/State/AtopAircraftState.cs b/State/AtopAircraftState.cs index 74fb9dc..efbd497 100644 --- a/State/AtopAircraftState.cs +++ b/State/AtopAircraftState.cs @@ -9,12 +9,14 @@ public class AtopAircraftState { public AtopAircraftState(FDP2.FDR fdr) { + Fdr = fdr; UpdateFromFdr(fdr); DownlinkIndicator = false; RadarToggleIndicator = false; PreviouslyTracked = false; } + public FDP2.FDR Fdr { get; private set; } public CalculatedFlightData CalculatedFlightData { get; private set; } public DirectionOfFlight DirectionOfFlight { get; private set; } public SccFlag? HighestSccFlag { get; private set; } @@ -28,6 +30,8 @@ public AtopAircraftState(FDP2.FDR fdr) public void UpdateFromFdr(FDP2.FDR updatedFdr) { + Fdr = updatedFdr; + CalculatedFlightData = FlightDataCalculator.GetCalculatedFlightData(updatedFdr); DirectionOfFlight = DirectionOfFlightCalculator.GetDirectionOfFlight(updatedFdr); HighestSccFlag = SccFlagCalculator.CalculateHighestPriorityFlag(updatedFdr); diff --git a/State/AtopPluginStateManager.cs b/State/AtopPluginStateManager.cs index 9bdd2aa..b01998a 100644 --- a/State/AtopPluginStateManager.cs +++ b/State/AtopPluginStateManager.cs @@ -1,18 +1,25 @@ -using System.Collections.Concurrent; +#nullable enable +using System.Collections.Concurrent; using vatsys; namespace AuroraLabelItemsPlugin.State; public static class AtopPluginStateManager { - private const int MissingFromFdpState = -1; - - private static readonly ConcurrentDictionary ExtendedFdrStates = new(); - public static AtopAircraftState GetState(string callsign) + private static readonly ConcurrentDictionary AircraftStates = new(); + private static readonly ConcurrentDictionary DisplayStates = new(); + + public static AtopAircraftState? GetAircraftState(string callsign) + { + var found = AircraftStates.TryGetValue(callsign, out var state); + return found ? state : null; + } + + public static AtopAircraftDisplayState? GetDisplayState(string callsign) { - var found = ExtendedFdrStates.TryGetValue(callsign, out var state); + var found = DisplayStates.TryGetValue(callsign, out var state); return found ? state : null; } @@ -22,19 +29,26 @@ public static void ProcessStateUpdate(FDP2.FDR updated) if (FDP2.GetFDRIndex(callsign) == MissingFromFdpState) { - ExtendedFdrStates.TryRemove(callsign, out _); + AircraftStates.TryRemove(callsign, out _); + DisplayStates.TryRemove(callsign, out _); return; } - - var extendedFdrState = GetState(callsign); - if (extendedFdrState == null) + var aircraftState = GetAircraftState(callsign); + if (aircraftState == null) { - ExtendedFdrStates.TryAdd(callsign, new AtopAircraftState(updated)); + aircraftState = new AtopAircraftState(updated); + AircraftStates.TryAdd(callsign, aircraftState); } else { - extendedFdrState.UpdateFromFdr(updated); + aircraftState.UpdateFromFdr(updated); } + + var displayState = GetDisplayState(callsign); + if (displayState == null) + DisplayStates.TryAdd(callsign, new AtopAircraftDisplayState(aircraftState)); + else + displayState.UpdateFromAtopState(aircraftState); } } \ No newline at end of file diff --git a/State/PrivateMessagesChangedHandler.cs b/State/PrivateMessagesChangedHandler.cs index a0c26e4..cdad249 100644 --- a/State/PrivateMessagesChangedHandler.cs +++ b/State/PrivateMessagesChangedHandler.cs @@ -6,7 +6,7 @@ public static class PrivateMessagesChangedHandler { public static void Handle(object sender, Network.GenericMessageEventArgs eventArgs) { - var extendedFdrState = AtopPluginStateManager.GetState(eventArgs.Message.Address); + var extendedFdrState = AtopPluginStateManager.GetAircraftState(eventArgs.Message.Address); extendedFdrState.DownlinkIndicator = !eventArgs.Message.Sent; } } \ No newline at end of file From c201f1a057087dd7737da9e2ba6c211428908090 Mon Sep 17 00:00:00 2001 From: Maxim Salikhov Date: Sun, 25 Feb 2024 00:36:26 -0500 Subject: [PATCH 50/76] Finish strip rendering logic Except for next sector --- Constants.cs | 7 +++++ Display/LabelItemRenderer.cs | 8 +++--- Display/StripItemRenderer.cs | 48 ++++++++++++++++++++++--------- State/AtopAircraftDisplayState.cs | 24 +++++++++++++--- 4 files changed, 66 insertions(+), 21 deletions(-) diff --git a/Constants.cs b/Constants.cs index a639ecc..2067696 100644 --- a/Constants.cs +++ b/Constants.cs @@ -30,6 +30,8 @@ public static class Symbols public const string T10 = "M"; public const string Mnt = "R"; public const string Rvsm = "W"; + public const string L50 = "R"; + public const string L23 = "4"; public const string CommDownlink = "▼"; public const string CommEmpty = "⬜"; @@ -38,6 +40,7 @@ public static class Symbols public const string UntoggledFlag = "◦"; public const string ScratchpadFlag = "&"; public const string MntFlag = "M"; + public const string ComplexFlag = "*"; public const string RestrictionsFlag = "x"; public const string Climbing = "↑"; @@ -46,6 +49,10 @@ public static class Symbols public const string DeviatingBelow = "-"; public const string Inhibited = "^"; + public const string EmptyAnnotations = "."; + + public const string StripRouteItem = "F"; + public const string StripRadarIndicator = "A"; } public static class StripConstants diff --git a/Display/LabelItemRenderer.cs b/Display/LabelItemRenderer.cs index b3ce6b0..28e989a 100644 --- a/Display/LabelItemRenderer.cs +++ b/Display/LabelItemRenderer.cs @@ -52,8 +52,9 @@ public static class LabelItemRenderer } : null, - LabelConstants.LabelItemAnnotInd => new CustomLabelItem - { Text = displayState.AnnotationIndicator }, + LabelConstants.LabelItemAnnotInd => displayState.HasAnnotations + ? new CustomLabelItem { Text = Symbols.ScratchpadFlag } + : new CustomLabelItem { Text = Symbols.UntoggledFlag }, LabelConstants.LabelItemRestr => displayState.IsRestrictionsIndicatorToggled ? new CustomLabelItem { Text = Symbols.RestrictionsFlag } @@ -107,8 +108,7 @@ public static class LabelItemRenderer LabelConstants.LabelItemFiledSpeed => new CustomLabelItem { Text = displayState.FiledSpeed }, - LabelConstants.LabelItem3DigitGroundspeed => new CustomLabelItem - { Text = displayState.GroundSpeed }, + LabelConstants.LabelItem3DigitGroundspeed => new CustomLabelItem { Text = displayState.GroundSpeed }, LabelConstants.LabelItemDestination => new CustomLabelItem { Text = fdr.DesAirport }, diff --git a/Display/StripItemRenderer.cs b/Display/StripItemRenderer.cs index aa557fe..6520511 100644 --- a/Display/StripItemRenderer.cs +++ b/Display/StripItemRenderer.cs @@ -12,13 +12,18 @@ public static class StripItemRenderer { if (fdr == null) return null; + var atopState = fdr.GetAtopState(); + var displayState = fdr.GetDisplayState(); + return itemType switch { StripConstants.StripItemCallsign => RenderCallsignStripItem(fdr), + StripConstants.StripItemCtlsector => RenderCtlSectorStripItem(fdr), - StripConstants.StripItemNxtsector => null, - StripConstants.LabelItemAdsbCpdlc => null, + StripConstants.StripItemNxtsector => null, // TODO + + StripConstants.LabelItemAdsbCpdlc => RenderAdsbCpdlcStripItem(fdr), StripConstants.StripItemT10Flag => fdr.PerformanceData.IsJet ? new CustomStripItem { Text = Symbols.T10 } @@ -28,33 +33,43 @@ public static class StripItemRenderer ? new CustomStripItem { Text = Symbols.Mnt } : null, - StripConstants.StripItemDistFlag => null, + StripConstants.StripItemDistFlag => new CustomStripItem + { + Text = displayState.AdsFlag, ForeColourIdentity = Colours.Identities.Custom, + CustomForeColour = CustomColors.SepFlags + }, StripConstants.StripItemRvsmFlag => fdr.RVSM ? new CustomStripItem { Text = Symbols.Rvsm, BackColourIdentity = Colours.Identities.Custom, - CustomBackColour = CustomColors.SepFlags, + CustomBackColour = CustomColors.SepFlags } : null, - StripConstants.StripItemVmi => null, + StripConstants.StripItemVmi => new CustomStripItem { Text = atopState.AltitudeFlag?.Value ?? "" }, - StripConstants.StripItemComplex => null, + StripConstants.StripItemComplex => displayState.IsRestrictionsIndicatorToggled + ? new CustomStripItem() { Text = Symbols.ComplexFlag } + : null, - StripConstants.StripItemClearedLevel => null, + StripConstants.StripItemClearedLevel => new CustomStripItem { Text = displayState.ClearedLevel }, - StripConstants.StripItemRequestedLevel => null, + StripConstants.StripItemRequestedLevel => new CustomStripItem { Text = displayState.RequestedLevel }, - StripConstants.StripItemRoute => null, + StripConstants.StripItemRoute => new CustomStripItem { Text = Symbols.StripRouteItem }, - StripConstants.StripItemRadarInd => null, + StripConstants.StripItemRadarInd => new CustomStripItem { Text = Symbols.StripRadarIndicator }, - StripConstants.StripItemAnnotInd => null, + StripConstants.StripItemAnnotInd => displayState.HasAnnotations + ? new CustomStripItem { Text = Symbols.ScratchpadFlag } + : new CustomStripItem { Text = Symbols.EmptyAnnotations }, - StripConstants.StripItemLateralFlag => null, + StripConstants.StripItemLateralFlag => new CustomStripItem { Text = displayState.LateralFlag }, - StripConstants.StripItemRestr => null, + StripConstants.StripItemRestr => displayState.IsRestrictionsIndicatorToggled + ? new CustomStripItem { Text = Symbols.RestrictionsFlag } + : null, _ => null }; @@ -84,6 +99,13 @@ private static CustomStripItem RenderCtlSectorStripItem(FDP2.FDR fdr) return stripItem; } + private static CustomStripItem RenderAdsbCpdlcStripItem(FDP2.FDR fdr) + { + var stripItem = GetStripItemWithColorsForDirection(fdr.GetAtopState().DirectionOfFlight); + stripItem.Text = fdr.GetDisplayState().CpdlcAdsbSymbol; + return stripItem; + } + private static CustomStripItem GetStripItemWithColorsForDirection(DirectionOfFlight directionOfFlight) { var foreColorIdentity = directionOfFlight == DirectionOfFlight.Eastbound diff --git a/State/AtopAircraftDisplayState.cs b/State/AtopAircraftDisplayState.cs index 41cd7dc..dfa2f12 100644 --- a/State/AtopAircraftDisplayState.cs +++ b/State/AtopAircraftDisplayState.cs @@ -18,11 +18,13 @@ public AtopAircraftDisplayState(AtopAircraftState atopAircraftState) public string CpdlcAdsbSymbol { get; private set; } public string AdsFlag { get; private set; } + public string LateralFlag { get; private set; } public bool IsMntFlagToggled { get; private set; } - public string AnnotationIndicator { get; private set; } + public bool HasAnnotations { get; private set; } public bool IsRestrictionsIndicatorToggled { get; private set; } public string CurrentLevel { get; private set; } public string ClearedLevel { get; private set; } + public string RequestedLevel { get; private set; } public BorderFlags AltitudeBorderFlags { get; private set; } public CustomColour? AltitudeColor { get; private set; } public string FiledSpeed { get; private set; } @@ -32,11 +34,13 @@ public void UpdateFromAtopState(AtopAircraftState atopAircraftState) { CpdlcAdsbSymbol = GetCpdlcAdsbSymbol(atopAircraftState); AdsFlag = GetAdsFlag(atopAircraftState); + LateralFlag = GetLateralFlag(atopAircraftState); IsMntFlagToggled = atopAircraftState.Fdr.PerformanceData.IsJet; - AnnotationIndicator = GetAnnotationIndicator(atopAircraftState); + HasAnnotations = !string.IsNullOrEmpty(atopAircraftState.Fdr.LabelOpData); IsRestrictionsIndicatorToggled = GetRestrictionsIndicatorToggled(atopAircraftState); CurrentLevel = (atopAircraftState.Fdr.PRL / 100).ToString(); ClearedLevel = GetClearedLevel(atopAircraftState); + RequestedLevel = GetRequestedLevel(atopAircraftState); AltitudeBorderFlags = GetAltitudeBorderFlags(atopAircraftState); AltitudeColor = atopAircraftState.Fdr.RVSM ? null : CustomColors.NonRvsm; FiledSpeed = GetFiledSpeed(atopAircraftState); @@ -66,9 +70,14 @@ private static string GetAdsFlag(AtopAircraftState atopAircraftState) }; } - private static string GetAnnotationIndicator(AtopAircraftState atopAircraftState) + private static string GetLateralFlag(AtopAircraftState atopAircraftState) { - return string.IsNullOrEmpty(atopAircraftState.Fdr.LabelOpData) ? Symbols.UntoggledFlag : Symbols.ScratchpadFlag; + return atopAircraftState.CalculatedFlightData switch + { + { Adsc: true, Cpdlc: true, Rnp4: true } => Symbols.L23, + { Adsc: true, Cpdlc: true, Rnp10: true } => Symbols.L50, + _ => Symbols.Empty + }; } private static bool GetRestrictionsIndicatorToggled(AtopAircraftState atopAircraftState) @@ -88,6 +97,13 @@ private static string GetClearedLevel(AtopAircraftState atopAircraftState) return altitudeBlock.ToString(); } + private static string GetRequestedLevel(AtopAircraftState atopAircraftState) + { + return atopAircraftState.Fdr.State == FDP2.FDR.FDRStates.STATE_INACTIVE + ? (atopAircraftState.Fdr.RFL / 100).ToString() + : Symbols.Empty; + } + private static BorderFlags GetAltitudeBorderFlags(AtopAircraftState atopAircraftState) { return atopAircraftState.Fdr.State switch From 8c05feae75fcefc1ce9d2c667d77dcff6249f32c Mon Sep 17 00:00:00 2001 From: Maxim Salikhov Date: Sun, 25 Feb 2024 00:47:47 -0500 Subject: [PATCH 51/76] Add next sector calculation --- AuroraLabelItemsPlugin.csproj | 1 + Display/StripItemRenderer.cs | 2 +- Logic/NextSectorCalculator.cs | 33 +++++++++++++++++++++++++++++++++ State/AtopAircraftState.cs | 3 +++ 4 files changed, 38 insertions(+), 1 deletion(-) create mode 100644 Logic/NextSectorCalculator.cs diff --git a/AuroraLabelItemsPlugin.csproj b/AuroraLabelItemsPlugin.csproj index 170c050..107de4c 100644 --- a/AuroraLabelItemsPlugin.csproj +++ b/AuroraLabelItemsPlugin.csproj @@ -64,6 +64,7 @@ + diff --git a/Display/StripItemRenderer.cs b/Display/StripItemRenderer.cs index 6520511..c662251 100644 --- a/Display/StripItemRenderer.cs +++ b/Display/StripItemRenderer.cs @@ -21,7 +21,7 @@ public static class StripItemRenderer StripConstants.StripItemCtlsector => RenderCtlSectorStripItem(fdr), - StripConstants.StripItemNxtsector => null, // TODO + StripConstants.StripItemNxtsector => new CustomStripItem { Text = atopState.NextSector?.Name ?? "" }, StripConstants.LabelItemAdsbCpdlc => RenderAdsbCpdlcStripItem(fdr), diff --git a/Logic/NextSectorCalculator.cs b/Logic/NextSectorCalculator.cs new file mode 100644 index 0000000..67cf92d --- /dev/null +++ b/Logic/NextSectorCalculator.cs @@ -0,0 +1,33 @@ +#nullable enable +using System; +using System.Linq; +using vatsys; + +namespace AuroraLabelItemsPlugin.Logic; + +public static class NextSectorCalculator +{ + public static SectorsVolumes.Sector? GetNextSector(FDP2.FDR fdr) + { + var segment = (from s in fdr.ParsedRoute.ToList() + where s.Type == FDP2.FDR.ExtractedRoute.Segment.SegmentTypes.ZPOINT && + !fdr.ControllingSector.Equals(SectorsVolumes.FindSector((SectorsVolumes.Volume)s.Tag)) + select s).FirstOrDefault(s => s.ETO > DateTime.UtcNow); + + SectorsVolumes.Volume? volume = null; + if (segment != null) volume = (SectorsVolumes.Volume)segment.Tag; + + var nextSector = volume != null ? SectorsVolumes.FindSector(volume) : null; + + if (nextSector == null) return nextSector; + + SectorsVolumes.Sector sector = null; + foreach (var s2 in SectorsVolumes.SectorGroupings.Keys) + if (s2.SubSectors.Contains(nextSector) && + (sector == null || sector.SubSectors.Count > s2.SubSectors.Count)) + sector = s2; + if (sector != null) nextSector = sector; + + return nextSector; + } +} \ No newline at end of file diff --git a/State/AtopAircraftState.cs b/State/AtopAircraftState.cs index efbd497..f225f46 100644 --- a/State/AtopAircraftState.cs +++ b/State/AtopAircraftState.cs @@ -21,6 +21,7 @@ public AtopAircraftState(FDP2.FDR fdr) public DirectionOfFlight DirectionOfFlight { get; private set; } public SccFlag? HighestSccFlag { get; private set; } public AltitudeFlag? AltitudeFlag { get; private set; } + public SectorsVolumes.Sector? NextSector { get; private set; } public bool DownlinkIndicator { get; set; } public bool RadarToggleIndicator { get; set; } public bool PreviouslyTracked { get; set; } @@ -41,6 +42,8 @@ public void UpdateFromFdr(FDP2.FDR updatedFdr) AltitudeCalculator.CalculateAltitudeChangePending(updatedFdr, PreviousAltitudeBlock, PendingAltitudeChange); AltitudeFlag = AltitudeCalculator.CalculateAltitudeFlag(updatedFdr, PendingAltitudeChange); + NextSector = NextSectorCalculator.GetNextSector(updatedFdr); + // update this last since so we have the previous value for the next update PreviousAltitudeBlock = AltitudeBlock.ExtractAltitudeBlock(updatedFdr); } From c483113e7824b79aa29cdc6f47cb7107b394105a Mon Sep 17 00:00:00 2001 From: Maxim Salikhov Date: Sun, 25 Feb 2024 00:48:37 -0500 Subject: [PATCH 52/76] Delete old code --- AuroraLabelItemsPlugin.cs | 658 ---------------------------------- AuroraLabelItemsPlugin.csproj | 5 - AuroraStripItemPlugin.cs | 547 ---------------------------- Conflict/ConflictProbe.cs | 9 +- Conflict/MinimaCalculator.cs | 23 +- FPAP.cs | 103 ------ GEO.cs | 602 ------------------------------- Logic/FlightDataCalculator.cs | 1 + TOC.cs | 53 --- 9 files changed, 7 insertions(+), 1994 deletions(-) delete mode 100644 AuroraLabelItemsPlugin.cs delete mode 100644 AuroraStripItemPlugin.cs delete mode 100644 FPAP.cs delete mode 100644 GEO.cs delete mode 100644 TOC.cs diff --git a/AuroraLabelItemsPlugin.cs b/AuroraLabelItemsPlugin.cs deleted file mode 100644 index 193d80f..0000000 --- a/AuroraLabelItemsPlugin.cs +++ /dev/null @@ -1,658 +0,0 @@ -//<--Need to add a reference to System.ComponentModel.Composition -using System; -using System.Collections.Concurrent; -using System.Collections.Generic; -using System.ComponentModel.Composition; -using System.Linq; -using System.Text.RegularExpressions; -using System.Threading; -using vatsys; -using vatsys.Plugin; -using static vatsys.FDP2; -using static vatsys.SectorsVolumes; - - -//Note the reference to vatsys (set Copy Local to false) -----> - -namespace AuroraLabelItemsPlugin -{ - [Export(typeof(IPlugin))] - public class AuroraLabelItemsPlugin : ILabelPlugin - { - private readonly ConcurrentDictionary adsbcpdlcValues = new ConcurrentDictionary(); - private readonly ConcurrentDictionary adsflagValues = new ConcurrentDictionary(); - - public readonly ConcurrentDictionary> advisoryConflict = - new ConcurrentDictionary>(); - - private readonly ConcurrentDictionary altValues = new ConcurrentDictionary(); - private readonly ConcurrentDictionary downlink = new ConcurrentDictionary(); - - private readonly ConcurrentDictionary eastboundCallsigns = - new ConcurrentDictionary(); - - public readonly ConcurrentDictionary> imminentConflict = - new ConcurrentDictionary>(); - - private readonly ConcurrentDictionary mntflagtoggle = new ConcurrentDictionary(); - private readonly ConcurrentDictionary mntflagValues = new ConcurrentDictionary(); - private readonly ConcurrentDictionary radartoggle = new ConcurrentDictionary(); - - private readonly ConcurrentDictionary - sccflagValues = new ConcurrentDictionary(); - - - public AuroraLabelItemsPlugin() - { - Network.PrivateMessagesChanged += Network_PrivateMessagesChanged; - Network.RadioMessageAcknowledged += Network_RadioMessageAcknowledged; - } - - - /// Plugin Name - public string Name => "Aurora Label Items"; - - /// This is called each time a flight data record is updated - /// Here we are updating the eastbound callsigns dictionary with each flight data record - /// When the FDR is updated we check if it still exists in the Flight Data Processor and remove from our dictionary if not. Otherwise we do some simple regex matching to find - /// the flight planned PBN category and store the character we want to display in the label in the dictionary. - public void OnFDRUpdate(FDR updated) - { - var pbn = Regex.Match(updated.Remarks, @"PBN\/\w+\s"); - var rnp10 = pbn.Value.Contains("A1"); - var rnp4 = pbn.Value.Contains("L1"); - var cpdlc = updated.AircraftEquip.Contains("J5") || updated.AircraftEquip.Contains("J7"); - var adsc = updated.AircraftSurvEquip.Contains("D1"); - var jet = updated.PerformanceData?.IsJet ?? false; - var vs = updated.PredictedPosition.VerticalSpeed; - var prl = updated.PRL / 100; - var cfl = updated.CFLUpper; - var rfl = updated.RFL; - var alt = cfl == -1 ? rfl : cfl; - - - if (GetFDRIndex(updated.Callsign) == -1) - { - eastboundCallsigns.TryRemove(updated.Callsign, out _); - adsbcpdlcValues.TryRemove(updated.Callsign, out _); - adsflagValues.TryRemove(updated.Callsign, out _); - mntflagValues.TryRemove(updated.Callsign, out _); - sccflagValues.TryRemove(updated.Callsign, out _); - altValues.TryRemove(updated.Callsign, out _); - radartoggle.TryRemove(updated.Callsign, out _); - mntflagtoggle.TryRemove(updated.Callsign, out _); - downlink.TryRemove(updated.Callsign, out _); - advisoryConflict.TryRemove(updated.Callsign, out _); - imminentConflict.TryRemove(updated.Callsign, out _); - } - else - { - char c1 = default; - - if (!updated.ADSB && cpdlc) - - c1 = '⧆'; - - else if (!updated.ADSB) - - c1 = '⎕'; - - else if (cpdlc) - - c1 = '✱'; - - - adsbcpdlcValues.AddOrUpdate(updated.Callsign, c1, (k, v) => c1); - - char c2 = default; - - if (adsc & cpdlc & rnp4) - c2 = '3'; - - else if (adsc & cpdlc & rnp10) - c2 = 'D'; - - adsflagValues.AddOrUpdate(updated.Callsign, c2, (k, v) => c2); - - char c3 = default; - - if (updated.PerformanceData?.IsJet ?? false) - c3 = 'M'; - - mntflagValues.AddOrUpdate(updated.Callsign, c3, (k, v) => c3); - - NetworkPilot code; - code = new NetworkPilot(); - - var d1 = string.Empty; - - if (!rnp10 || !rnp4) - d1 = "RNP"; - - else if (code.TransponderCode == 7700) - d1 = "EMG"; - - else if (code.TransponderCode == 7600) - d1 = "RCF"; - - else if (code.TransponderCode == 7777) - d1 = "MTI"; - - else if (code.TransponderCode == 7700) - d1 = "EMG"; - - sccflagValues.AddOrUpdate(updated.Callsign, d1, (k, v) => d1); - - char h1 = default; - - if (Math.Abs(updated.PRL - alt) <= 299) //level flight - h1 = default; - - else if (alt / 100 > prl || vs > 300) //Issued or trending climb - h1 = '↑'; - - else if ((alt / 100 > 0 && alt < prl) || vs < -300) //Issued or trending descent - h1 = '↓'; - - else if (prl - alt / 100 >= 3) //deviating above - h1 = '+'; - - else if (prl - alt / 100 <= -3) //deviating below - h1 = '-'; - - - altValues.AddOrUpdate(updated.Callsign, h1, (k, v) => h1); - - if (updated.ParsedRoute.Count > 1) - { - //calculate track from first route point to last (Departure point to destination point) - var rte = updated.ParsedRoute; - var trk = Conversions.CalculateTrack(rte.First().Intersection.LatLong, - rte.Last().Intersection.LatLong); - var east = trk >= 0 && trk < 180; - eastboundCallsigns.AddOrUpdate(updated.Callsign, east, (c, e) => east); - } - - TransferOfControl(updated); - - var cpar = new CPAR(); - - if (jet & rnp4 & cpdlc & adsc) ///Using CalculateAreaofConflict method against intruder aircraft - cpar.ConflictProbe(updated, 23); - else if (rnp4 || rnp10) - cpar.ConflictProbe(updated, 50); - else if (rnp10) - cpar.ConflictProbe(updated, 75); - else - cpar.ConflictProbe(updated, 100); - } - } - - //void SendNextDataAuthority(Network network, NetworkPilot pilot, VSCSFrequency freq) - //{ - // - // if (network.ValidATC && network.HaveConnection && !((DateTime.UtcNow - pilot.LastContactMe).TotalMinutes < 1.0)) - // { - // string text = "NEXT DATA AUTHORITY KZAK"; - // if (freq.AliasFrequency != VSCSFrequency.None.Frequency) - // { - // text = text + " (" + Conversions.FrequencyToString(freq.AliasFrequency) + ")"; - //Network.Instance.SendRadioMessage(radioMessage.FSDFrequencies, radioMessage.Address, "Unable", ThisRequiresResponse: false, radioMessage, CloseRequest: true); - // } - // - // network.SendTextMessage(pilot.Callsign, text); - // pilot.LastContactMe = DateTime.UtcNow; - // } - //} - - - /// Could use the new position of the radar track or its change in state (cancelled, etc.) to do some processing. - public void OnRadarTrackUpdate(RDP.RadarTrack updated) - { - } - - - /// vatSys calls this function when it encounters a custom label item (defined in Labels.xml) during the label rendering. - /// itemType is the value of the Type attribute in Labels.xml - /// If it's not our item being called (another plugins, for example), return null. - /// As a general rule, don't do processing in here as you'll slow down the ASD refresh. In the case of parsing a level to a string though, that's fine. - public CustomLabelItem GetCustomLabelItem(string itemType, Track track, FDR flightDataRecord, - RDP.RadarTrack radarTrack) - { - if (flightDataRecord == null || radarTrack == null) - return null; - - char c1; - adsbcpdlcValues.TryGetValue(flightDataRecord.Callsign, out c1); - char c2; - adsflagValues.TryGetValue(flightDataRecord.Callsign, out c2); - char c3; - mntflagValues.TryGetValue(flightDataRecord.Callsign, out c3); - string d1; - sccflagValues.TryGetValue(flightDataRecord.Callsign, out d1); - char h1; - altValues.TryGetValue(flightDataRecord.Callsign, out h1); - - var radarToggled = radartoggle.TryGetValue(flightDataRecord.Callsign, out _); - var mntflagToggled = mntflagtoggle.TryGetValue(flightDataRecord.Callsign, out _); - var downLink = downlink.TryGetValue(flightDataRecord.Callsign, out _); - var isNonRVSM = !flightDataRecord.RVSM; - var pbn = Regex.Match(flightDataRecord.Remarks, @"PBN\/\w+\s"); - var rnp10 = pbn.Value.Contains("A1"); - var rnp4 = pbn.Value.Contains("L1"); - var prl = flightDataRecord.PRL / 100; - var cfl = flightDataRecord.CFLUpper / 100; - var rfl = flightDataRecord.RFL / 100; - var alt = flightDataRecord.CFLUpper == -1 ? rfl : cfl; - var notProbe = flightDataRecord.State == (FDR.FDRStates.STATE_PREACTIVE | FDR.FDRStates.STATE_COORDINATED) - ? BorderFlags.All - : BorderFlags.None; - var colour = !flightDataRecord.RVSM ? CustomColors.NonRvsm : ExcludeConflictColor(track, flightDataRecord); - var excludeConflict = SelectASDTrackColour(track) == GetConflictColour(flightDataRecord.Callsign); - - switch (itemType) - - { - case LabelConstants.LabelItemSelectHori: - - if (MMI.SelectedTrack?.GetFDR()?.Callsign == track.GetFDR().Callsign) - return new CustomLabelItem - { - Text = "", - Border = BorderFlags.Bottom - }; - - return null; - - case LabelConstants.LabelItemSelectVert: - - if (MMI.SelectedTrack?.GetFDR()?.Callsign == track.GetFDR().Callsign) - return new CustomLabelItem - { - Text = "", - Border = BorderFlags.Left - }; - - return null; - - case LabelConstants.LabelItemCommIcon: - - if (downLink) - return new CustomLabelItem - { - Text = "▼", - Border = BorderFlags.All, - ForeColourIdentity = excludeConflict ? Colours.Identities.Custom : default, - CustomForeColour = ExcludeConflictColor(track, flightDataRecord) - }; - return new CustomLabelItem - { - Text = "⬜", - ForeColourIdentity = excludeConflict ? Colours.Identities.Custom : default, - CustomForeColour = ExcludeConflictColor(track, flightDataRecord) - }; - case LabelConstants.LabelItemAdsbCpdlc: - - var useCustomForeColour = - flightDataRecord.State == (FDR.FDRStates.STATE_PREACTIVE | FDR.FDRStates.STATE_COORDINATED); - - if (useCustomForeColour) - return new CustomLabelItem - { - ForeColourIdentity = Colours.Identities.Custom, - CustomForeColour = CustomColors.NotCda, - Text = c1.ToString() - }; - return new CustomLabelItem - { - Text = c1.ToString(), - ForeColourIdentity = excludeConflict ? Colours.Identities.Custom : default, - CustomForeColour = ExcludeConflictColor(track, flightDataRecord) - }; - - case LabelConstants.LabelItemAdsFlags: - - return new CustomLabelItem - { - Text = c2.ToString(), - ForeColourIdentity = excludeConflict ? Colours.Identities.Custom : default, - CustomForeColour = ExcludeConflictColor(track, flightDataRecord) - }; - - - case LabelConstants.LabelItemMntFlags: - - if (mntflagToggled) - return new CustomLabelItem - { - Text = c3.ToString(), - ForeColourIdentity = excludeConflict ? Colours.Identities.Custom : default, - CustomForeColour = ExcludeConflictColor(track, flightDataRecord) - }; - - return new CustomLabelItem - { - Text = "" - }; - - - case LabelConstants.LabelItemScc: - - { - return new CustomLabelItem - { - Text = d1, - ForeColourIdentity = Colours.Identities.Custom, - CustomForeColour = CustomColors.SpecialConditionCode - }; - } - - - case LabelConstants.LabelItemAnnotInd: - var scratch = string.IsNullOrEmpty(flightDataRecord.LabelOpData); - - if (scratch) - return new CustomLabelItem - { - Text = "◦", - ForeColourIdentity = excludeConflict ? Colours.Identities.Custom : default, - CustomForeColour = ExcludeConflictColor(track, flightDataRecord) - }; - - return new CustomLabelItem - { - Text = "&", - ForeColourIdentity = excludeConflict ? Colours.Identities.Custom : default, - CustomForeColour = ExcludeConflictColor(track, flightDataRecord) - }; - - case LabelConstants.LabelItemRestr: - - if (flightDataRecord.LabelOpData.Contains("AT ") || flightDataRecord.LabelOpData.Contains(" BY ") || - flightDataRecord.LabelOpData.Contains("CLEARED TO ")) - - return new CustomLabelItem - { - Text = "x", - ForeColourIdentity = excludeConflict ? Colours.Identities.Custom : default, - CustomForeColour = ExcludeConflictColor(track, flightDataRecord) - }; - - return null; - - case LabelConstants.LabelItemLevel: - - var level = prl == -1 ? null : (radarTrack.CorrectedAltitude / 100).ToString(); - - - return new CustomLabelItem - { - Text = level, - Border = notProbe, - BorderColourIdentity = Colours.Identities.Custom, - CustomBorderColour = CustomColors.NotCda, - ForeColourIdentity = excludeConflict ? Colours.Identities.Custom : default, - CustomForeColour = colour - }; - - case LabelConstants.LabelItemVmi: - - return new CustomLabelItem - { - Text = h1.ToString(), - ForeColourIdentity = excludeConflict ? Colours.Identities.Custom : default, - CustomForeColour = colour - }; - - - case LabelConstants.LabelItemClearedLevel: - - - if (radarTrack.ReachedCFL || prl == alt || Math.Abs(flightDataRecord.PRL - alt) < 300) - return new CustomLabelItem - { - Text = "" - }; - - return new CustomLabelItem - { - Text = alt.ToString(), - Border = notProbe, - BorderColourIdentity = Colours.Identities.Custom, - CustomBorderColour = CustomColors.NotCda, - ForeColourIdentity = excludeConflict ? Colours.Identities.Custom : default, - CustomForeColour = colour - }; - - // case LABEL_ITEM_HANDOFF_IND: -// -// -// if (flightDataRecord.IsHandoff) -// { -// return new CustomLabelItem() -// { -// Text = "H" + flightDataRecord.HandoffSector.Name, -// }; -// } -// -// else if (flightDataRecord.State == FDR.FDRStates.STATE_HANDOVER_FIRST) -// { -// return new CustomLabelItem() -// { -// Text = "O" + flightDataRecord.HandoffSector.Name, -// }; -// } -// -// else -// { -// return new CustomLabelItem() -// { -// Text = "" -// }; -// } - - case LabelConstants.LabelItemRadarInd: - - - if (radarToggled) - return new CustomLabelItem - { - Text = "★", - OnMouseClick = HandleRadarFlagClick, - ForeColourIdentity = excludeConflict ? Colours.Identities.Custom : default, - CustomForeColour = ExcludeConflictColor(track, flightDataRecord) - }; - - return new CustomLabelItem - { - Text = "◦", - OnMouseClick = HandleRadarFlagClick, - ForeColourIdentity = excludeConflict ? Colours.Identities.Custom : default, - CustomForeColour = ExcludeConflictColor(track, flightDataRecord) - }; - - case LabelConstants.LabelItemInhibitInd: - - - if (flightDataRecord.State == FDR.FDRStates.STATE_INHIBITED) - return new CustomLabelItem - { - Text = "^", - ForeColourIdentity = excludeConflict ? Colours.Identities.Custom : default, - CustomForeColour = ExcludeConflictColor(track, flightDataRecord) - }; - - return new CustomLabelItem - { - Text = "" - }; - - - case LabelConstants.LabelItemFiledSpeed: - var mach = Conversions.CalculateMach(flightDataRecord.TAS, - GRIB.FindTemperature(flightDataRecord.PRL, track.GetLocation(), true)); - return new CustomLabelItem - { - Text = "M" + Convert.ToDecimal(mach).ToString("F2").Replace(".", ""), - //Text = "N" + flightDataRecord.TAS - ForeColourIdentity = excludeConflict ? Colours.Identities.Custom : default, - CustomForeColour = ExcludeConflictColor(track, flightDataRecord) - }; - - case LabelConstants.LabelItem3DigitGroundspeed: - //get groundspeed value from either FDR or radarTrack if coupled - var gs = radarTrack == null - ? flightDataRecord.PredictedPosition.Groundspeed - : radarTrack.GroundSpeed; - return new CustomLabelItem - { - Text = "N" + gs.ToString("000"), //format as 3 digits (with leading zeros) - ForeColourIdentity = excludeConflict ? Colours.Identities.Custom : default, - CustomForeColour = ExcludeConflictColor(track, flightDataRecord) - }; - - case LabelConstants.LabelItemDestination: - - return new CustomLabelItem - { - Text = flightDataRecord.DesAirport, - ForeColourIdentity = excludeConflict ? Colours.Identities.Custom : default, - CustomForeColour = ExcludeConflictColor(track, flightDataRecord) - }; - - default: - return null; - } - } - - public CustomColour SelectASDTrackColour(Track track) - { - var fdr = track.GetFDR(); - var fdr2 = track.GetFDR(); - //if track doesn't have an FDR coupled do nothing - if (fdr == null) - return null; - - - //only apply East/West colour to jurisdiction state - if (track.State == - MMI.HMIStates - .Jurisdiction) //read our dictionary of stored bools (true means is easterly) and return the correct colour - return GetConflictColour(fdr.Callsign) ?? GetDirectionColour(fdr.Callsign, fdr); - - if (fdr.State != - (FDR.FDRStates.STATE_PREACTIVE | - FDR.FDRStates.STATE_COORDINATED)) //only apply conflict colours if planes are of concern - return GetConflictColour(fdr.Callsign) ?? null; - - return default; - } - - public CustomColour SelectGroundTrackColour(Track track) - { - return null; - } - - - private void Network_RadioMessageAcknowledged(object sender, RadioMessageEventArgs e) - { - throw new NotImplementedException(); - } - - private void Network_PrivateMessagesChanged(object sender, Network.GenericMessageEventArgs e) - { - var downLink = e.Message.Sent; - - if (downLink) - downlink.TryRemove(e.Message.Address, out _); - else - downlink.TryAdd(e.Message.Address, 0); - } - - - private static void TOC(RDP.RadarTrack rt) - { - var fdr = rt.CoupledFDR; - if (fdr != null && rt != null) TransferOfControl(fdr); - } - - - private static void TransferOfControl(FDR fdr) - { - TOC toc; - toc = new TOC(fdr); - - var rt = fdr.CoupledTrack; - if (fdr != null) - if (!fdr.ESTed && MMI.IsMySectorConcerned(fdr)) - MMI.EstFDR(fdr); - - if (MMI.SectorsControlled.ToList() - .Exists(s => s.IsInSector(fdr.GetLocation(), fdr.PRL)) && !fdr.IsTrackedByMe && - !fdr.IsTracked) //MMI.SectorsControlled.Contains(fdr.ControllingSector) || fdr.ControllingSector == null - MMI.AcceptJurisdiction(fdr); - - - foreach (var volume in Volumes) - if (rt != null && (fdr.PRL == -1 || (fdr.PRL <= volume.UpperLevel && fdr.PRL > volume.LowerLevel)) && - Conversions.IsLatlonInPoly(fdr.GetLocation(), volume.Boundary)) - { - var whichVol = volume; - var whichFIR = FindSector(whichVol); - if (MMI.GetSectorEntryTime(fdr) == DateTime.MaxValue && MMI.SectorsControlled.ToList() - .TrueForAll(s => - !s.IsInSector(fdr.GetLocation(), fdr.PRL))) // && whichFIR != fdr.ControllingSector - - { - //toc.HandoffNextSector(); - MMI.HandoffJurisdiction(fdr, whichFIR); - MMI.Inhibit(fdr); - Thread.Sleep(300000); - RDP.DeCouple(rt); - } - } - } - - - private void HandleRadarFlagClick(CustomLabelItemMouseClickEventArgs e) - { - var radarToggled = radartoggle.TryGetValue(e.Track.GetFDR().Callsign, out _); - - if (radarToggled) - radartoggle.TryRemove(e.Track.GetFDR().Callsign, out _); - else - radartoggle.TryAdd(e.Track.GetFDR().Callsign, 0); - - e.Handled = true; - } - - private CustomColour GetDirectionColour(string callsign, FDR fdr) - { - if (eastboundCallsigns.TryGetValue(callsign, out var east)) - { - if (east) - return CustomColors.EastboundColour; - return CustomColors.WestboundColour; - } - - return default; - } - - private CustomColour GetConflictColour(string callsign) - { - if (imminentConflict.Count % 2 == 0 && imminentConflict.TryGetValue(callsign, out _)) - return CustomColors.Imminent; - if (advisoryConflict.Count % 2 == 0 && advisoryConflict.TryGetValue(callsign, out _)) return CustomColors.Advisory; - - return default; - } - - private CustomColour ExcludeConflictColor(Track track, FDR flightDataRecord) - { - if ((imminentConflict.Count > 0 || advisoryConflict.Count > 0) && track.State == MMI.HMIStates.Jurisdiction) - return GetDirectionColour(flightDataRecord.Callsign, flightDataRecord); - if (imminentConflict.Count > 0 || advisoryConflict.Count > 0) return CustomColors.ApsBlue; - return default; - } - } -} \ No newline at end of file diff --git a/AuroraLabelItemsPlugin.csproj b/AuroraLabelItemsPlugin.csproj index 107de4c..f8bfb3b 100644 --- a/AuroraLabelItemsPlugin.csproj +++ b/AuroraLabelItemsPlugin.csproj @@ -50,8 +50,6 @@ - - @@ -60,8 +58,6 @@ - - @@ -79,7 +75,6 @@ - \ No newline at end of file diff --git a/AuroraStripItemPlugin.cs b/AuroraStripItemPlugin.cs deleted file mode 100644 index 4cd62ec..0000000 --- a/AuroraStripItemPlugin.cs +++ /dev/null @@ -1,547 +0,0 @@ -//<--Need to add a reference to System.ComponentModel.Composition -using System.Collections.Concurrent; -using System.ComponentModel.Composition; -using System.Text.RegularExpressions; -using AuroraLabelItemsPlugin; -using vatsys; -using vatsys.Plugin; -using static vatsys.FDP2; - -namespace AuroraStripItemsPlugin -{ - [Export(typeof(IPlugin))] - public class AuroraStripItemsPlugin : IStripPlugin - { - - private readonly ConcurrentDictionary eastboundCallsigns = - new ConcurrentDictionary(); - - private readonly ConcurrentDictionary flagtoggle = new ConcurrentDictionary(); - - /// Plugin Name - public string Name => "Aurora Label Items"; - - public void OnFDRUpdate(FDR updated) - { - if (GetFDRIndex(updated.Callsign) == -1) //FDR was removed (that's what triggered the update) - { - eastboundCallsigns.TryRemove(updated.Callsign, out _); - flagtoggle.TryRemove(updated.Callsign, out _); - } - - else - - { - if (updated.ParsedRoute.Count > 1) - { - //calculate track from first route point to last (Departure point to destination point) - var rte = updated.ParsedRoute; - var trk = Conversions.CalculateTrack(rte.First().Intersection.LatLong, - rte.Last().Intersection.LatLong); - var east = trk >= 0 && trk < 180; - eastboundCallsigns.AddOrUpdate(updated.Callsign, east, (c, e) => east); - } - } - } - - /// This is called each time a radar track is updated - public void OnRadarTrackUpdate(RDP.RadarTrack updated) - { - } - - public CustomStripItem GetCustomStripItem(string itemType, Track track, FDR flightDataRecord, - RDP.RadarTrack radarTrack) - - { - var pbn = Regex.Match(flightDataRecord.Remarks, @"PBN\/\w+\s"); - var rnp10 = pbn.Value.Contains("A1"); - var rnp4 = pbn.Value.Contains("L1"); - var cpdlc = flightDataRecord.AircraftEquip.Contains("J5") || flightDataRecord.AircraftEquip.Contains("J7"); - var adsc = flightDataRecord.AircraftSurvEquip.Contains("D1"); - var adsb = flightDataRecord.ADSB; - var rvsm = flightDataRecord.RVSM; - var level = radarTrack == null ? flightDataRecord.PRL / 100 : radarTrack.CorrectedAltitude / 100; - var isEastBound = true; - eastboundCallsigns.TryGetValue(flightDataRecord.Callsign, out isEastBound); - var prl = flightDataRecord.PRL / 100; - var cfl = flightDataRecord.CFLUpper / 100; - var rfl = flightDataRecord.RFL / 100; - var alt = flightDataRecord.CFLUpper == -1 ? rfl : cfl; - - if (flightDataRecord == null) - return null; - - switch (itemType) - { - case StripConstants.StripItemCallsign: - - - if (isEastBound) - return new CustomStripItem - { - BackColourIdentity = Colours.Identities.StripText, - ForeColourIdentity = Colours.Identities.StripBackground, - Text = flightDataRecord.Callsign - }; - return new CustomStripItem - { - BackColourIdentity = Colours.Identities.StripBackground, - ForeColourIdentity = Colours.Identities.StripText, - Text = flightDataRecord.Callsign - }; - - case StripConstants.StripItemCtlsector: - - var pendingCoordination = flightDataRecord.State == - (FDR.FDRStates.STATE_PREACTIVE | FDR.FDRStates.STATE_COORDINATED); - var sectorName = flightDataRecord.ControllingSector == null - ? "" - : flightDataRecord.ControllingSector.Name; - - { - return new CustomStripItem - { - ForeColourIdentity = pendingCoordination ? Colours.Identities.Custom : default, - CustomForeColour = CustomColors.Pending, - Text = sectorName - }; - } - - - case StripConstants.StripItemNxtsector: - - TOC toc; - toc = new TOC(flightDataRecord); - - var firName = toc.nextSector == null ? "" : toc.nextSector.Name; - - { - return new CustomStripItem - { - ForeColourIdentity = Colours.Identities.Custom, - CustomForeColour = CustomColors.Pending, - Text = firName - }; - } - - - case StripConstants.LabelItemAdsbCpdlc: - - - if (!isEastBound && !adsb && cpdlc) - - return new CustomStripItem - { - BackColourIdentity = Colours.Identities.StripBackground, - ForeColourIdentity = Colours.Identities.StripText, - Text = "⧆" - }; - - if (isEastBound && !adsb && cpdlc) - - return new CustomStripItem - { - BackColourIdentity = Colours.Identities.StripText, - ForeColourIdentity = Colours.Identities.StripBackground, - Text = "⧆" - }; - - if (!isEastBound && !adsb) - - return new CustomStripItem - { - BackColourIdentity = Colours.Identities.StripBackground, - ForeColourIdentity = Colours.Identities.StripText, - Text = "⎕" - }; - - if (isEastBound && !adsb) - - return new CustomStripItem - { - BackColourIdentity = Colours.Identities.StripText, - ForeColourIdentity = Colours.Identities.StripBackground, - Text = "⎕" - }; - - if (!isEastBound && cpdlc) - - return new CustomStripItem - { - BackColourIdentity = Colours.Identities.StripBackground, - ForeColourIdentity = Colours.Identities.StripText, - Text = "*" - }; - - if (isEastBound && cpdlc) - - return new CustomStripItem - { - BackColourIdentity = Colours.Identities.StripText, - ForeColourIdentity = Colours.Identities.StripBackground, - Text = "*" - }; - - return null; - - case StripConstants.StripItemT10Flag: - - if (flightDataRecord.PerformanceData?.IsJet ?? false) - - return new CustomStripItem - { - //BackColourIdentity = Colours.Identities.Custom, - //CustomBackColour = SepFlags, - Text = "M" - //OnMouseClick = ItemMouseClick - }; - - return null; - - case StripConstants.StripItemMntFlag: - - if (flightDataRecord.PerformanceData?.IsJet ?? false) - - return new CustomStripItem - { - //BackColourIdentity = Colours.Identities.Custom, - //CustomBackColour = SepFlags, - Text = "R" - }; - - return null; - - case StripConstants.StripItemDistFlag: - - if (adsc & cpdlc & (rnp4 || rnp10)) - - - return new CustomStripItem - { - BackColourIdentity = Colours.Identities.Custom, - CustomBackColour = CustomColors.SepFlags, - Text = rnp4 ? "3" : "D" - }; - return null; - - case StripConstants.StripItemRvsmFlag: - - if (rvsm) - - return new CustomStripItem - { - BackColourIdentity = Colours.Identities.Custom, - CustomBackColour = CustomColors.SepFlags, - Text = "W" - }; - - return null; - - case StripConstants.StripItemVmi: - var vs = radarTrack == null - ? flightDataRecord.PredictedPosition.VerticalSpeed - : radarTrack.VerticalSpeed; - - if (level == cfl || level == flightDataRecord.RFL) //level - - return new CustomStripItem - { - Text = "" - }; - if ((cfl > level && track.NewCFL) || vs > 300) //Issued or trending climb - - return new CustomStripItem - { - Text = "↑" - }; - - if ((cfl > 0 && cfl < level && track.NewCFL) || vs < -300) //Issued or trending descent - - return new CustomStripItem - { - Text = "↓" - }; - - return null; - - case StripConstants.StripItemComplex: - - if (flightDataRecord.LabelOpData.Contains("AT ") || flightDataRecord.LabelOpData.Contains(" BY ") || - flightDataRecord.LabelOpData.Contains("CLEARED TO ")) - - return new CustomStripItem - { - Text = "*" - }; - - return null; - - case StripConstants.StripItemClearedLevel: - - if (cfl == 0) - return new CustomStripItem - { - Text = "" - }; - - return new CustomStripItem - { - Text = cfl.ToString() - }; - - case StripConstants.StripItemRequestedLevel: - - if (flightDataRecord.State == FDR.FDRStates.STATE_INACTIVE || - flightDataRecord.State == FDR.FDRStates.STATE_INACTIVE) - return new CustomStripItem - { - Text = rfl.ToString() - }; - - return new CustomStripItem - { - Text = "" - }; - - //case STRIP_ITEM_MAN_EST: - - //if (Estimates) - // return new CustomStripItem() - // { - // BackColourIdentity = Colours.Identities.HighlightedText - // }; - //return null; - - //case STRIP_ITEM_POINT: - // Coordinate coordinate = Conversions.ConvertToCoordinate(FDR.ExtractedRoute); - // - // if (StripItemType.Point == ) - // return new CustomStripItem() - // { - // Text = Conversions.ConvertToFlightplanLatLong() - // }; - case StripConstants.StripItemRoute: - - return new CustomStripItem - { - Text = "F" - //OnMouseClick = ItemMouseClick - }; - - - case StripConstants.StripItemRadarInd: - - return new CustomStripItem - { - Text = "A" - //OnMouseClick = - }; - - - case StripConstants.StripItemAnnotInd: - - var scratch = string.IsNullOrEmpty(flightDataRecord.LabelOpData); - - if (scratch) - return new CustomStripItem - { - Text = "." - }; - - return new CustomStripItem - { - Text = "&" - }; - - - case StripConstants.StripItemLateralFlag: - - if (adsc & cpdlc & rnp4 || rnp10) - - - return new CustomStripItem - { - BackColourIdentity = Colours.Identities.Custom, - CustomBackColour = CustomColors.SepFlags, - Text = rnp4 ? "4" : rnp10 ? "R" : "" - //OnMouseClick = ItemMouseClick - }; - return null; - - case StripConstants.StripItemRestr: - - if (flightDataRecord.LabelOpData.Contains("AT ") || flightDataRecord.LabelOpData.Contains(" BY ") || - flightDataRecord.LabelOpData.Contains("CLEARED TO ")) - - return new CustomStripItem - { - Text = "x" - }; - - return null; - - // case STRIP_ITEM_CLRD_RTE: - // - // return new CustomStripItem() - // { - // Text = "Cleared Route:" + flightDataRecord.RouteNoParse - // }; - // - // if (label.imminentConflict.TryGetValue(flightDataRecord.Callsign, out _) || (label.advisoryConflict.TryGetValue(flightDataRecord.Callsign, out)) == flightDataRecord.Callsign; - // - // case CPAR_ITEM_TYPE: - // - // return new CustomStripItem() - // { - // Text = - // }; - // - // case CPAR_ITEM_REQUIRED: - // - // return new CustomStripItem() - // { - // Text = cpar.Segments1[0].callsign - // }; - // - // case CPAR_ITEM_INTRUDER: - // - // return new CustomStripItem() - // { - // Text = cpar.Segments1[0].callsign - // }; - // - // case CPAR_ITEM_LOS: - // - // return new CustomStripItem() - // { - // Text = cpar.Segments1[0].callsign - // }; - // - // case CPAR_ITEM_ACTUAL: - // - // return new CustomStripItem() - // { - // Text = cpar.Segments1[0].callsign - // }; - // - // case CPAR_ITEM_PASSING: - // - // return new CustomStripItem() - // { - // Text = cpar.Segments1[0].callsign - // }; - // - // case CPAR_ITEM_CONF_SEG_START_1: - // - // return new CustomStripItem() - // { - // Text = cpar.Segments1[0].startLatlong.ToString() - // }; - // - // case CPAR_ITEM_CONF_SEG_START_2: - // - // return new CustomStripItem() - // { - // Text = cpar.Segments2[0].startLatlong.ToString() - // }; - // - // case CPAR_ITEM_CONF_SEG_END_1: - // - // return new CustomStripItem() - // { - // Text = cpar.Segments1[0].endLatlong.ToString() - // }; - // - // case CPAR_ITEM_CONF_SEG_END_2: - // - // return new CustomStripItem() - // { - // Text = cpar.Segments2[0].endLatlong.ToString() - // }; - // - // case CPAR_ITEM_STARTIME_1: - // - // return new CustomStripItem() - // { - // Text = cpar.Segments1[0].startTime.ToString() - // }; - // - // case CPAR_ITEM_STARTIME_2: - // - // return new CustomStripItem() - // { - // Text = cpar.Segments2[0].startTime.ToString() - // }; - // - // case CPAR_ITEM_ENDTIME_1: - // - // return new CustomStripItem() - // { - // Text = cpar.Segments1[0].endTime.ToString() - // }; - // - // case CPAR_ITEM_ENDTIME_2: - // - // return new CustomStripItem() - // { - // Text = cpar.Segments2[0].endTime.ToString() - // }; - // - // case CPAR_ITEM_AID_2: - // - // return new CustomStripItem() - // { - // Text = cpar.Segments2[0].callsign - // }; - // - // case CPAR_ITEM_TYP_2: - // - // return new CustomStripItem() - // { - // Text = - // }; - // - // case CPAR_ITEM_SPD_2: - // - // return new CustomStripItem() - // { - // Text = - // }; - // - // case CPAR_ITEM_ALT_2: - // - // return new CustomStripItem() - // { - // Text = - // }; - - default: return null; - } - } - - //public void Estimates(FDP2.FDR.ExtractedRoute.Segment estimate) - //{ - // estimate.IsPETO = true; - //} - - private void ItemMouseClick(CustomStripItemMouseClickEventArgs e) - { - var flagToggled = flagtoggle.TryGetValue(e.Track.GetFDR().Callsign, out _); - - if (flagToggled) - flagtoggle.TryRemove(e.Track.GetFDR().Callsign, out _); - else - flagtoggle.TryAdd(e.Track.GetFDR().Callsign, 0); - e.Handled = true; - } - //private CustomColour PETOColor(FDP2.FDR.ExtractedRoute.Segment estimate, Colours.Identities state) - //{ - // if (estimate.IsPETO) - // { - // return state = state; - // } - // - // return null; - //} - } -} \ No newline at end of file diff --git a/Conflict/ConflictProbe.cs b/Conflict/ConflictProbe.cs index a6de53e..b1f1d03 100644 --- a/Conflict/ConflictProbe.cs +++ b/Conflict/ConflictProbe.cs @@ -39,7 +39,7 @@ public List Probe(FDP2.FDR fdr) data.VerticalSep = MinimaCalculator.GetVerticalMinima(fdr, fdr2); if (data.VerticalAct >= data.VerticalSep) continue; - + data.LatSep = MinimaCalculator.GetLateralMinima(fdr, fdr2); // TODO(msalikhov): figure out what this was trying to do - it had no effect @@ -116,15 +116,12 @@ public List Probe(FDP2.FDR fdr) data.EarliestLos.Subtract(DateTime.UtcNow).Duration() && data.EarliestLos.Subtract(DateTime.UtcNow).Duration() >= new TimeSpan(0, 0, 30, 0, 0); //check if 2 hours > timediff > 30 mins - if (data.ActualConflicts || data.ImminentConflicts || data.AdvisoryConflicts) - { - discoveredConflicts.Add(data); - } + if (data.ActualConflicts || data.ImminentConflicts || data.AdvisoryConflicts) discoveredConflicts.Add(data); } return discoveredConflicts; } - + public record ConflictData { public bool ActualConflicts; diff --git a/Conflict/MinimaCalculator.cs b/Conflict/MinimaCalculator.cs index be743a4..362dd40 100644 --- a/Conflict/MinimaCalculator.cs +++ b/Conflict/MinimaCalculator.cs @@ -22,15 +22,9 @@ public static class MinimaCalculator public static int GetLateralMinima(FDP2.FDR fdr1, FDP2.FDR fdr2) { - if (CanApplyRnp4(fdr1) && CanApplyRnp4(fdr2)) - { - return Rnp4Lateral; - } + if (CanApplyRnp4(fdr1) && CanApplyRnp4(fdr2)) return Rnp4Lateral; - if (CanApplyRnp10(fdr1) && CanApplyRnp10(fdr2)) - { - return Rnp10Lateral; - } + if (CanApplyRnp10(fdr1) && CanApplyRnp10(fdr2)) return Rnp10Lateral; return StandardLateral; } @@ -41,19 +35,13 @@ public static int GetVerticalMinima(FDP2.FDR fdr1, FDP2.FDR fdr2) var block2 = AltitudeBlock.ExtractAltitudeBlock(fdr2); if (block1.IsAbove600() || block2.IsAbove600()) // technically this only applies if they are military - { return Above600Vertical; - } if (block1.IsAbove450() || block2.IsAbove450()) // technically this only applies if one is supersonic - { return SupersonicVertical; - } if (!(block1.IsBelowRvsm() || block2.IsBelowRvsm()) && (block1.IsAboveRvsm() || block2.IsAboveRvsm())) - { return NonRvsmVertical; - } return StandardVertical; } @@ -67,15 +55,10 @@ public static TimeSpan GetLongitudinalTime(FDP2.FDR fdr1, FDP2.FDR fdr2) public static int? GetLongitudinalDistance(FDP2.FDR fdr1, FDP2.FDR fdr2) { - if (CanApplyRnp4(fdr1) && CanApplyRnp4(fdr2)) - { - return Rnp4Longitudinal; - } + if (CanApplyRnp4(fdr1) && CanApplyRnp4(fdr2)) return Rnp4Longitudinal; if (HasDatalink(fdr1) && HasDatalink(fdr2) && CanApplyRnp10(fdr1) && CanApplyRnp10(fdr2)) - { return DistanceLongitudinal; - } return null; } diff --git a/FPAP.cs b/FPAP.cs deleted file mode 100644 index 8967d38..0000000 --- a/FPAP.cs +++ /dev/null @@ -1,103 +0,0 @@ -using System; -using System.Linq; -using System.Text.RegularExpressions; -using System.Threading; -using vatsys; -using static vatsys.SectorsVolumes; - -namespace AuroraLabelItemsPlugin -{ - public class FPAP - { - public bool adsc; - public int alt; - public int cfl; - public bool cpdlc; - public bool jet; - public bool pbcs; - public Match pbn; - public int prl; - public int rfl; - public bool rnp10; - public bool rnp4; - public Match sur; - public double vs; - - public void OnFDRUpdate(FDP2.FDR updated) - { - pbn = Regex.Match(updated.Remarks, @"PBN\/\w+\s"); - sur = Regex.Match(updated.Remarks, @"SUR\/\w+\s"); - rnp10 = pbn.Value.Contains("A1") && updated.AircraftEquip.Contains("R"); - rnp4 = pbn.Value.Contains("L1") && updated.AircraftEquip.Contains("R"); - pbcs = sur.Value.Contains("RSP180") && updated.AircraftSurvEquip.Contains("P2"); - cpdlc = updated.AircraftEquip.Contains("J5") || updated.AircraftEquip.Contains("J7"); - adsc = updated.AircraftSurvEquip.Contains("D1"); - jet = updated.PerformanceData?.IsJet ?? false; - vs = updated.PredictedPosition.VerticalSpeed; - prl = updated.PRL / 100; - cfl = updated.CFLUpper; - rfl = updated.RFL; - alt = cfl == -1 ? rfl : cfl; - } - - public void TOC(RDP.RadarTrack rt) - { - var fdr = rt.CoupledFDR; - if (fdr != null && rt != null) TransferOfControl(fdr); - } - - - public static void TransferOfControl(FDP2.FDR fdr) - { - TOC toc; - toc = new TOC(fdr); - - var rt = fdr.CoupledTrack; - if (fdr != null) - if (!fdr.ESTed && MMI.IsMySectorConcerned(fdr)) - MMI.EstFDR(fdr); - - if (MMI.SectorsControlled.ToList() - .Exists(s => s.IsInSector(fdr.GetLocation(), fdr.PRL)) && !fdr.IsTrackedByMe && - !fdr.IsTracked) //MMI.SectorsControlled.Contains(fdr.ControllingSector) || fdr.ControllingSector == null - MMI.AcceptJurisdiction(fdr); - - - foreach (var volume in Volumes) - if (rt != null && (fdr.PRL == -1 || (fdr.PRL <= volume.UpperLevel && fdr.PRL > volume.LowerLevel)) && - Conversions.IsLatlonInPoly(fdr.GetLocation(), volume.Boundary)) - { - var whichVol = volume; - var whichFIR = FindSector(whichVol); - if (MMI.GetSectorEntryTime(fdr) == DateTime.MaxValue && MMI.SectorsControlled.ToList() - .TrueForAll(s => - !s.IsInSector(fdr.GetLocation(), fdr.PRL))) // && whichFIR != fdr.ControllingSector - - { - //toc.HandoffNextSector(); - MMI.HandoffJurisdiction(fdr, whichFIR); - MMI.Inhibit(fdr); - Thread.Sleep(300000); - RDP.DeCouple(rt); - } - } - } - - //void SendNextDataAuthority(Network network, NetworkPilot pilot, VSCSFrequency freq) - //{ - // - // if (network.ValidATC && network.HaveConnection && !((DateTime.UtcNow - pilot.LastContactMe).TotalMinutes < 1.0)) - // { - // string text = "NEXT DATA AUTHORITY KZAK"; - // if (freq.AliasFrequency != VSCSFrequency.None.Frequency) - // { - // text = text + " (" + Conversions.FrequencyToString(freq.AliasFrequency) + ")"; - //Network.Instance.SendRadioMessage(radioMessage.FSDFrequencies, radioMessage.Address, "Unable", ThisRequiresResponse: false, radioMessage, CloseRequest: true); - // } - // - // network.SendTextMessage(pilot.Callsign, text); - // pilot.LastContactMe = DateTime.UtcNow; - // } - //} - } -} \ No newline at end of file diff --git a/GEO.cs b/GEO.cs deleted file mode 100644 index ac87952..0000000 --- a/GEO.cs +++ /dev/null @@ -1,602 +0,0 @@ -//<--Need to add a reference to System.ComponentModel.Composition -using System; -using System.Collections.Concurrent; -using System.Collections.Generic; -using System.ComponentModel.Composition; -using vatsys; -using vatsys.Plugin; -using static vatsys.FDP2; - - -//Note the reference to vatsys (set Copy Local to false) -----> - -namespace AuroraLabelItemsPlugin -{ - [Export(typeof(IPlugin))] - public class GEO : ILabelPlugin - { - /// The name of the custom label item we've added to Labels - /// in the Profile - private const string LABEL_ITEM_SELECT_HORI = "SELECT_HORI"; - - private const string LABEL_ITEM_SELECT_VERT = "SELECT_VERT"; - private const string LABEL_ITEM_COMM_ICON = "AURORA_COMM_ICON"; //field a(2) - private const string LABEL_ITEM_ADSB_CPDLC = "AURORA_ADSB_CPDLC"; //field c(4) - private const string LABEL_ITEM_ADS_FLAGS = "AURORA_ADS_FLAGS"; //field c(4) - private const string LABEL_ITEM_MNT_FLAGS = "AURORA_MNT_FLAGS"; //field c(4) - private const string LABEL_ITEM_SCC = "AURORA_SCC"; //field d(5) - private const string LABEL_ITEM_ANNOT_IND = "AURORA_ANNOT_IND"; //field e(1) - private const string LABEL_ITEM_RESTR = "AURORA_RESTR"; //field f(1) - private const string LABEL_ITEM_LEVEL = "AURORA_LEVEL"; //field g(3) - private const string LABEL_ITEM_VMI = "AURORA_VMI"; //field h(1) - private const string LABEL_ITEM_CLEARED_LEVEL = "AURORA_CLEARED_LEVEL"; //field i(7) - private const string LABEL_ITEM_HANDOFF_IND = "AURORA_HO_IND"; //field j(4) - private const string LABEL_ITEM_RADAR_IND = "AURORA_RADAR_IND"; //field k(1) - private const string LABEL_ITEM_INHIBIT_IND = "AURORA_INHIBIT_IND"; //field l(1) - private const string LABEL_ITEM_FILED_SPEED = "AURORA_FILEDSPEED"; //field m(4) - private const string LABEL_ITEM_3DIGIT_GROUNDSPEED = "AURORA_GROUNDSPEED"; //field n(5) - private const string LABEL_ITEM_DESTINATION = "AURORA_DESTINATION"; //field o(4) - private static readonly CustomColour EastboundColour = new CustomColour(240, 255, 255); - private static readonly CustomColour WestboundColour = new CustomColour(240, 231, 140); - private static readonly CustomColour NonRVSM = new CustomColour(242, 133, 0); - private static readonly CustomColour Probe = new CustomColour(0, 255, 0); - private static readonly CustomColour NotCDA = new CustomColour(100, 0, 100); - private static readonly CustomColour Advisory = new CustomColour(255, 165, 0); - private static readonly CustomColour Imminent = new CustomColour(255, 0, 0); - private static readonly CustomColour SpecialConditionCode = new CustomColour(255, 255, 0); - private static readonly CustomColour ApsBlue = new CustomColour(141, 182, 205); - private readonly ConcurrentDictionary adsbcpdlcValues = new ConcurrentDictionary(); - private readonly ConcurrentDictionary adsflagValues = new ConcurrentDictionary(); - - public readonly ConcurrentDictionary> advisoryConflict = - new ConcurrentDictionary>(); - - private readonly ConcurrentDictionary altValues = new ConcurrentDictionary(); - private readonly ConcurrentDictionary downlink = new ConcurrentDictionary(); - - private readonly ConcurrentDictionary eastboundCallsigns = - new ConcurrentDictionary(); - - public readonly ConcurrentDictionary> imminentConflict = - new ConcurrentDictionary>(); - - private readonly ConcurrentDictionary mntflagtoggle = new ConcurrentDictionary(); - private readonly ConcurrentDictionary mntflagValues = new ConcurrentDictionary(); - private readonly ConcurrentDictionary radartoggle = new ConcurrentDictionary(); - - private readonly ConcurrentDictionary - sccflagValues = new ConcurrentDictionary(); - - - public GEO() - { - Network.PrivateMessagesChanged += Network_PrivateMessagesChanged; - Network.RadioMessageAcknowledged += Network_RadioMessageAcknowledged; - } - - - /// Plugin Name - public string Name => "Aurora Label Items"; - - /// This is called each time a flight data record is updated - /// Here we are updating the eastbound callsigns dictionary with each flight data record - /// When the FDR is updated we check if it still exists in the Flight Data Processor and remove from our dictionary if not. Otherwise we do some simple regex matching to find - /// the flight planned PBN category and store the character we want to display in the label in the dictionary. - public void OnFDRUpdate(FDR updated) - { - var fpap = new FPAP(); - - - if (GetFDRIndex(updated.Callsign) == -1) - { - eastboundCallsigns.TryRemove(updated.Callsign, out _); - adsbcpdlcValues.TryRemove(updated.Callsign, out _); - adsflagValues.TryRemove(updated.Callsign, out _); - mntflagValues.TryRemove(updated.Callsign, out _); - sccflagValues.TryRemove(updated.Callsign, out _); - altValues.TryRemove(updated.Callsign, out _); - radartoggle.TryRemove(updated.Callsign, out _); - mntflagtoggle.TryRemove(updated.Callsign, out _); - downlink.TryRemove(updated.Callsign, out _); - advisoryConflict.TryRemove(updated.Callsign, out _); - imminentConflict.TryRemove(updated.Callsign, out _); - } - else - { - char c1 = default; - - if (!updated.ADSB && fpap.cpdlc) - - c1 = '⧆'; - - else if (!updated.ADSB) - - c1 = '⎕'; - - else if (fpap.cpdlc) - - c1 = '✱'; - - - adsbcpdlcValues.AddOrUpdate(updated.Callsign, c1, (k, v) => c1); - - char c2 = default; - - if (fpap.adsc & fpap.cpdlc & fpap.rnp4) - c2 = '3'; - - else if (fpap.adsc & fpap.cpdlc & fpap.rnp10) - c2 = 'D'; - - adsflagValues.AddOrUpdate(updated.Callsign, c2, (k, v) => c2); - - char c3 = default; - - if (updated.PerformanceData?.IsJet ?? false) - c3 = 'M'; - - mntflagValues.AddOrUpdate(updated.Callsign, c3, (k, v) => c3); - - NetworkPilot code; - code = new NetworkPilot(); - - var d1 = string.Empty; - - if (!fpap.rnp10 && !fpap.rnp4) - d1 = "RNP"; - - else if (code.TransponderCode == 7700) - d1 = "EMG"; - - else if (code.TransponderCode == 7600) - d1 = "RCF"; - - else if (code.TransponderCode == 7777) - d1 = "MTI"; - - else if (code.TransponderCode == 7700) - d1 = "EMG"; - - sccflagValues.AddOrUpdate(updated.Callsign, d1, (k, v) => d1); - - char h1 = default; - - if (Math.Abs(updated.PRL - fpap.alt) <= 299) //level flight - h1 = default; - - else if (fpap.alt / 100 > fpap.prl || fpap.vs > 300) //Issued or trending climb - h1 = '↑'; - - else if ((fpap.alt / 100 > 0 && fpap.alt < fpap.prl) || fpap.vs < -300) //Issued or trending descent - h1 = '↓'; - - else if (fpap.prl - fpap.alt / 100 >= 3) //deviating above - h1 = '+'; - - else if (fpap.prl - fpap.alt / 100 <= -3) //deviating below - h1 = '-'; - - - altValues.AddOrUpdate(updated.Callsign, h1, (k, v) => h1); - - if (updated.ParsedRoute.Count > 1) - { - //calculate track from first route point to last (Departure point to destination point) - var rte = updated.ParsedRoute; - var trk = Conversions.CalculateTrack(rte.First().Intersection.LatLong, - rte.Last().Intersection.LatLong); - var east = trk >= 0 && trk < 180; - eastboundCallsigns.AddOrUpdate(updated.Callsign, east, (c, e) => east); - } - - FPAP.TransferOfControl(updated); - - var cpar = new CPAR(); - var reqLat = new CPAR.ConflictData(); - - cpar.ConflictProbe(updated, reqLat.latSep); - } - } - - /// Could use the new position of the radar track or its change in state (cancelled, etc.) to do some processing. - public void OnRadarTrackUpdate(RDP.RadarTrack updated) - { - } - - - /// vatSys calls this function when it encounters a custom label item (defined in Labels.xml) during the label rendering. - /// itemType is the value of the Type attribute in Labels.xml - /// If it's not our item being called (another plugins, for example), return null. - /// As a general rule, don't do processing in here as you'll slow down the ASD refresh. In the case of parsing a level to a string though, that's fine. - public CustomLabelItem GetCustomLabelItem(string itemType, Track track, FDR flightDataRecord, - RDP.RadarTrack radarTrack) - { - var fpap = new FPAP(); - - if (flightDataRecord == null || radarTrack == null) - return null; - - char c1; - adsbcpdlcValues.TryGetValue(flightDataRecord.Callsign, out c1); - char c2; - adsflagValues.TryGetValue(flightDataRecord.Callsign, out c2); - char c3; - mntflagValues.TryGetValue(flightDataRecord.Callsign, out c3); - string d1; - sccflagValues.TryGetValue(flightDataRecord.Callsign, out d1); - char h1; - altValues.TryGetValue(flightDataRecord.Callsign, out h1); - - - var radarToggled = radartoggle.TryGetValue(flightDataRecord.Callsign, out _); - var mntflagToggled = mntflagtoggle.TryGetValue(flightDataRecord.Callsign, out _); - var downLink = downlink.TryGetValue(flightDataRecord.Callsign, out _); - var isNonRVSM = !flightDataRecord.RVSM; - var notProbe = flightDataRecord.State == (FDR.FDRStates.STATE_PREACTIVE | FDR.FDRStates.STATE_COORDINATED) - ? BorderFlags.All - : BorderFlags.None; - var colour = !flightDataRecord.RVSM ? NonRVSM : ExcludeConflictColor(track, flightDataRecord); - var excludeConflict = SelectASDTrackColour(track) == GetConflictColour(flightDataRecord.Callsign); - - switch (itemType) - - { - case LABEL_ITEM_SELECT_HORI: - - if (MMI.SelectedTrack?.GetFDR()?.Callsign == track.GetFDR().Callsign) - return new CustomLabelItem - { - Text = "", - Border = BorderFlags.Bottom - }; - - return null; - - case LABEL_ITEM_SELECT_VERT: - - if (MMI.SelectedTrack?.GetFDR()?.Callsign == track.GetFDR().Callsign) - return new CustomLabelItem - { - Text = "", - Border = BorderFlags.Left - }; - - return null; - - case LABEL_ITEM_COMM_ICON: - - if (downLink) - return new CustomLabelItem - { - Text = "▼", - Border = BorderFlags.All, - ForeColourIdentity = excludeConflict ? Colours.Identities.Custom : default, - CustomForeColour = ExcludeConflictColor(track, flightDataRecord) - }; - return new CustomLabelItem - { - Text = "⬜", - ForeColourIdentity = excludeConflict ? Colours.Identities.Custom : default, - CustomForeColour = ExcludeConflictColor(track, flightDataRecord) - }; - case LABEL_ITEM_ADSB_CPDLC: - - var useCustomForeColour = - flightDataRecord.State == (FDR.FDRStates.STATE_PREACTIVE | FDR.FDRStates.STATE_COORDINATED); - - if (useCustomForeColour) - return new CustomLabelItem - { - ForeColourIdentity = Colours.Identities.Custom, - CustomForeColour = NotCDA, - Text = c1.ToString() - }; - return new CustomLabelItem - { - Text = c1.ToString(), - ForeColourIdentity = excludeConflict ? Colours.Identities.Custom : default, - CustomForeColour = ExcludeConflictColor(track, flightDataRecord) - }; - - case LABEL_ITEM_ADS_FLAGS: - - return new CustomLabelItem - { - Text = c2.ToString(), - ForeColourIdentity = excludeConflict ? Colours.Identities.Custom : default, - CustomForeColour = ExcludeConflictColor(track, flightDataRecord) - }; - - - case LABEL_ITEM_MNT_FLAGS: - - if (mntflagToggled) - return new CustomLabelItem - { - Text = c3.ToString(), - ForeColourIdentity = excludeConflict ? Colours.Identities.Custom : default, - CustomForeColour = ExcludeConflictColor(track, flightDataRecord) - }; - - return new CustomLabelItem - { - Text = "" - }; - - - case LABEL_ITEM_SCC: - - { - return new CustomLabelItem - { - Text = d1, - ForeColourIdentity = Colours.Identities.Custom, - CustomForeColour = SpecialConditionCode - }; - } - - - case LABEL_ITEM_ANNOT_IND: - var scratch = string.IsNullOrEmpty(flightDataRecord.LabelOpData); - - if (scratch) - return new CustomLabelItem - { - Text = "◦", - ForeColourIdentity = excludeConflict ? Colours.Identities.Custom : default, - CustomForeColour = ExcludeConflictColor(track, flightDataRecord) - }; - - return new CustomLabelItem - { - Text = "&", - ForeColourIdentity = excludeConflict ? Colours.Identities.Custom : default, - CustomForeColour = ExcludeConflictColor(track, flightDataRecord) - }; - - case LABEL_ITEM_RESTR: - - if (flightDataRecord.LabelOpData.Contains("AT ") || flightDataRecord.LabelOpData.Contains(" BY ") || - flightDataRecord.LabelOpData.Contains("CLEARED TO ")) - - return new CustomLabelItem - { - Text = "x", - ForeColourIdentity = excludeConflict ? Colours.Identities.Custom : default, - CustomForeColour = ExcludeConflictColor(track, flightDataRecord) - }; - - return null; - - case LABEL_ITEM_LEVEL: - - var level = fpap.prl == -1 ? null : (radarTrack.CorrectedAltitude / 100).ToString(); - - - return new CustomLabelItem - { - Text = level, - Border = notProbe, - BorderColourIdentity = Colours.Identities.Custom, - CustomBorderColour = NotCDA, - ForeColourIdentity = excludeConflict ? Colours.Identities.Custom : default, - CustomForeColour = colour - }; - - case LABEL_ITEM_VMI: - - return new CustomLabelItem - { - Text = h1.ToString(), - ForeColourIdentity = excludeConflict ? Colours.Identities.Custom : default, - CustomForeColour = colour - }; - - - case LABEL_ITEM_CLEARED_LEVEL: - - - if (radarTrack.ReachedCFL || fpap.prl == fpap.alt || - Math.Abs(flightDataRecord.PRL - fpap.alt) < 300) - return new CustomLabelItem - { - Text = "" - }; - - return new CustomLabelItem - { - Text = fpap.alt.ToString(), - Border = notProbe, - BorderColourIdentity = Colours.Identities.Custom, - CustomBorderColour = NotCDA, - ForeColourIdentity = excludeConflict ? Colours.Identities.Custom : default, - CustomForeColour = colour - }; - - // case LABEL_ITEM_HANDOFF_IND: -// -// -// if (flightDataRecord.IsHandoff) -// { -// return new CustomLabelItem() -// { -// Text = "H" + flightDataRecord.HandoffSector.Name, -// }; -// } -// -// else if (flightDataRecord.State == FDR.FDRStates.STATE_HANDOVER_FIRST) -// { -// return new CustomLabelItem() -// { -// Text = "O" + flightDataRecord.HandoffSector.Name, -// }; -// } -// -// else -// { -// return new CustomLabelItem() -// { -// Text = "" -// }; -// } - - case LABEL_ITEM_RADAR_IND: - - - if (radarToggled) - return new CustomLabelItem - { - Text = "★", - OnMouseClick = HandleRadarFlagClick, - ForeColourIdentity = excludeConflict ? Colours.Identities.Custom : default, - CustomForeColour = ExcludeConflictColor(track, flightDataRecord) - }; - - return new CustomLabelItem - { - Text = "◦", - OnMouseClick = HandleRadarFlagClick, - ForeColourIdentity = excludeConflict ? Colours.Identities.Custom : default, - CustomForeColour = ExcludeConflictColor(track, flightDataRecord) - }; - - case LABEL_ITEM_INHIBIT_IND: - - - if (flightDataRecord.State == FDR.FDRStates.STATE_INHIBITED) - return new CustomLabelItem - { - Text = "^", - ForeColourIdentity = excludeConflict ? Colours.Identities.Custom : default, - CustomForeColour = ExcludeConflictColor(track, flightDataRecord) - }; - - return new CustomLabelItem - { - Text = "" - }; - - - case LABEL_ITEM_FILED_SPEED: - var mach = Conversions.CalculateMach(flightDataRecord.TAS, - GRIB.FindTemperature(flightDataRecord.PRL, track.GetLocation(), true)); - return new CustomLabelItem - { - Text = "M" + Convert.ToDecimal(mach).ToString("F2").Replace(".", ""), - //Text = "N" + flightDataRecord.TAS - ForeColourIdentity = excludeConflict ? Colours.Identities.Custom : default, - CustomForeColour = ExcludeConflictColor(track, flightDataRecord) - }; - - case LABEL_ITEM_3DIGIT_GROUNDSPEED: - //get groundspeed value from either FDR or radarTrack if coupled - var gs = radarTrack == null - ? flightDataRecord.PredictedPosition.Groundspeed - : radarTrack.GroundSpeed; - return new CustomLabelItem - { - Text = "N" + gs.ToString("000"), //format as 3 digits (with leading zeros) - ForeColourIdentity = excludeConflict ? Colours.Identities.Custom : default, - CustomForeColour = ExcludeConflictColor(track, flightDataRecord) - }; - - case LABEL_ITEM_DESTINATION: - - return new CustomLabelItem - { - Text = flightDataRecord.DesAirport, - ForeColourIdentity = excludeConflict ? Colours.Identities.Custom : default, - CustomForeColour = ExcludeConflictColor(track, flightDataRecord) - }; - - default: - return null; - } - } - - public CustomColour SelectASDTrackColour(Track track) - { - var fdr = track.GetFDR(); - var fdr2 = track.GetFDR(); - //if track doesn't have an FDR coupled do nothing - if (fdr == null) - return null; - - - //only apply East/West colour to jurisdiction state - if (track.State == - MMI.HMIStates - .Jurisdiction) //read our dictionary of stored bools (true means is easterly) and return the correct colour - return GetConflictColour(fdr.Callsign) ?? GetDirectionColour(fdr.Callsign, fdr); - - if (fdr.State != - (FDR.FDRStates.STATE_PREACTIVE | - FDR.FDRStates.STATE_COORDINATED)) //only apply conflict colours if planes are of concern - return GetConflictColour(fdr.Callsign) ?? null; - - return default; - } - - public CustomColour SelectGroundTrackColour(Track track) - { - return null; - } - - - private void Network_RadioMessageAcknowledged(object sender, RadioMessageEventArgs e) - { - throw new NotImplementedException(); - } - - private void Network_PrivateMessagesChanged(object sender, Network.GenericMessageEventArgs e) - { - var downLink = e.Message.Sent; - - if (downLink) - downlink.TryRemove(e.Message.Address, out _); - else - downlink.TryAdd(e.Message.Address, 0); - } - - private void HandleRadarFlagClick(CustomLabelItemMouseClickEventArgs e) - { - var radarToggled = radartoggle.TryGetValue(e.Track.GetFDR().Callsign, out _); - - if (radarToggled) - radartoggle.TryRemove(e.Track.GetFDR().Callsign, out _); - else - radartoggle.TryAdd(e.Track.GetFDR().Callsign, 0); - - e.Handled = true; - } - - private CustomColour GetDirectionColour(string callsign, FDR fdr) - { - if (eastboundCallsigns.TryGetValue(callsign, out var east)) - { - if (east) - return EastboundColour; - return WestboundColour; - } - - return default; - } - - private CustomColour GetConflictColour(string callsign) - { - if (imminentConflict.Count % 2 == 0 && imminentConflict.TryGetValue(callsign, out _)) - return Imminent; - if (advisoryConflict.Count % 2 == 0 && advisoryConflict.TryGetValue(callsign, out _)) return Advisory; - - return default; - } - - private CustomColour ExcludeConflictColor(Track track, FDR flightDataRecord) - { - if ((imminentConflict.Count > 0 || advisoryConflict.Count > 0) && track.State == MMI.HMIStates.Jurisdiction) - return GetDirectionColour(flightDataRecord.Callsign, flightDataRecord); - if (imminentConflict.Count > 0 || advisoryConflict.Count > 0) return ApsBlue; - return default; - } - } -} \ No newline at end of file diff --git a/Logic/FlightDataCalculator.cs b/Logic/FlightDataCalculator.cs index f2ba69e..9b55b58 100644 --- a/Logic/FlightDataCalculator.cs +++ b/Logic/FlightDataCalculator.cs @@ -16,6 +16,7 @@ public static class FlightDataCalculator private const string Rcp240SurvEquip = "P2"; private const string PbnEquip = "R"; + private static readonly string[] CpdlcEquip = { "J5", "J7" diff --git a/TOC.cs b/TOC.cs deleted file mode 100644 index 8bd4645..0000000 --- a/TOC.cs +++ /dev/null @@ -1,53 +0,0 @@ -#region Assembly vatSys, Version=0.4.8114.34539, Culture=neutral, PublicKeyToken=null - -// E:\vatsys\bin\vatSys.exe -// Decompiled with ICSharpCode.Decompiler 7.1.0.6543 - -#endregion - -using System; -using System.Collections.Generic; -using System.Linq; - -namespace vatsys -{ - public class TOC - { - public FDP2.FDR fdr; - - public SectorsVolumes.Sector nextSector; - - public List sectors; - - public TOC(FDP2.FDR fdr) - { - this.fdr = fdr; - var segment = (from s in fdr.ParsedRoute.ToList() - where s.Type == FDP2.FDR.ExtractedRoute.Segment.SegmentTypes.ZPOINT && fdr.ControllingSector != - SectorsVolumes.FindSector((SectorsVolumes.Volume)s.Tag) - select s).FirstOrDefault(s => s.ETO > DateTime.UtcNow); - SectorsVolumes.Volume volume = null; - if (segment != null) volume = (SectorsVolumes.Volume)segment.Tag; - - if (volume != null) - nextSector = SectorsVolumes.FindSector(volume); - else - nextSector = null; - - if (nextSector != null) - { - SectorsVolumes.Sector sector = null; - foreach (var s2 in SectorsVolumes.SectorGroupings.Keys) - if (s2.SubSectors.Contains(nextSector) && - (sector == null || sector.SubSectors.Count > s2.SubSectors.Count)) - sector = s2; - if (sector != null) nextSector = sector; - } - } - - public void HandoffNextSector() - { - if (nextSector != null) MMI.HandoffJurisdiction(fdr, nextSector); - } - } -} \ No newline at end of file From 1104d1864238a42dffe5acd77f13fe15427242e6 Mon Sep 17 00:00:00 2001 From: Maxim Salikhov Date: Sun, 25 Feb 2024 00:52:59 -0500 Subject: [PATCH 53/76] Rename to AtopPlugin --- AtopPlugin.cs | 6 +++--- AuroraLabelItemsPlugin.csproj => AtopPlugin.csproj | 4 ++-- AuroraLabelItemsPlugin.sln => AtopPlugin.sln | 2 +- Conflict/ConflictAreaCalculator.cs | 2 +- Conflict/ConflictProbe.cs | 4 ++-- Conflict/MinimaCalculator.cs | 4 ++-- Constants.cs | 2 +- Display/LabelItemRenderer.cs | 4 ++-- Display/StripItemRenderer.cs | 4 ++-- Display/TrackColorRenderer.cs | 4 ++-- Extensions.cs | 4 ++-- Logic/AltitudeCalculator.cs | 4 ++-- Logic/FlightDataCalculator.cs | 4 ++-- Logic/NextSectorCalculator.cs | 2 +- Logic/SccFlagCalculator.cs | 4 ++-- Models/AltitudeBlock.cs | 2 +- Models/AltitudeFlag.cs | 2 +- Models/CalculatedFlightData.cs | 2 +- Models/ConflictType.cs | 2 +- Models/DirectionOfFlight.cs | 2 +- Models/SccFlag.cs | 2 +- State/AtopAircraftDisplayState.cs | 6 +++--- State/AtopAircraftState.cs | 6 +++--- State/AtopPluginStateManager.cs | 2 +- State/JurisdictionManager.cs | 2 +- State/PrivateMessagesChangedHandler.cs | 2 +- State/RadarFlagToggleHandler.cs | 2 +- 27 files changed, 43 insertions(+), 43 deletions(-) rename AuroraLabelItemsPlugin.csproj => AtopPlugin.csproj (96%) rename AuroraLabelItemsPlugin.sln => AtopPlugin.sln (86%) diff --git a/AtopPlugin.cs b/AtopPlugin.cs index d6a0021..ae854c8 100644 --- a/AtopPlugin.cs +++ b/AtopPlugin.cs @@ -1,10 +1,10 @@ using System.ComponentModel.Composition; -using AuroraLabelItemsPlugin.Display; -using AuroraLabelItemsPlugin.State; +using AtopPlugin.Display; +using AtopPlugin.State; using vatsys; using vatsys.Plugin; -namespace AuroraLabelItemsPlugin; +namespace AtopPlugin; [Export(typeof(IPlugin))] public class AtopPlugin : ILabelPlugin, IStripPlugin diff --git a/AuroraLabelItemsPlugin.csproj b/AtopPlugin.csproj similarity index 96% rename from AuroraLabelItemsPlugin.csproj rename to AtopPlugin.csproj index f8bfb3b..0293244 100644 --- a/AuroraLabelItemsPlugin.csproj +++ b/AtopPlugin.csproj @@ -7,8 +7,8 @@ {59170BAC-129C-4AB8-884D-F583E460AA63} Library Properties - AuroraLabelItemsPlugin - AuroraLabelItemsPlugin + AtopPlugin + AtopPlugin v4.8 512 true diff --git a/AuroraLabelItemsPlugin.sln b/AtopPlugin.sln similarity index 86% rename from AuroraLabelItemsPlugin.sln rename to AtopPlugin.sln index 97c859f..f982761 100644 --- a/AuroraLabelItemsPlugin.sln +++ b/AtopPlugin.sln @@ -3,7 +3,7 @@ Microsoft Visual Studio Solution File, Format Version 12.00 # Visual Studio Version 16 VisualStudioVersion = 16.0.30711.63 MinimumVisualStudioVersion = 10.0.40219.1 -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "AuroraLabelItemsPlugin", "AuroraLabelItemsPlugin.csproj", "{59170BAC-129C-4AB8-884D-F583E460AA63}" +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "AtopPlugin", "AtopPlugin.csproj", "{59170BAC-129C-4AB8-884D-F583E460AA63}" EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution diff --git a/Conflict/ConflictAreaCalculator.cs b/Conflict/ConflictAreaCalculator.cs index 5e23365..308cd9d 100644 --- a/Conflict/ConflictAreaCalculator.cs +++ b/Conflict/ConflictAreaCalculator.cs @@ -3,7 +3,7 @@ using System.Linq; using vatsys; -namespace AuroraLabelItemsPlugin.Conflict; +namespace AtopPlugin.Conflict; public static class ConflictAreaCalculator { diff --git a/Conflict/ConflictProbe.cs b/Conflict/ConflictProbe.cs index b1f1d03..a184280 100644 --- a/Conflict/ConflictProbe.cs +++ b/Conflict/ConflictProbe.cs @@ -1,10 +1,10 @@ using System; using System.Collections.Generic; using System.Linq; -using AuroraLabelItemsPlugin.Models; +using AtopPlugin.Models; using vatsys; -namespace AuroraLabelItemsPlugin.Conflict; +namespace AtopPlugin.Conflict; public class ConflictProbe { diff --git a/Conflict/MinimaCalculator.cs b/Conflict/MinimaCalculator.cs index 362dd40..749f293 100644 --- a/Conflict/MinimaCalculator.cs +++ b/Conflict/MinimaCalculator.cs @@ -1,8 +1,8 @@ using System; -using AuroraLabelItemsPlugin.Models; +using AtopPlugin.Models; using vatsys; -namespace AuroraLabelItemsPlugin.Conflict; +namespace AtopPlugin.Conflict; public static class MinimaCalculator { diff --git a/Constants.cs b/Constants.cs index 2067696..3a8d9c7 100644 --- a/Constants.cs +++ b/Constants.cs @@ -1,6 +1,6 @@ using vatsys.Plugin; -namespace AuroraLabelItemsPlugin; +namespace AtopPlugin; public static class CustomColors { diff --git a/Display/LabelItemRenderer.cs b/Display/LabelItemRenderer.cs index 28e989a..43222dd 100644 --- a/Display/LabelItemRenderer.cs +++ b/Display/LabelItemRenderer.cs @@ -1,9 +1,9 @@ #nullable enable -using AuroraLabelItemsPlugin.State; +using AtopPlugin.State; using vatsys; using vatsys.Plugin; -namespace AuroraLabelItemsPlugin.Display; +namespace AtopPlugin.Display; public static class LabelItemRenderer { diff --git a/Display/StripItemRenderer.cs b/Display/StripItemRenderer.cs index c662251..fcebee3 100644 --- a/Display/StripItemRenderer.cs +++ b/Display/StripItemRenderer.cs @@ -1,9 +1,9 @@ #nullable enable -using AuroraLabelItemsPlugin.Models; +using AtopPlugin.Models; using vatsys; using vatsys.Plugin; -namespace AuroraLabelItemsPlugin.Display; +namespace AtopPlugin.Display; public static class StripItemRenderer { diff --git a/Display/TrackColorRenderer.cs b/Display/TrackColorRenderer.cs index 5b72abe..25ff0b9 100644 --- a/Display/TrackColorRenderer.cs +++ b/Display/TrackColorRenderer.cs @@ -1,8 +1,8 @@ -using AuroraLabelItemsPlugin.Models; +using AtopPlugin.Models; using vatsys; using vatsys.Plugin; -namespace AuroraLabelItemsPlugin.Display; +namespace AtopPlugin.Display; public static class TrackColorRenderer { diff --git a/Extensions.cs b/Extensions.cs index fec5bfe..6356de4 100644 --- a/Extensions.cs +++ b/Extensions.cs @@ -1,7 +1,7 @@ -using AuroraLabelItemsPlugin.State; +using AtopPlugin.State; using vatsys; -namespace AuroraLabelItemsPlugin; +namespace AtopPlugin; public static class Extensions { diff --git a/Logic/AltitudeCalculator.cs b/Logic/AltitudeCalculator.cs index f724f5e..5e846ff 100644 --- a/Logic/AltitudeCalculator.cs +++ b/Logic/AltitudeCalculator.cs @@ -1,8 +1,8 @@ #nullable enable -using AuroraLabelItemsPlugin.Models; +using AtopPlugin.Models; using vatsys; -namespace AuroraLabelItemsPlugin.Logic; +namespace AtopPlugin.Logic; public static class AltitudeCalculator { diff --git a/Logic/FlightDataCalculator.cs b/Logic/FlightDataCalculator.cs index 9b55b58..2138b5c 100644 --- a/Logic/FlightDataCalculator.cs +++ b/Logic/FlightDataCalculator.cs @@ -1,9 +1,9 @@ using System.Linq; using System.Text.RegularExpressions; -using AuroraLabelItemsPlugin.Models; +using AtopPlugin.Models; using vatsys; -namespace AuroraLabelItemsPlugin.Logic; +namespace AtopPlugin.Logic; public static class FlightDataCalculator { diff --git a/Logic/NextSectorCalculator.cs b/Logic/NextSectorCalculator.cs index 67cf92d..9e7cba3 100644 --- a/Logic/NextSectorCalculator.cs +++ b/Logic/NextSectorCalculator.cs @@ -3,7 +3,7 @@ using System.Linq; using vatsys; -namespace AuroraLabelItemsPlugin.Logic; +namespace AtopPlugin.Logic; public static class NextSectorCalculator { diff --git a/Logic/SccFlagCalculator.cs b/Logic/SccFlagCalculator.cs index 2820590..58e611c 100644 --- a/Logic/SccFlagCalculator.cs +++ b/Logic/SccFlagCalculator.cs @@ -1,8 +1,8 @@ #nullable enable -using AuroraLabelItemsPlugin.Models; +using AtopPlugin.Models; using vatsys; -namespace AuroraLabelItemsPlugin.Logic; +namespace AtopPlugin.Logic; public static class SccFlagCalculator { diff --git a/Models/AltitudeBlock.cs b/Models/AltitudeBlock.cs index 4619cae..25a7c16 100644 --- a/Models/AltitudeBlock.cs +++ b/Models/AltitudeBlock.cs @@ -1,6 +1,6 @@ using vatsys; -namespace AuroraLabelItemsPlugin.Models; +namespace AtopPlugin.Models; public record struct AltitudeBlock(int LowerAltitude, int UpperAltitude) { diff --git a/Models/AltitudeFlag.cs b/Models/AltitudeFlag.cs index f883fd9..949d5fd 100644 --- a/Models/AltitudeFlag.cs +++ b/Models/AltitudeFlag.cs @@ -1,4 +1,4 @@ -namespace AuroraLabelItemsPlugin.Models; +namespace AtopPlugin.Models; public class AltitudeFlag { diff --git a/Models/CalculatedFlightData.cs b/Models/CalculatedFlightData.cs index 95a2a91..32d88aa 100644 --- a/Models/CalculatedFlightData.cs +++ b/Models/CalculatedFlightData.cs @@ -1,4 +1,4 @@ -namespace AuroraLabelItemsPlugin.Models; +namespace AtopPlugin.Models; public record struct CalculatedFlightData( bool Rnp4, diff --git a/Models/ConflictType.cs b/Models/ConflictType.cs index 35f9a2d..6e108ea 100644 --- a/Models/ConflictType.cs +++ b/Models/ConflictType.cs @@ -1,4 +1,4 @@ -namespace AuroraLabelItemsPlugin.Models; +namespace AtopPlugin.Models; public enum ConflictType { diff --git a/Models/DirectionOfFlight.cs b/Models/DirectionOfFlight.cs index d6c6178..d8d88c5 100644 --- a/Models/DirectionOfFlight.cs +++ b/Models/DirectionOfFlight.cs @@ -1,6 +1,6 @@ using vatsys; -namespace AuroraLabelItemsPlugin.Models; +namespace AtopPlugin.Models; public enum DirectionOfFlight { diff --git a/Models/SccFlag.cs b/Models/SccFlag.cs index ad484d7..f19c608 100644 --- a/Models/SccFlag.cs +++ b/Models/SccFlag.cs @@ -1,4 +1,4 @@ -namespace AuroraLabelItemsPlugin.Models; +namespace AtopPlugin.Models; public class SccFlag { diff --git a/State/AtopAircraftDisplayState.cs b/State/AtopAircraftDisplayState.cs index dfa2f12..e592a55 100644 --- a/State/AtopAircraftDisplayState.cs +++ b/State/AtopAircraftDisplayState.cs @@ -1,11 +1,11 @@ #nullable enable using System.Linq; -using AuroraLabelItemsPlugin.Logic; -using AuroraLabelItemsPlugin.Models; +using AtopPlugin.Logic; +using AtopPlugin.Models; using vatsys; using vatsys.Plugin; -namespace AuroraLabelItemsPlugin.State; +namespace AtopPlugin.State; public class AtopAircraftDisplayState { diff --git a/State/AtopAircraftState.cs b/State/AtopAircraftState.cs index f225f46..62d7401 100644 --- a/State/AtopAircraftState.cs +++ b/State/AtopAircraftState.cs @@ -1,9 +1,9 @@ #nullable enable -using AuroraLabelItemsPlugin.Logic; -using AuroraLabelItemsPlugin.Models; +using AtopPlugin.Logic; +using AtopPlugin.Models; using vatsys; -namespace AuroraLabelItemsPlugin.State; +namespace AtopPlugin.State; public class AtopAircraftState { diff --git a/State/AtopPluginStateManager.cs b/State/AtopPluginStateManager.cs index b01998a..526924e 100644 --- a/State/AtopPluginStateManager.cs +++ b/State/AtopPluginStateManager.cs @@ -2,7 +2,7 @@ using System.Collections.Concurrent; using vatsys; -namespace AuroraLabelItemsPlugin.State; +namespace AtopPlugin.State; public static class AtopPluginStateManager { diff --git a/State/JurisdictionManager.cs b/State/JurisdictionManager.cs index 4acda2e..492c047 100644 --- a/State/JurisdictionManager.cs +++ b/State/JurisdictionManager.cs @@ -1,7 +1,7 @@ using System.Linq; using vatsys; -namespace AuroraLabelItemsPlugin.State; +namespace AtopPlugin.State; public static class JurisdictionManager { diff --git a/State/PrivateMessagesChangedHandler.cs b/State/PrivateMessagesChangedHandler.cs index cdad249..9e14105 100644 --- a/State/PrivateMessagesChangedHandler.cs +++ b/State/PrivateMessagesChangedHandler.cs @@ -1,6 +1,6 @@ using vatsys; -namespace AuroraLabelItemsPlugin.State; +namespace AtopPlugin.State; public static class PrivateMessagesChangedHandler { diff --git a/State/RadarFlagToggleHandler.cs b/State/RadarFlagToggleHandler.cs index ad19cbf..5f097b8 100644 --- a/State/RadarFlagToggleHandler.cs +++ b/State/RadarFlagToggleHandler.cs @@ -1,6 +1,6 @@ using vatsys.Plugin; -namespace AuroraLabelItemsPlugin.State; +namespace AtopPlugin.State; public static class RadarFlagToggleHandler { From 9091a27825802018eb2376a40a1e7de80a48e6c1 Mon Sep 17 00:00:00 2001 From: Maxim Salikhov Date: Sun, 25 Feb 2024 01:23:05 -0500 Subject: [PATCH 54/76] Fix initial null reference issues --- Conflict/MinimaCalculator.cs | 7 +------ Display/StripItemRenderer.cs | 4 ++-- Extensions.cs | 5 +++++ Logic/NextSectorCalculator.cs | 2 +- Logic/SccFlagCalculator.cs | 6 ++---- State/AtopAircraftDisplayState.cs | 2 +- State/AtopAircraftState.cs | 2 +- 7 files changed, 13 insertions(+), 15 deletions(-) diff --git a/Conflict/MinimaCalculator.cs b/Conflict/MinimaCalculator.cs index 749f293..99f73a2 100644 --- a/Conflict/MinimaCalculator.cs +++ b/Conflict/MinimaCalculator.cs @@ -48,7 +48,7 @@ public static int GetVerticalMinima(FDP2.FDR fdr1, FDP2.FDR fdr2) public static TimeSpan GetLongitudinalTime(FDP2.FDR fdr1, FDP2.FDR fdr2) { - return IsJet(fdr1) && IsJet(fdr2) + return fdr1.IsJet() && fdr2.IsJet() ? new TimeSpan(0, JetLongitudinal, 0) : new TimeSpan(0, TimeLongitudinal, 0); } @@ -77,9 +77,4 @@ private static bool CanApplyRnp10(FDP2.FDR fdr) { return fdr.GetAtopState().CalculatedFlightData is { Rnp10: true }; } - - private static bool IsJet(FDP2.FDR fdr) - { - return fdr.PerformanceData.IsJet; - } } \ No newline at end of file diff --git a/Display/StripItemRenderer.cs b/Display/StripItemRenderer.cs index fcebee3..b8dee60 100644 --- a/Display/StripItemRenderer.cs +++ b/Display/StripItemRenderer.cs @@ -25,11 +25,11 @@ public static class StripItemRenderer StripConstants.LabelItemAdsbCpdlc => RenderAdsbCpdlcStripItem(fdr), - StripConstants.StripItemT10Flag => fdr.PerformanceData.IsJet + StripConstants.StripItemT10Flag => fdr.IsJet() ? new CustomStripItem { Text = Symbols.T10 } : null, - StripConstants.StripItemMntFlag => fdr.PerformanceData.IsJet + StripConstants.StripItemMntFlag => fdr.IsJet() ? new CustomStripItem { Text = Symbols.Mnt } : null, diff --git a/Extensions.cs b/Extensions.cs index 6356de4..92b6c97 100644 --- a/Extensions.cs +++ b/Extensions.cs @@ -20,6 +20,11 @@ public static AtopAircraftDisplayState GetDisplayState(this FDP2.FDR fdr) return fdr.CoupledTrack?.ActualAircraft.TransponderCode; } + public static bool IsJet(this FDP2.FDR fdr) + { + return fdr.PerformanceData?.IsJet ?? false; + } + public static bool IsSelected(this Track track) { return MMI.SelectedTrack == track; diff --git a/Logic/NextSectorCalculator.cs b/Logic/NextSectorCalculator.cs index 9e7cba3..be61410 100644 --- a/Logic/NextSectorCalculator.cs +++ b/Logic/NextSectorCalculator.cs @@ -11,7 +11,7 @@ public static class NextSectorCalculator { var segment = (from s in fdr.ParsedRoute.ToList() where s.Type == FDP2.FDR.ExtractedRoute.Segment.SegmentTypes.ZPOINT && - !fdr.ControllingSector.Equals(SectorsVolumes.FindSector((SectorsVolumes.Volume)s.Tag)) + fdr.ControllingSector != SectorsVolumes.FindSector((SectorsVolumes.Volume)s.Tag) select s).FirstOrDefault(s => s.ETO > DateTime.UtcNow); SectorsVolumes.Volume? volume = null; diff --git a/Logic/SccFlagCalculator.cs b/Logic/SccFlagCalculator.cs index 58e611c..f8a872e 100644 --- a/Logic/SccFlagCalculator.cs +++ b/Logic/SccFlagCalculator.cs @@ -10,10 +10,8 @@ public static class SccFlagCalculator private const int EmergencyCode = 7700; private const int MilitaryInterceptCode = 7777; - public static SccFlag? CalculateHighestPriorityFlag(FDP2.FDR fdr) + public static SccFlag? CalculateHighestPriorityFlag(FDP2.FDR fdr, CalculatedFlightData calculatedFlightData) { - var parsedFdrFields = fdr.GetAtopState().CalculatedFlightData; - var transponderCode = fdr.GetTransponderCode(); switch (transponderCode) { @@ -25,7 +23,7 @@ public static class SccFlagCalculator return SccFlag.Mti; } - if (!parsedFdrFields.Rnp4 || !parsedFdrFields.Rnp10) return SccFlag.Rnp; + if (!calculatedFlightData.Rnp4 || !calculatedFlightData.Rnp10) return SccFlag.Rnp; return null; } diff --git a/State/AtopAircraftDisplayState.cs b/State/AtopAircraftDisplayState.cs index e592a55..015b0f5 100644 --- a/State/AtopAircraftDisplayState.cs +++ b/State/AtopAircraftDisplayState.cs @@ -35,7 +35,7 @@ public void UpdateFromAtopState(AtopAircraftState atopAircraftState) CpdlcAdsbSymbol = GetCpdlcAdsbSymbol(atopAircraftState); AdsFlag = GetAdsFlag(atopAircraftState); LateralFlag = GetLateralFlag(atopAircraftState); - IsMntFlagToggled = atopAircraftState.Fdr.PerformanceData.IsJet; + IsMntFlagToggled = atopAircraftState.Fdr.IsJet(); HasAnnotations = !string.IsNullOrEmpty(atopAircraftState.Fdr.LabelOpData); IsRestrictionsIndicatorToggled = GetRestrictionsIndicatorToggled(atopAircraftState); CurrentLevel = (atopAircraftState.Fdr.PRL / 100).ToString(); diff --git a/State/AtopAircraftState.cs b/State/AtopAircraftState.cs index 62d7401..53f44dd 100644 --- a/State/AtopAircraftState.cs +++ b/State/AtopAircraftState.cs @@ -35,7 +35,7 @@ public void UpdateFromFdr(FDP2.FDR updatedFdr) CalculatedFlightData = FlightDataCalculator.GetCalculatedFlightData(updatedFdr); DirectionOfFlight = DirectionOfFlightCalculator.GetDirectionOfFlight(updatedFdr); - HighestSccFlag = SccFlagCalculator.CalculateHighestPriorityFlag(updatedFdr); + HighestSccFlag = SccFlagCalculator.CalculateHighestPriorityFlag(updatedFdr, CalculatedFlightData); // ensure the bool for altitude change is calculated first since it is used in the altitude flag calculation PendingAltitudeChange = From 0b12d81c09ccd6c1aa2b365d338da6edde1eb9a4 Mon Sep 17 00:00:00 2001 From: Maxim Salikhov Date: Sun, 25 Feb 2024 11:26:08 -0500 Subject: [PATCH 55/76] Fix autoassume/autodrop --- AtopPlugin.cs | 1 + AtopPlugin.csproj | 1 + Conflict/ConflictProbe.cs | 1 + Display/LabelItemRenderer.cs | 3 +-- Display/StripItemRenderer.cs | 3 +-- Logic/AltitudeCalculator.cs | 3 +-- Logic/NextSectorCalculator.cs | 3 +-- Logic/SccFlagCalculator.cs | 3 +-- Models/DirectionOfFlight.cs | 1 + State/AtopAircraftDisplayState.cs | 3 +-- State/AtopAircraftState.cs | 3 +-- State/AtopPluginStateManager.cs | 3 +-- State/JurisdictionManager.cs | 43 +++++++++++++++++++++---------- 13 files changed, 42 insertions(+), 29 deletions(-) diff --git a/AtopPlugin.cs b/AtopPlugin.cs index ae854c8..1980f3d 100644 --- a/AtopPlugin.cs +++ b/AtopPlugin.cs @@ -24,6 +24,7 @@ public void OnFDRUpdate(FDP2.FDR updated) public void OnRadarTrackUpdate(RDP.RadarTrack updated) { + JurisdictionManager.HandleRadarTrackUpdate(updated); } public CustomStripItem GetCustomStripItem(string itemType, Track track, FDP2.FDR flightDataRecord, diff --git a/AtopPlugin.csproj b/AtopPlugin.csproj index 0293244..8ed0a9b 100644 --- a/AtopPlugin.csproj +++ b/AtopPlugin.csproj @@ -13,6 +13,7 @@ 512 true 11 + enable true diff --git a/Conflict/ConflictProbe.cs b/Conflict/ConflictProbe.cs index a184280..b6ef3b7 100644 --- a/Conflict/ConflictProbe.cs +++ b/Conflict/ConflictProbe.cs @@ -8,6 +8,7 @@ namespace AtopPlugin.Conflict; public class ConflictProbe { + // TODO(msalikhov): actually probe public List Probe(FDP2.FDR fdr) { if (!MMI.IsMySectorConcerned(fdr)) return null; diff --git a/Display/LabelItemRenderer.cs b/Display/LabelItemRenderer.cs index 43222dd..24a8d1b 100644 --- a/Display/LabelItemRenderer.cs +++ b/Display/LabelItemRenderer.cs @@ -1,5 +1,4 @@ -#nullable enable -using AtopPlugin.State; +using AtopPlugin.State; using vatsys; using vatsys.Plugin; diff --git a/Display/StripItemRenderer.cs b/Display/StripItemRenderer.cs index b8dee60..5358364 100644 --- a/Display/StripItemRenderer.cs +++ b/Display/StripItemRenderer.cs @@ -1,5 +1,4 @@ -#nullable enable -using AtopPlugin.Models; +using AtopPlugin.Models; using vatsys; using vatsys.Plugin; diff --git a/Logic/AltitudeCalculator.cs b/Logic/AltitudeCalculator.cs index 5e846ff..ce8c65e 100644 --- a/Logic/AltitudeCalculator.cs +++ b/Logic/AltitudeCalculator.cs @@ -1,5 +1,4 @@ -#nullable enable -using AtopPlugin.Models; +using AtopPlugin.Models; using vatsys; namespace AtopPlugin.Logic; diff --git a/Logic/NextSectorCalculator.cs b/Logic/NextSectorCalculator.cs index be61410..ca28317 100644 --- a/Logic/NextSectorCalculator.cs +++ b/Logic/NextSectorCalculator.cs @@ -1,5 +1,4 @@ -#nullable enable -using System; +using System; using System.Linq; using vatsys; diff --git a/Logic/SccFlagCalculator.cs b/Logic/SccFlagCalculator.cs index f8a872e..c82e955 100644 --- a/Logic/SccFlagCalculator.cs +++ b/Logic/SccFlagCalculator.cs @@ -1,5 +1,4 @@ -#nullable enable -using AtopPlugin.Models; +using AtopPlugin.Models; using vatsys; namespace AtopPlugin.Logic; diff --git a/Models/DirectionOfFlight.cs b/Models/DirectionOfFlight.cs index d8d88c5..7178f50 100644 --- a/Models/DirectionOfFlight.cs +++ b/Models/DirectionOfFlight.cs @@ -13,6 +13,7 @@ public static class DirectionOfFlightCalculator { public static DirectionOfFlight GetDirectionOfFlight(FDP2.FDR fdr) { + // TODO(msalikhov): handle case where aircraft go the "long way around" if (fdr.ParsedRoute.Count <= 1) return DirectionOfFlight.Undetermined; var track = Conversions.CalculateTrack(fdr.ParsedRoute.First().Intersection.LatLong, diff --git a/State/AtopAircraftDisplayState.cs b/State/AtopAircraftDisplayState.cs index 015b0f5..0028fa4 100644 --- a/State/AtopAircraftDisplayState.cs +++ b/State/AtopAircraftDisplayState.cs @@ -1,5 +1,4 @@ -#nullable enable -using System.Linq; +using System.Linq; using AtopPlugin.Logic; using AtopPlugin.Models; using vatsys; diff --git a/State/AtopAircraftState.cs b/State/AtopAircraftState.cs index 53f44dd..c66fae5 100644 --- a/State/AtopAircraftState.cs +++ b/State/AtopAircraftState.cs @@ -1,5 +1,4 @@ -#nullable enable -using AtopPlugin.Logic; +using AtopPlugin.Logic; using AtopPlugin.Models; using vatsys; diff --git a/State/AtopPluginStateManager.cs b/State/AtopPluginStateManager.cs index 526924e..8be1492 100644 --- a/State/AtopPluginStateManager.cs +++ b/State/AtopPluginStateManager.cs @@ -1,5 +1,4 @@ -#nullable enable -using System.Collections.Concurrent; +using System.Collections.Concurrent; using vatsys; namespace AtopPlugin.State; diff --git a/State/JurisdictionManager.cs b/State/JurisdictionManager.cs index 492c047..a0ce3e1 100644 --- a/State/JurisdictionManager.cs +++ b/State/JurisdictionManager.cs @@ -1,4 +1,5 @@ -using System.Linq; +using System; +using System.Linq; using vatsys; namespace AtopPlugin.State; @@ -7,20 +8,36 @@ public static class JurisdictionManager { public static void HandleFdrUpdate(FDP2.FDR fdr) { - var isInSector = MMI.SectorsControlled.ToList().Exists(sector => sector.IsInSector(fdr.GetLocation(), fdr.PRL)); + // TODO(msalikhov): Because of this its impossible to cancel an FDR that's disconnected + if (!fdr.ESTed && MMI.IsMySectorConcerned(fdr)) MMI.EstFDR(fdr); - switch (isInSector) + var isInControlledSector = IsInControlledSector(fdr.GetLocation(), fdr.PRL); + + // check if aircraft previously tracked to avoid re-tracking manually dropped/handed off tracks + if (isInControlledSector && !fdr.IsTracked && !fdr.GetAtopState().PreviouslyTracked) { - // check if aircraft previously tracked to avoid re-tracking manually dropped/handed off tracks - case true when !fdr.IsTracked && !fdr.GetAtopState().PreviouslyTracked: - MMI.AcceptJurisdiction(fdr); - fdr.GetAtopState().PreviouslyTracked = true; - break; - - // if they're outside sector and currently, tracked, drop them - case false when fdr.IsTrackedByMe: - MMI.HandoffToNone(fdr); - break; + MMI.AcceptJurisdiction(fdr); + fdr.GetAtopState().PreviouslyTracked = true; } + + // if they're outside sector, currently tracked, and not going to re-enter, drop them + if (!isInControlledSector && fdr.IsTrackedByMe && !WillEnter(fdr)) MMI.HandoffToNone(fdr); + } + + public static void HandleRadarTrackUpdate(RDP.RadarTrack rt) + { + if (rt.CoupledFDR == null) return; + HandleFdrUpdate(rt.CoupledFDR); + } + + private static bool WillEnter(FDP2.FDR fdr) + { + return MMI.GetSectorEntryTime(fdr) != DateTime.MaxValue; + } + + private static bool IsInControlledSector(Coordinate? location, int altitude) + { + if (location == null || double.IsNaN(location.Latitude) || double.IsNaN(location.Longitude)) return false; + return MMI.SectorsControlled.ToList().Exists(sector => sector.IsInSector(location, altitude)); } } \ No newline at end of file From aa9533157b7c38b02b1dddcfe0405eae3da49a5c Mon Sep 17 00:00:00 2001 From: Maxim Salikhov Date: Sun, 25 Feb 2024 12:11:37 -0500 Subject: [PATCH 56/76] Run conflict probe --- AtopPlugin.csproj | 1 + Conflict/ConflictProbe.cs | 68 +++++++++++++++++++++++++++----------- Models/ConflictStatus.cs | 23 +++++++++++++ State/AtopAircraftState.cs | 5 ++- 4 files changed, 77 insertions(+), 20 deletions(-) create mode 100644 Models/ConflictStatus.cs diff --git a/AtopPlugin.csproj b/AtopPlugin.csproj index 8ed0a9b..a9f77f4 100644 --- a/AtopPlugin.csproj +++ b/AtopPlugin.csproj @@ -65,6 +65,7 @@ + diff --git a/Conflict/ConflictProbe.cs b/Conflict/ConflictProbe.cs index b6ef3b7..55a8d41 100644 --- a/Conflict/ConflictProbe.cs +++ b/Conflict/ConflictProbe.cs @@ -6,12 +6,11 @@ namespace AtopPlugin.Conflict; -public class ConflictProbe +public static class ConflictProbe { - // TODO(msalikhov): actually probe - public List Probe(FDP2.FDR fdr) + public static Conflicts Probe(FDP2.FDR fdr) { - if (!MMI.IsMySectorConcerned(fdr)) return null; + if (!MMI.IsMySectorConcerned(fdr)) return EmptyConflicts(); var discoveredConflicts = new List(); @@ -75,15 +74,19 @@ public List Probe(FDP2.FDR fdr) && data.LongDistact < data.LongDistsep; data.TimeLongopposite = false; - data.Top = null; if (failedLateral && oppoDir) - { - data.Top = new TimeOfPassing(fdr, fdr2); - data.TimeLongopposite = data.Top.Time > DateTime.UtcNow - && data.Top.Time.Add(data.LongTimesep) > DateTime.UtcNow && - data.Top.Time.Subtract(data.LongTimesep) < DateTime.UtcNow; - } + try + { + data.Top = new TimeOfPassing(fdr, fdr2); + data.TimeLongopposite = data.Top.Time > DateTime.UtcNow + && data.Top.Time.Add(data.LongTimesep) > DateTime.UtcNow && + data.Top.Time.Subtract(data.LongTimesep) < DateTime.UtcNow; + } + catch (Exception e) + { + // ignored - we were unable to calculate time of passing for some reason + } data.LongType = data.LongDistsep == null ? data.TimeLongsame @@ -99,39 +102,66 @@ public List Probe(FDP2.FDR fdr) ? firstConflictTime.StartTime : firstConflictTime2.StartTime; - data.ActualConflicts = failedLateral && oppoDir && data.VerticalAct < data.VerticalSep + var actual = failedLateral && oppoDir && data.VerticalAct < data.VerticalSep ? new TimeSpan(0, 0, 1, 0, 0) >= data.EarliestLos.Subtract(DateTime.UtcNow).Duration() : (lossOfSep && new TimeSpan(0, 0, 1, 0, 0) >= data.EarliestLos.Subtract(DateTime.UtcNow).Duration()) || data.EarliestLos < DateTime.UtcNow; - data.ImminentConflicts = failedLateral && oppoDir && data.VerticalAct < data.VerticalSep + var imminent = failedLateral && oppoDir && data.VerticalAct < data.VerticalSep ? new TimeSpan(0, 0, 30, 0, 0) >= data.EarliestLos.Subtract(DateTime.UtcNow).Duration() : lossOfSep && new TimeSpan(0, 0, 30, 0, 0) >= data.EarliestLos.Subtract(DateTime.UtcNow).Duration(); //check if timediff < 30 min - data.AdvisoryConflicts = failedLateral && oppoDir && data.VerticalAct < data.VerticalSep + var advisory = failedLateral && oppoDir && data.VerticalAct < data.VerticalSep ? new TimeSpan(0, 2, 0, 0, 0) > data.EarliestLos.Subtract(DateTime.UtcNow).Duration() && data.EarliestLos.Subtract(DateTime.UtcNow).Duration() >= new TimeSpan(0, 0, 30, 0, 0) : lossOfSep && new TimeSpan(0, 2, 0, 0, 0) > data.EarliestLos.Subtract(DateTime.UtcNow).Duration() && data.EarliestLos.Subtract(DateTime.UtcNow).Duration() >= new TimeSpan(0, 0, 30, 0, 0); //check if 2 hours > timediff > 30 mins - if (data.ActualConflicts || data.ImminentConflicts || data.AdvisoryConflicts) discoveredConflicts.Add(data); + + data.ConflictStatus = ConflictStatusUtils.From(actual, imminent, advisory); + + if (data.ConflictStatus != ConflictStatus.None) discoveredConflicts.Add(data); + } + + return GroupConflicts(discoveredConflicts); + } + + private static Conflicts EmptyConflicts() + { + return new Conflicts(new List(), new List(), new List()); + } + + private static Conflicts GroupConflicts(List allConflicts) + { + var actual = new List(); + var imminent = new List(); + var advisory = new List(); + + foreach (var conflict in allConflicts) + { + if (conflict.ConflictStatus == ConflictStatus.Actual) actual.Add(conflict); + if (conflict.ConflictStatus == ConflictStatus.Imminent) imminent.Add(conflict); + if (conflict.ConflictStatus == ConflictStatus.Advisory) advisory.Add(conflict); } - return discoveredConflicts; + return new Conflicts(actual, imminent, advisory); } + public record struct Conflicts( + List ActualConflicts, + List ImminentConflicts, + List AdvisoryConflicts); + public record ConflictData { - public bool ActualConflicts; - public bool AdvisoryConflicts; + public ConflictStatus ConflictStatus; public ConflictType? ConflictType; public bool DistLongsame; public DateTime EarliestLos; public FDP2.FDR Fdr2; - public bool ImminentConflicts; public int LatSep; public double LongDistact; public int? LongDistsep; diff --git a/Models/ConflictStatus.cs b/Models/ConflictStatus.cs new file mode 100644 index 0000000..1978337 --- /dev/null +++ b/Models/ConflictStatus.cs @@ -0,0 +1,23 @@ +namespace AtopPlugin.Models; + +public enum ConflictStatus +{ + Actual, + Imminent, + Advisory, + None +} + +public static class ConflictStatusUtils +{ + public static ConflictStatus From(bool actual, bool imminent, bool advisory) + { + return (actual, imminent, advisory) switch + { + { actual: true } => ConflictStatus.Actual, + { imminent: true } => ConflictStatus.Imminent, + { advisory: true } => ConflictStatus.Advisory, + _ => ConflictStatus.None + }; + } +} \ No newline at end of file diff --git a/State/AtopAircraftState.cs b/State/AtopAircraftState.cs index c66fae5..d9f5bf0 100644 --- a/State/AtopAircraftState.cs +++ b/State/AtopAircraftState.cs @@ -1,4 +1,5 @@ -using AtopPlugin.Logic; +using AtopPlugin.Conflict; +using AtopPlugin.Logic; using AtopPlugin.Models; using vatsys; @@ -16,6 +17,7 @@ public AtopAircraftState(FDP2.FDR fdr) } public FDP2.FDR Fdr { get; private set; } + public ConflictProbe.Conflicts Conflicts { get; private set; } public CalculatedFlightData CalculatedFlightData { get; private set; } public DirectionOfFlight DirectionOfFlight { get; private set; } public SccFlag? HighestSccFlag { get; private set; } @@ -31,6 +33,7 @@ public AtopAircraftState(FDP2.FDR fdr) public void UpdateFromFdr(FDP2.FDR updatedFdr) { Fdr = updatedFdr; + Conflicts = ConflictProbe.Probe(updatedFdr); CalculatedFlightData = FlightDataCalculator.GetCalculatedFlightData(updatedFdr); DirectionOfFlight = DirectionOfFlightCalculator.GetDirectionOfFlight(updatedFdr); From 2662ea08c61c50953f74fea714b396404fd2232f Mon Sep 17 00:00:00 2001 From: Maxim Salikhov Date: Sun, 25 Feb 2024 12:42:29 -0500 Subject: [PATCH 57/76] Add conflict color rendering --- Conflict/ConflictProbe.cs | 4 ++-- Display/TrackColorRenderer.cs | 25 ++++++++++++++++++++----- Extensions.cs | 4 ++-- 3 files changed, 24 insertions(+), 9 deletions(-) diff --git a/Conflict/ConflictProbe.cs b/Conflict/ConflictProbe.cs index 55a8d41..bda2904 100644 --- a/Conflict/ConflictProbe.cs +++ b/Conflict/ConflictProbe.cs @@ -97,7 +97,7 @@ public static Conflicts Probe(FDP2.FDR fdr) lossOfSep && crossing ? ConflictType.Crossing : lossOfSep && oppoDir ? ConflictType.OppositeDirection : null; data.EarliestLos = failedLateral && oppoDir - ? data.Top.Time.Subtract(new TimeSpan(0, 0, 10, 0)) + ? data.Top?.Time.Subtract(new TimeSpan(0, 0, 10, 0)) ?? DateTime.MaxValue : DateTime.Compare(firstConflictTime.StartTime, firstConflictTime2.StartTime) < 0 ? firstConflictTime.StartTime : firstConflictTime2.StartTime; @@ -171,7 +171,7 @@ public record ConflictData public bool TimeLongcross; public bool TimeLongopposite; public bool TimeLongsame; - public TimeOfPassing Top; + public TimeOfPassing? Top; public double TrkAngle; public int VerticalAct; public int VerticalSep; diff --git a/Display/TrackColorRenderer.cs b/Display/TrackColorRenderer.cs index 25ff0b9..19aaafc 100644 --- a/Display/TrackColorRenderer.cs +++ b/Display/TrackColorRenderer.cs @@ -6,19 +6,24 @@ namespace AtopPlugin.Display; public static class TrackColorRenderer { - public static CustomColour GetAsdColor(Track track) + public static CustomColour? GetAsdColor(Track track) { var fdr = track.GetFDR(); if (fdr == null) return null; - // TODO(msalikhov): render conflict color - return IsInJurisdiction(track) ? GetDirectionColour(fdr) : null; + return (IsInJurisdiction(track), fdr.State) switch + { + { Item1: true } => GetConflictColour(fdr) ?? GetDirectionColour(fdr), + { State: FDP2.FDR.FDRStates.STATE_PREACTIVE or FDP2.FDR.FDRStates.STATE_COORDINATED } => + GetConflictColour(fdr), + _ => null + }; } - private static CustomColour GetDirectionColour(FDP2.FDR fdr) + private static CustomColour? GetDirectionColour(FDP2.FDR fdr) { - return fdr.GetAtopState().DirectionOfFlight switch + return fdr.GetAtopState()?.DirectionOfFlight switch { DirectionOfFlight.Eastbound => CustomColors.EastboundColour, DirectionOfFlight.Westbound => CustomColors.WestboundColour, @@ -26,6 +31,16 @@ private static CustomColour GetDirectionColour(FDP2.FDR fdr) }; } + private static CustomColour? GetConflictColour(FDP2.FDR fdr) + { + return fdr.GetAtopState()?.Conflicts switch + { + { ActualConflicts.Count: > 0 } or { ImminentConflicts.Count: > 0 } => CustomColors.Imminent, + { AdvisoryConflicts.Count: > 0 } => CustomColors.Advisory, + _ => null + }; + } + private static bool IsInJurisdiction(Track track) { return track.State == MMI.HMIStates.Jurisdiction; diff --git a/Extensions.cs b/Extensions.cs index 92b6c97..7a65b43 100644 --- a/Extensions.cs +++ b/Extensions.cs @@ -5,12 +5,12 @@ namespace AtopPlugin; public static class Extensions { - public static AtopAircraftState GetAtopState(this FDP2.FDR fdr) + public static AtopAircraftState? GetAtopState(this FDP2.FDR fdr) { return AtopPluginStateManager.GetAircraftState(fdr.Callsign); } - public static AtopAircraftDisplayState GetDisplayState(this FDP2.FDR fdr) + public static AtopAircraftDisplayState? GetDisplayState(this FDP2.FDR fdr) { return AtopPluginStateManager.GetDisplayState(fdr.Callsign); } From d8a59b6a052f812d35739caa49ac4450fb9e7501 Mon Sep 17 00:00:00 2001 From: Maxim Salikhov Date: Sun, 25 Feb 2024 12:56:23 -0500 Subject: [PATCH 58/76] Only show conflict color for callsign --- Display/LabelItemRenderer.cs | 21 +++++++++++++++++++-- Display/TrackColorRenderer.cs | 2 +- 2 files changed, 20 insertions(+), 3 deletions(-) diff --git a/Display/LabelItemRenderer.cs b/Display/LabelItemRenderer.cs index 24a8d1b..2553535 100644 --- a/Display/LabelItemRenderer.cs +++ b/Display/LabelItemRenderer.cs @@ -8,11 +8,28 @@ public static class LabelItemRenderer { public static CustomLabelItem? RenderLabelItem(string itemType, Track track, FDP2.FDR? fdr, RDP.RadarTrack _) + { + var renderedItem = RenderLabelItemDelegate(itemType, track, fdr); + return renderedItem != null ? ExcludeConflictColor(fdr!, renderedItem) : null; + } + + private static CustomLabelItem ExcludeConflictColor(FDP2.FDR fdr, CustomLabelItem customLabelItem) + { + // If we already overrode it, keep it that way + if (customLabelItem.ForeColourIdentity == Colours.Identities.Custom) return customLabelItem; + + customLabelItem.ForeColourIdentity = Colours.Identities.Custom; + customLabelItem.CustomForeColour = TrackColorRenderer.GetDirectionColour(fdr) ?? CustomColors.ApsBlue; + + return customLabelItem; + } + + private static CustomLabelItem? RenderLabelItemDelegate(string itemType, Track track, FDP2.FDR? fdr) { if (fdr == null) return null; - var atopState = fdr.GetAtopState(); - var displayState = fdr.GetDisplayState(); + var atopState = fdr.GetAtopState()!; + var displayState = fdr.GetDisplayState()!; return itemType switch { diff --git a/Display/TrackColorRenderer.cs b/Display/TrackColorRenderer.cs index 19aaafc..a03d857 100644 --- a/Display/TrackColorRenderer.cs +++ b/Display/TrackColorRenderer.cs @@ -21,7 +21,7 @@ public static class TrackColorRenderer }; } - private static CustomColour? GetDirectionColour(FDP2.FDR fdr) + public static CustomColour? GetDirectionColour(FDP2.FDR fdr) { return fdr.GetAtopState()?.DirectionOfFlight switch { From 091bfcbb826dfdeb6517bfa4620149602de7b252 Mon Sep 17 00:00:00 2001 From: Maxim Salikhov Date: Sun, 25 Feb 2024 20:31:01 -0500 Subject: [PATCH 59/76] Fix cleared flight level display --- AtopPlugin.cs | 18 +++++++++++----- AtopPlugin.csproj | 1 + Models/AltitudeBlock.cs | 10 +++++---- State/AtopPluginStateManager.cs | 13 +++++++++--- State/FdrPropertyChangesListener.cs | 33 +++++++++++++++++++++++++++++ 5 files changed, 63 insertions(+), 12 deletions(-) create mode 100644 State/FdrPropertyChangesListener.cs diff --git a/AtopPlugin.cs b/AtopPlugin.cs index 1980f3d..100588d 100644 --- a/AtopPlugin.cs +++ b/AtopPlugin.cs @@ -12,14 +12,22 @@ public class AtopPlugin : ILabelPlugin, IStripPlugin public string Name => "ATOP Plugin"; public AtopPlugin() + { + RegisterEventHandlers(); + } + + private static void RegisterEventHandlers() { Network.PrivateMessagesChanged += PrivateMessagesChangedHandler.Handle; + FdrPropertyChangesListener.RegisterAllHandlers(); } public void OnFDRUpdate(FDP2.FDR updated) { - AtopPluginStateManager.ProcessStateUpdate(updated); + AtopPluginStateManager.ProcessFdrUpdate(updated); + AtopPluginStateManager.ProcessDisplayUpdate(updated); JurisdictionManager.HandleFdrUpdate(updated); + FdrPropertyChangesListener.RegisterHandler(updated); } public void OnRadarTrackUpdate(RDP.RadarTrack updated) @@ -27,24 +35,24 @@ public void OnRadarTrackUpdate(RDP.RadarTrack updated) JurisdictionManager.HandleRadarTrackUpdate(updated); } - public CustomStripItem GetCustomStripItem(string itemType, Track track, FDP2.FDR flightDataRecord, + public CustomStripItem? GetCustomStripItem(string itemType, Track track, FDP2.FDR flightDataRecord, RDP.RadarTrack radarTrack) { return StripItemRenderer.RenderStripItem(itemType, track, flightDataRecord, radarTrack); } - public CustomLabelItem GetCustomLabelItem(string itemType, Track track, FDP2.FDR flightDataRecord, + public CustomLabelItem? GetCustomLabelItem(string itemType, Track track, FDP2.FDR flightDataRecord, RDP.RadarTrack radarTrack) { return LabelItemRenderer.RenderLabelItem(itemType, track, flightDataRecord, radarTrack); } - public CustomColour SelectASDTrackColour(Track track) + public CustomColour? SelectASDTrackColour(Track track) { return TrackColorRenderer.GetAsdColor(track); } - public CustomColour SelectGroundTrackColour(Track track) + public CustomColour? SelectGroundTrackColour(Track track) { return null; } diff --git a/AtopPlugin.csproj b/AtopPlugin.csproj index a9f77f4..8f6819a 100644 --- a/AtopPlugin.csproj +++ b/AtopPlugin.csproj @@ -74,6 +74,7 @@ + diff --git a/Models/AltitudeBlock.cs b/Models/AltitudeBlock.cs index 25a7c16..88a5f74 100644 --- a/Models/AltitudeBlock.cs +++ b/Models/AltitudeBlock.cs @@ -41,14 +41,16 @@ public static int Difference(AltitudeBlock block1, AltitudeBlock block2) public static AltitudeBlock ExtractAltitudeBlock(FDP2.FDR fdr) { - var altitudeUpper = ExtractClearedOrRequestedValue(fdr.CFLUpper, fdr.RFL); - var altitudeLower = ExtractClearedOrRequestedValue(fdr.CFLLower, fdr.RFL); + var cflUpperAsNull = AsNullWhenNegative(fdr.CFLUpper); + var cflLowerAsNull = AsNullWhenNegative(fdr.CFLLower); + var altitudeUpper = cflUpperAsNull ?? fdr.RFL; + var altitudeLower = cflLowerAsNull ?? (cflUpperAsNull ?? fdr.RFL); return new AltitudeBlock(altitudeLower, altitudeUpper); } - private static int ExtractClearedOrRequestedValue(int clearedValue, int requestedValue) + private static int? AsNullWhenNegative(int number) { - return clearedValue == -1 ? requestedValue : clearedValue; + return number >= 0 ? number : null; } public override string ToString() diff --git a/State/AtopPluginStateManager.cs b/State/AtopPluginStateManager.cs index 8be1492..79e5179 100644 --- a/State/AtopPluginStateManager.cs +++ b/State/AtopPluginStateManager.cs @@ -22,7 +22,7 @@ public static class AtopPluginStateManager return found ? state : null; } - public static void ProcessStateUpdate(FDP2.FDR updated) + public static void ProcessFdrUpdate(FDP2.FDR updated) { var callsign = updated.Callsign; @@ -43,11 +43,18 @@ public static void ProcessStateUpdate(FDP2.FDR updated) { aircraftState.UpdateFromFdr(updated); } + } + + public static void ProcessDisplayUpdate(FDP2.FDR fdr) + { + var callsign = fdr.Callsign; + var atopState = fdr.GetAtopState(); + if (atopState == null) return; var displayState = GetDisplayState(callsign); if (displayState == null) - DisplayStates.TryAdd(callsign, new AtopAircraftDisplayState(aircraftState)); + DisplayStates.TryAdd(callsign, new AtopAircraftDisplayState(atopState)); else - displayState.UpdateFromAtopState(aircraftState); + displayState.UpdateFromAtopState(atopState); } } \ No newline at end of file diff --git a/State/FdrPropertyChangesListener.cs b/State/FdrPropertyChangesListener.cs new file mode 100644 index 0000000..2a354f6 --- /dev/null +++ b/State/FdrPropertyChangesListener.cs @@ -0,0 +1,33 @@ +using System.Collections.Concurrent; +using System.Collections.Generic; +using System.ComponentModel; +using System.Linq; +using vatsys; + +namespace AtopPlugin.State; + +public static class FdrPropertyChangesListener +{ + private static readonly string[] RelevantProperties = { "CFLUpper", "CFLLower" }; + private static readonly HashSet RegisteredFdrs = new(); + + public static void RegisterAllHandlers() + { + FDP2.GetFDRs.ForEach(RegisterHandler); + } + + public static void RegisterHandler(FDP2.FDR fdr) + { + var newEntry = RegisteredFdrs.Add(fdr.Callsign); + if (!newEntry) return; + fdr.PropertyChanged += Handle; + } + + private static void Handle(object sender, PropertyChangedEventArgs eventArgs) + { + if (sender is not FDP2.FDR fdr) return; + if (!RelevantProperties.Contains(eventArgs.PropertyName)) return; + AtopPluginStateManager.ProcessFdrUpdate(fdr); + AtopPluginStateManager.ProcessDisplayUpdate(fdr); + } +} \ No newline at end of file From b7511a300460161891d9a62938d5948ff293fbc3 Mon Sep 17 00:00:00 2001 From: Maxim Salikhov Date: Sun, 25 Feb 2024 20:34:50 -0500 Subject: [PATCH 60/76] Don't auto-assume when observing --- AtopPlugin.cs | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/AtopPlugin.cs b/AtopPlugin.cs index 100588d..369e2fa 100644 --- a/AtopPlugin.cs +++ b/AtopPlugin.cs @@ -19,6 +19,9 @@ public AtopPlugin() private static void RegisterEventHandlers() { Network.PrivateMessagesChanged += PrivateMessagesChangedHandler.Handle; + + // changes to cleared flight level do not register an FDR update + // we need to create custom handlers to be able to update the label/strip FdrPropertyChangesListener.RegisterAllHandlers(); } @@ -26,13 +29,16 @@ public void OnFDRUpdate(FDP2.FDR updated) { AtopPluginStateManager.ProcessFdrUpdate(updated); AtopPluginStateManager.ProcessDisplayUpdate(updated); - JurisdictionManager.HandleFdrUpdate(updated); FdrPropertyChangesListener.RegisterHandler(updated); + + // don't manage jurisdiction if not connected as ATC + if (Network.Me.IsRealATC) JurisdictionManager.HandleFdrUpdate(updated); } public void OnRadarTrackUpdate(RDP.RadarTrack updated) { - JurisdictionManager.HandleRadarTrackUpdate(updated); + // don't manage jurisdiction if not connected as ATC + if (Network.Me.IsRealATC) JurisdictionManager.HandleRadarTrackUpdate(updated); } public CustomStripItem? GetCustomStripItem(string itemType, Track track, FDP2.FDR flightDataRecord, From 13f1328da6a350ddb5a7f97228ed36ff776fa7f5 Mon Sep 17 00:00:00 2001 From: Maxim Salikhov Date: Sun, 25 Feb 2024 21:20:21 -0500 Subject: [PATCH 61/76] Add async processing for update --- State/AtopPluginStateManager.cs | 18 ++++++++++++------ State/FdrPropertyChangesListener.cs | 6 +++--- State/JurisdictionManager.cs | 20 +++++++++++--------- 3 files changed, 26 insertions(+), 18 deletions(-) diff --git a/State/AtopPluginStateManager.cs b/State/AtopPluginStateManager.cs index 79e5179..14fda49 100644 --- a/State/AtopPluginStateManager.cs +++ b/State/AtopPluginStateManager.cs @@ -1,4 +1,5 @@ using System.Collections.Concurrent; +using System.Threading.Tasks; using vatsys; namespace AtopPlugin.State; @@ -22,7 +23,7 @@ public static class AtopPluginStateManager return found ? state : null; } - public static void ProcessFdrUpdate(FDP2.FDR updated) + public static async Task ProcessFdrUpdate(FDP2.FDR updated) { var callsign = updated.Callsign; @@ -36,16 +37,16 @@ public static void ProcessFdrUpdate(FDP2.FDR updated) var aircraftState = GetAircraftState(callsign); if (aircraftState == null) { - aircraftState = new AtopAircraftState(updated); + aircraftState = await Task.Run(() => new AtopAircraftState(updated)); AircraftStates.TryAdd(callsign, aircraftState); } else { - aircraftState.UpdateFromFdr(updated); + await Task.Run(() => aircraftState.UpdateFromFdr(updated)); } } - public static void ProcessDisplayUpdate(FDP2.FDR fdr) + public static async Task ProcessDisplayUpdate(FDP2.FDR fdr) { var callsign = fdr.Callsign; var atopState = fdr.GetAtopState(); @@ -53,8 +54,13 @@ public static void ProcessDisplayUpdate(FDP2.FDR fdr) var displayState = GetDisplayState(callsign); if (displayState == null) - DisplayStates.TryAdd(callsign, new AtopAircraftDisplayState(atopState)); + { + displayState = await Task.Run(() => new AtopAircraftDisplayState(atopState)); + DisplayStates.TryAdd(callsign, displayState); + } else - displayState.UpdateFromAtopState(atopState); + { + await Task.Run(() => displayState.UpdateFromAtopState(atopState)); + } } } \ No newline at end of file diff --git a/State/FdrPropertyChangesListener.cs b/State/FdrPropertyChangesListener.cs index 2a354f6..051c893 100644 --- a/State/FdrPropertyChangesListener.cs +++ b/State/FdrPropertyChangesListener.cs @@ -23,11 +23,11 @@ public static void RegisterHandler(FDP2.FDR fdr) fdr.PropertyChanged += Handle; } - private static void Handle(object sender, PropertyChangedEventArgs eventArgs) + private static async void Handle(object sender, PropertyChangedEventArgs eventArgs) { if (sender is not FDP2.FDR fdr) return; if (!RelevantProperties.Contains(eventArgs.PropertyName)) return; - AtopPluginStateManager.ProcessFdrUpdate(fdr); - AtopPluginStateManager.ProcessDisplayUpdate(fdr); + await AtopPluginStateManager.ProcessFdrUpdate(fdr); + await AtopPluginStateManager.ProcessDisplayUpdate(fdr); } } \ No newline at end of file diff --git a/State/JurisdictionManager.cs b/State/JurisdictionManager.cs index a0ce3e1..bc1efaf 100644 --- a/State/JurisdictionManager.cs +++ b/State/JurisdictionManager.cs @@ -1,17 +1,18 @@ using System; using System.Linq; +using System.Threading.Tasks; using vatsys; namespace AtopPlugin.State; public static class JurisdictionManager { - public static void HandleFdrUpdate(FDP2.FDR fdr) + public static async Task HandleFdrUpdate(FDP2.FDR fdr) { // TODO(msalikhov): Because of this its impossible to cancel an FDR that's disconnected if (!fdr.ESTed && MMI.IsMySectorConcerned(fdr)) MMI.EstFDR(fdr); - var isInControlledSector = IsInControlledSector(fdr.GetLocation(), fdr.PRL); + var isInControlledSector = await IsInControlledSector(fdr.GetLocation(), fdr.PRL); // check if aircraft previously tracked to avoid re-tracking manually dropped/handed off tracks if (isInControlledSector && !fdr.IsTracked && !fdr.GetAtopState().PreviouslyTracked) @@ -21,23 +22,24 @@ public static void HandleFdrUpdate(FDP2.FDR fdr) } // if they're outside sector, currently tracked, and not going to re-enter, drop them - if (!isInControlledSector && fdr.IsTrackedByMe && !WillEnter(fdr)) MMI.HandoffToNone(fdr); + if (!isInControlledSector && fdr.IsTrackedByMe && !await WillEnter(fdr)) MMI.HandoffToNone(fdr); } - public static void HandleRadarTrackUpdate(RDP.RadarTrack rt) + public static async Task HandleRadarTrackUpdate(RDP.RadarTrack rt) { if (rt.CoupledFDR == null) return; - HandleFdrUpdate(rt.CoupledFDR); + await HandleFdrUpdate(rt.CoupledFDR); } - private static bool WillEnter(FDP2.FDR fdr) + private static async Task WillEnter(FDP2.FDR fdr) { - return MMI.GetSectorEntryTime(fdr) != DateTime.MaxValue; + return await Task.Run(() => MMI.GetSectorEntryTime(fdr) != DateTime.MaxValue); } - private static bool IsInControlledSector(Coordinate? location, int altitude) + private static async Task IsInControlledSector(Coordinate? location, int altitude) { if (location == null || double.IsNaN(location.Latitude) || double.IsNaN(location.Longitude)) return false; - return MMI.SectorsControlled.ToList().Exists(sector => sector.IsInSector(location, altitude)); + return await Task.Run(() => + MMI.SectorsControlled.ToList().Exists(sector => sector.IsInSector(location, altitude))); } } \ No newline at end of file From 51b637db00bdc7db933ed1e97a75dfa2ce1bd6de Mon Sep 17 00:00:00 2001 From: Maxim Salikhov Date: Sun, 25 Feb 2024 21:44:03 -0500 Subject: [PATCH 62/76] Reset plugin state on disconnect --- AtopPlugin.cs | 3 ++- AtopPlugin.csproj | 1 + Conflict/ConflictProbe.cs | 2 +- Conflict/MinimaCalculator.cs | 6 +++--- Display/LabelItemRenderer.cs | 2 +- Display/StripItemRenderer.cs | 12 ++++++------ Logic/NextSectorCalculator.cs | 2 +- State/AtopPluginStateManager.cs | 6 ++++++ State/DisconnectHandler.cs | 11 +++++++++++ State/JurisdictionManager.cs | 5 +++-- State/PrivateMessagesChangedHandler.cs | 2 +- State/RadarFlagToggleHandler.cs | 2 +- 12 files changed, 37 insertions(+), 17 deletions(-) create mode 100644 State/DisconnectHandler.cs diff --git a/AtopPlugin.cs b/AtopPlugin.cs index 369e2fa..ade087b 100644 --- a/AtopPlugin.cs +++ b/AtopPlugin.cs @@ -19,7 +19,8 @@ public AtopPlugin() private static void RegisterEventHandlers() { Network.PrivateMessagesChanged += PrivateMessagesChangedHandler.Handle; - + Network.Disconnected += DisconnectHandler.Handle; + // changes to cleared flight level do not register an FDR update // we need to create custom handlers to be able to update the label/strip FdrPropertyChangesListener.RegisterAllHandlers(); diff --git a/AtopPlugin.csproj b/AtopPlugin.csproj index 8f6819a..57c38b1 100644 --- a/AtopPlugin.csproj +++ b/AtopPlugin.csproj @@ -74,6 +74,7 @@ + diff --git a/Conflict/ConflictProbe.cs b/Conflict/ConflictProbe.cs index bda2904..fba8923 100644 --- a/Conflict/ConflictProbe.cs +++ b/Conflict/ConflictProbe.cs @@ -83,7 +83,7 @@ public static Conflicts Probe(FDP2.FDR fdr) && data.Top.Time.Add(data.LongTimesep) > DateTime.UtcNow && data.Top.Time.Subtract(data.LongTimesep) < DateTime.UtcNow; } - catch (Exception e) + catch (Exception) { // ignored - we were unable to calculate time of passing for some reason } diff --git a/Conflict/MinimaCalculator.cs b/Conflict/MinimaCalculator.cs index 99f73a2..e4c380c 100644 --- a/Conflict/MinimaCalculator.cs +++ b/Conflict/MinimaCalculator.cs @@ -65,16 +65,16 @@ public static TimeSpan GetLongitudinalTime(FDP2.FDR fdr1, FDP2.FDR fdr2) private static bool HasDatalink(FDP2.FDR fdr) { - return fdr.GetAtopState().CalculatedFlightData is { Pbcs: true, Adsc: true, Cpdlc: true }; + return fdr.GetAtopState()?.CalculatedFlightData is { Pbcs: true, Adsc: true, Cpdlc: true }; } private static bool CanApplyRnp4(FDP2.FDR fdr) { - return HasDatalink(fdr) && fdr.GetAtopState().CalculatedFlightData.Rnp4; + return HasDatalink(fdr) && fdr.GetAtopState()?.CalculatedFlightData is { Rnp4: true }; } private static bool CanApplyRnp10(FDP2.FDR fdr) { - return fdr.GetAtopState().CalculatedFlightData is { Rnp10: true }; + return fdr.GetAtopState()?.CalculatedFlightData is { Rnp10: true }; } } \ No newline at end of file diff --git a/Display/LabelItemRenderer.cs b/Display/LabelItemRenderer.cs index 2553535..66a21c5 100644 --- a/Display/LabelItemRenderer.cs +++ b/Display/LabelItemRenderer.cs @@ -26,7 +26,7 @@ private static CustomLabelItem ExcludeConflictColor(FDP2.FDR fdr, CustomLabelIte private static CustomLabelItem? RenderLabelItemDelegate(string itemType, Track track, FDP2.FDR? fdr) { - if (fdr == null) return null; + if (fdr?.GetAtopState() == null || fdr.GetDisplayState() == null) return null; var atopState = fdr.GetAtopState()!; var displayState = fdr.GetDisplayState()!; diff --git a/Display/StripItemRenderer.cs b/Display/StripItemRenderer.cs index 5358364..23882f6 100644 --- a/Display/StripItemRenderer.cs +++ b/Display/StripItemRenderer.cs @@ -9,10 +9,10 @@ public static class StripItemRenderer public static CustomStripItem? RenderStripItem(string itemType, Track track, FDP2.FDR? fdr, RDP.RadarTrack radarTrack) { - if (fdr == null) return null; + if (fdr?.GetAtopState() == null || fdr.GetDisplayState() == null) return null; - var atopState = fdr.GetAtopState(); - var displayState = fdr.GetDisplayState(); + var atopState = fdr.GetAtopState()!; + var displayState = fdr.GetDisplayState()!; return itemType switch { @@ -100,12 +100,12 @@ private static CustomStripItem RenderCtlSectorStripItem(FDP2.FDR fdr) private static CustomStripItem RenderAdsbCpdlcStripItem(FDP2.FDR fdr) { - var stripItem = GetStripItemWithColorsForDirection(fdr.GetAtopState().DirectionOfFlight); - stripItem.Text = fdr.GetDisplayState().CpdlcAdsbSymbol; + var stripItem = GetStripItemWithColorsForDirection(fdr.GetAtopState()?.DirectionOfFlight); + stripItem.Text = fdr.GetDisplayState()!.CpdlcAdsbSymbol; return stripItem; } - private static CustomStripItem GetStripItemWithColorsForDirection(DirectionOfFlight directionOfFlight) + private static CustomStripItem GetStripItemWithColorsForDirection(DirectionOfFlight? directionOfFlight) { var foreColorIdentity = directionOfFlight == DirectionOfFlight.Eastbound ? Colours.Identities.StripBackground diff --git a/Logic/NextSectorCalculator.cs b/Logic/NextSectorCalculator.cs index ca28317..c1c5270 100644 --- a/Logic/NextSectorCalculator.cs +++ b/Logic/NextSectorCalculator.cs @@ -20,7 +20,7 @@ public static class NextSectorCalculator if (nextSector == null) return nextSector; - SectorsVolumes.Sector sector = null; + SectorsVolumes.Sector? sector = null; foreach (var s2 in SectorsVolumes.SectorGroupings.Keys) if (s2.SubSectors.Contains(nextSector) && (sector == null || sector.SubSectors.Count > s2.SubSectors.Count)) diff --git a/State/AtopPluginStateManager.cs b/State/AtopPluginStateManager.cs index 14fda49..26fb194 100644 --- a/State/AtopPluginStateManager.cs +++ b/State/AtopPluginStateManager.cs @@ -63,4 +63,10 @@ public static async Task ProcessDisplayUpdate(FDP2.FDR fdr) await Task.Run(() => displayState.UpdateFromAtopState(atopState)); } } + + public static void Reset() + { + AircraftStates.Clear(); + DisplayStates.Clear(); + } } \ No newline at end of file diff --git a/State/DisconnectHandler.cs b/State/DisconnectHandler.cs new file mode 100644 index 0000000..fd7e6b7 --- /dev/null +++ b/State/DisconnectHandler.cs @@ -0,0 +1,11 @@ +using System; + +namespace AtopPlugin.State; + +public static class DisconnectHandler +{ + public static void Handle(object sender, EventArgs eventArgs) + { + AtopPluginStateManager.Reset(); + } +} \ No newline at end of file diff --git a/State/JurisdictionManager.cs b/State/JurisdictionManager.cs index bc1efaf..626fe97 100644 --- a/State/JurisdictionManager.cs +++ b/State/JurisdictionManager.cs @@ -13,12 +13,13 @@ public static async Task HandleFdrUpdate(FDP2.FDR fdr) if (!fdr.ESTed && MMI.IsMySectorConcerned(fdr)) MMI.EstFDR(fdr); var isInControlledSector = await IsInControlledSector(fdr.GetLocation(), fdr.PRL); + var atopState = fdr.GetAtopState(); // check if aircraft previously tracked to avoid re-tracking manually dropped/handed off tracks - if (isInControlledSector && !fdr.IsTracked && !fdr.GetAtopState().PreviouslyTracked) + if (isInControlledSector && !fdr.IsTracked && atopState is { PreviouslyTracked: false }) { MMI.AcceptJurisdiction(fdr); - fdr.GetAtopState().PreviouslyTracked = true; + atopState.PreviouslyTracked = true; } // if they're outside sector, currently tracked, and not going to re-enter, drop them diff --git a/State/PrivateMessagesChangedHandler.cs b/State/PrivateMessagesChangedHandler.cs index 9e14105..99d02eb 100644 --- a/State/PrivateMessagesChangedHandler.cs +++ b/State/PrivateMessagesChangedHandler.cs @@ -7,6 +7,6 @@ public static class PrivateMessagesChangedHandler public static void Handle(object sender, Network.GenericMessageEventArgs eventArgs) { var extendedFdrState = AtopPluginStateManager.GetAircraftState(eventArgs.Message.Address); - extendedFdrState.DownlinkIndicator = !eventArgs.Message.Sent; + if (extendedFdrState != null) extendedFdrState.DownlinkIndicator = !eventArgs.Message.Sent; } } \ No newline at end of file diff --git a/State/RadarFlagToggleHandler.cs b/State/RadarFlagToggleHandler.cs index 5f097b8..7145916 100644 --- a/State/RadarFlagToggleHandler.cs +++ b/State/RadarFlagToggleHandler.cs @@ -7,7 +7,7 @@ public static class RadarFlagToggleHandler public static void Handle(CustomLabelItemMouseClickEventArgs eventArgs) { var atopState = eventArgs.Track.GetFDR().GetAtopState(); - atopState.RadarToggleIndicator = !atopState.RadarToggleIndicator; + if (atopState != null) atopState.RadarToggleIndicator = !atopState.RadarToggleIndicator; eventArgs.Handled = true; } } \ No newline at end of file From 97c860d3e72aa9dde63ca9883f5cdc1e51e5dae9 Mon Sep 17 00:00:00 2001 From: Maxim Salikhov Date: Mon, 26 Feb 2024 12:58:38 -0500 Subject: [PATCH 63/76] Fix direction color showing for non jurisdiction tracks --- Display/LabelItemRenderer.cs | 6 +++--- Display/TrackColorRenderer.cs | 11 +++++------ 2 files changed, 8 insertions(+), 9 deletions(-) diff --git a/Display/LabelItemRenderer.cs b/Display/LabelItemRenderer.cs index 66a21c5..729183f 100644 --- a/Display/LabelItemRenderer.cs +++ b/Display/LabelItemRenderer.cs @@ -10,16 +10,16 @@ public static class LabelItemRenderer RDP.RadarTrack _) { var renderedItem = RenderLabelItemDelegate(itemType, track, fdr); - return renderedItem != null ? ExcludeConflictColor(fdr!, renderedItem) : null; + return renderedItem != null ? ExcludeConflictColor(fdr!, track, renderedItem) : null; } - private static CustomLabelItem ExcludeConflictColor(FDP2.FDR fdr, CustomLabelItem customLabelItem) + private static CustomLabelItem ExcludeConflictColor(FDP2.FDR fdr, Track track, CustomLabelItem customLabelItem) { // If we already overrode it, keep it that way if (customLabelItem.ForeColourIdentity == Colours.Identities.Custom) return customLabelItem; customLabelItem.ForeColourIdentity = Colours.Identities.Custom; - customLabelItem.CustomForeColour = TrackColorRenderer.GetDirectionColour(fdr) ?? CustomColors.ApsBlue; + customLabelItem.CustomForeColour = TrackColorRenderer.GetDirectionColour(fdr, track) ?? CustomColors.ApsBlue; return customLabelItem; } diff --git a/Display/TrackColorRenderer.cs b/Display/TrackColorRenderer.cs index a03d857..85e0106 100644 --- a/Display/TrackColorRenderer.cs +++ b/Display/TrackColorRenderer.cs @@ -12,17 +12,16 @@ public static class TrackColorRenderer if (fdr == null) return null; - return (IsInJurisdiction(track), fdr.State) switch + return fdr.State switch { - { Item1: true } => GetConflictColour(fdr) ?? GetDirectionColour(fdr), - { State: FDP2.FDR.FDRStates.STATE_PREACTIVE or FDP2.FDR.FDRStates.STATE_COORDINATED } => - GetConflictColour(fdr), - _ => null + FDP2.FDR.FDRStates.STATE_PREACTIVE or FDP2.FDR.FDRStates.STATE_COORDINATED => GetConflictColour(fdr), + _ => GetConflictColour(fdr) ?? GetDirectionColour(fdr, track) }; } - public static CustomColour? GetDirectionColour(FDP2.FDR fdr) + public static CustomColour? GetDirectionColour(FDP2.FDR fdr, Track track) { + if (!IsInJurisdiction(track)) return null; return fdr.GetAtopState()?.DirectionOfFlight switch { DirectionOfFlight.Eastbound => CustomColors.EastboundColour, From 19e8283372c8c6b338c7bce1bddbfdef22691e6a Mon Sep 17 00:00:00 2001 From: Maxim Salikhov Date: Tue, 27 Feb 2024 09:11:33 -0500 Subject: [PATCH 64/76] Fix display of ADSB/no-CPDLC state --- Display/StripItemRenderer.cs | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/Display/StripItemRenderer.cs b/Display/StripItemRenderer.cs index 23882f6..c2f02dc 100644 --- a/Display/StripItemRenderer.cs +++ b/Display/StripItemRenderer.cs @@ -76,7 +76,7 @@ public static class StripItemRenderer private static CustomStripItem RenderCallsignStripItem(FDP2.FDR fdr) { - var stripItem = GetStripItemWithColorsForDirection(fdr.GetAtopState().DirectionOfFlight); + var stripItem = GetStripItemWithColorsForDirection(fdr.GetAtopState()?.DirectionOfFlight); stripItem.Text = fdr.Callsign; return stripItem; } @@ -98,10 +98,13 @@ private static CustomStripItem RenderCtlSectorStripItem(FDP2.FDR fdr) return stripItem; } - private static CustomStripItem RenderAdsbCpdlcStripItem(FDP2.FDR fdr) + private static CustomStripItem? RenderAdsbCpdlcStripItem(FDP2.FDR fdr) { + var text = fdr.GetDisplayState()!.CpdlcAdsbSymbol; + if (string.IsNullOrEmpty(text)) return null; + var stripItem = GetStripItemWithColorsForDirection(fdr.GetAtopState()?.DirectionOfFlight); - stripItem.Text = fdr.GetDisplayState()!.CpdlcAdsbSymbol; + stripItem.Text = text; return stripItem; } From a88b70e0a50be84c805c512c630a119359661f59 Mon Sep 17 00:00:00 2001 From: Maxim Salikhov Date: Tue, 27 Feb 2024 09:19:32 -0500 Subject: [PATCH 65/76] Show ADS/lateral flag activated --- Display/StripItemRenderer.cs | 22 +++++++++++++++------- 1 file changed, 15 insertions(+), 7 deletions(-) diff --git a/Display/StripItemRenderer.cs b/Display/StripItemRenderer.cs index c2f02dc..ee2b90e 100644 --- a/Display/StripItemRenderer.cs +++ b/Display/StripItemRenderer.cs @@ -32,11 +32,13 @@ public static class StripItemRenderer ? new CustomStripItem { Text = Symbols.Mnt } : null, - StripConstants.StripItemDistFlag => new CustomStripItem - { - Text = displayState.AdsFlag, ForeColourIdentity = Colours.Identities.Custom, - CustomForeColour = CustomColors.SepFlags - }, + StripConstants.StripItemDistFlag => !string.IsNullOrEmpty(displayState.AdsFlag) + ? new CustomStripItem + { + Text = displayState.AdsFlag, BackColourIdentity = Colours.Identities.Custom, + CustomBackColour = CustomColors.SepFlags + } + : null, StripConstants.StripItemRvsmFlag => fdr.RVSM ? new CustomStripItem @@ -64,7 +66,13 @@ public static class StripItemRenderer ? new CustomStripItem { Text = Symbols.ScratchpadFlag } : new CustomStripItem { Text = Symbols.EmptyAnnotations }, - StripConstants.StripItemLateralFlag => new CustomStripItem { Text = displayState.LateralFlag }, + StripConstants.StripItemLateralFlag => !string.IsNullOrEmpty(displayState.LateralFlag) + ? new CustomStripItem + { + Text = displayState.LateralFlag, BackColourIdentity = Colours.Identities.Custom, + CustomBackColour = CustomColors.SepFlags + } + : null, StripConstants.StripItemRestr => displayState.IsRestrictionsIndicatorToggled ? new CustomStripItem { Text = Symbols.RestrictionsFlag } @@ -102,7 +110,7 @@ private static CustomStripItem RenderCtlSectorStripItem(FDP2.FDR fdr) { var text = fdr.GetDisplayState()!.CpdlcAdsbSymbol; if (string.IsNullOrEmpty(text)) return null; - + var stripItem = GetStripItemWithColorsForDirection(fdr.GetAtopState()?.DirectionOfFlight); stripItem.Text = text; return stripItem; From 880b593db93fea290934dafa2e29191c52cfd61a Mon Sep 17 00:00:00 2001 From: Maxim Salikhov Date: Tue, 27 Feb 2024 09:33:59 -0500 Subject: [PATCH 66/76] Show VMI in tangerine when non-RVSM --- Display/LabelItemRenderer.cs | 18 +++++++++++++++++- 1 file changed, 17 insertions(+), 1 deletion(-) diff --git a/Display/LabelItemRenderer.cs b/Display/LabelItemRenderer.cs index 729183f..726cd2a 100644 --- a/Display/LabelItemRenderer.cs +++ b/Display/LabelItemRenderer.cs @@ -94,7 +94,23 @@ private static CustomLabelItem ExcludeConflictColor(FDP2.FDR fdr, Track track, C CustomForeColour = displayState.AltitudeColor }, - LabelConstants.LabelItemVmi => new CustomLabelItem { Text = atopState.AltitudeFlag?.Value ?? "" }, + LabelConstants.LabelItemVmi => displayState.AltitudeColor == null + ? new CustomLabelItem + { + Text = atopState.AltitudeFlag?.Value ?? "", + Border = displayState.AltitudeBorderFlags, + BorderColourIdentity = Colours.Identities.Custom, + CustomBorderColour = CustomColors.NotCda + } + : new CustomLabelItem + { + Text = atopState.AltitudeFlag?.Value ?? "", + Border = displayState.AltitudeBorderFlags, + BorderColourIdentity = Colours.Identities.Custom, + CustomBorderColour = CustomColors.NotCda, + ForeColourIdentity = Colours.Identities.Custom, + CustomForeColour = displayState.AltitudeColor + }, LabelConstants.LabelItemClearedLevel => displayState.AltitudeColor == null ? new CustomLabelItem From cd8ec181f52637f8d47d573f5df573b681f21f20 Mon Sep 17 00:00:00 2001 From: Maxim Salikhov Date: Tue, 27 Feb 2024 09:41:43 -0500 Subject: [PATCH 67/76] Don't display PRL when it is 0/blank --- Logic/AltitudeCalculator.cs | 9 +++++++-- State/AtopAircraftDisplayState.cs | 8 +++++++- 2 files changed, 14 insertions(+), 3 deletions(-) diff --git a/Logic/AltitudeCalculator.cs b/Logic/AltitudeCalculator.cs index ce8c65e..09ba2ef 100644 --- a/Logic/AltitudeCalculator.cs +++ b/Logic/AltitudeCalculator.cs @@ -19,9 +19,9 @@ public static bool CalculateAltitudeChangePending(FDP2.FDR updatedFdr, AltitudeB { var altitudeBlock = AltitudeBlock.ExtractAltitudeBlock(fdr); var (altitudeLower, altitudeUpper) = altitudeBlock; - var isOutsideThreshold = !IsWithinThreshold(fdr.PRL, altitudeBlock); + var isOutsideThresholdAndNotBlank = !IsWithinThreshold(fdr.PRL, altitudeBlock) && !IsBlank(fdr.PRL); - return isOutsideThreshold switch + return isOutsideThresholdAndNotBlank switch { true when pendingAltitudeChange && fdr.PRL < altitudeLower => AltitudeFlag.Climbing, true when pendingAltitudeChange && fdr.PRL > altitudeUpper => AltitudeFlag.Descending, @@ -37,4 +37,9 @@ public static bool IsWithinThreshold(int pilotReportedAltitude, AltitudeBlock al var upperWithThreshold = altitudeBlock.UpperAltitude + LevelFlightThreshold; return pilotReportedAltitude > lowerWithThreshold && pilotReportedAltitude < upperWithThreshold; } + + private static bool IsBlank(int altitude) + { + return altitude < 100; + } } \ No newline at end of file diff --git a/State/AtopAircraftDisplayState.cs b/State/AtopAircraftDisplayState.cs index 0028fa4..536d99d 100644 --- a/State/AtopAircraftDisplayState.cs +++ b/State/AtopAircraftDisplayState.cs @@ -37,7 +37,7 @@ public void UpdateFromAtopState(AtopAircraftState atopAircraftState) IsMntFlagToggled = atopAircraftState.Fdr.IsJet(); HasAnnotations = !string.IsNullOrEmpty(atopAircraftState.Fdr.LabelOpData); IsRestrictionsIndicatorToggled = GetRestrictionsIndicatorToggled(atopAircraftState); - CurrentLevel = (atopAircraftState.Fdr.PRL / 100).ToString(); + CurrentLevel = GetCurrentLevel(atopAircraftState); ClearedLevel = GetClearedLevel(atopAircraftState); RequestedLevel = GetRequestedLevel(atopAircraftState); AltitudeBorderFlags = GetAltitudeBorderFlags(atopAircraftState); @@ -84,6 +84,12 @@ private static bool GetRestrictionsIndicatorToggled(AtopAircraftState atopAircra return RestrictionLabels.Any(label => atopAircraftState.Fdr.LabelOpData.Contains(label)); } + private static string GetCurrentLevel(AtopAircraftState atopAircraftState) + { + var prlHundreds = atopAircraftState.Fdr.PRL / 100; + return prlHundreds == 0 ? "" : prlHundreds.ToString(); + } + private static string GetClearedLevel(AtopAircraftState atopAircraftState) { var fdr = atopAircraftState.Fdr; From a5a40276b9f366d7c782f5dfd546ad037bc10746 Mon Sep 17 00:00:00 2001 From: Maxim Salikhov Date: Mon, 4 Mar 2024 08:44:08 -0500 Subject: [PATCH 68/76] Conflict probing improvements (#3) * Separate out conflict probe step * Add button to disable conflict probe * Run conflict probe on CFL change --- AtopPlugin.cs | 22 +++++ AtopPlugin.csproj | 25 ++++++ Display/TrackColorRenderer.cs | 2 +- Extensions.cs | 8 +- State/AtopAircraftState.cs | 5 +- State/AtopPluginStateManager.cs | 30 +++++++ State/FdrPropertyChangesListener.cs | 1 + UI/SettingsWindow.Designer.cs | 67 ++++++++++++++++ UI/SettingsWindow.cs | 19 +++++ UI/SettingsWindow.resx | 120 ++++++++++++++++++++++++++++ packages.config | 1 + 11 files changed, 294 insertions(+), 6 deletions(-) create mode 100644 UI/SettingsWindow.Designer.cs create mode 100644 UI/SettingsWindow.cs create mode 100644 UI/SettingsWindow.resx diff --git a/AtopPlugin.cs b/AtopPlugin.cs index ade087b..1c9b063 100644 --- a/AtopPlugin.cs +++ b/AtopPlugin.cs @@ -1,6 +1,8 @@ using System.ComponentModel.Composition; +using System.Windows.Forms; using AtopPlugin.Display; using AtopPlugin.State; +using AtopPlugin.UI; using vatsys; using vatsys.Plugin; @@ -11,9 +13,17 @@ public class AtopPlugin : ILabelPlugin, IStripPlugin { public string Name => "ATOP Plugin"; + private static readonly SettingsWindow SettingsWindow; + + static AtopPlugin() + { + SettingsWindow = new SettingsWindow(); + } + public AtopPlugin() { RegisterEventHandlers(); + AddCustomMenuItems(); } private static void RegisterEventHandlers() @@ -26,10 +36,22 @@ private static void RegisterEventHandlers() FdrPropertyChangesListener.RegisterAllHandlers(); } + private static void AddCustomMenuItems() + { + var settingsMenu = new CustomToolStripMenuItem(CustomToolStripMenuItemWindowType.Main, + CustomToolStripMenuItemCategory.Custom, new ToolStripMenuItem("Settings")) + { + CustomCategoryName = "ATOP" + }; + settingsMenu.Item.Click += (_, _) => MMI.InvokeOnGUI(SettingsWindow.Show); + MMI.AddCustomMenuItem(settingsMenu); + } + public void OnFDRUpdate(FDP2.FDR updated) { AtopPluginStateManager.ProcessFdrUpdate(updated); AtopPluginStateManager.ProcessDisplayUpdate(updated); + AtopPluginStateManager.RunConflictProbe(updated); FdrPropertyChangesListener.RegisterHandler(updated); // don't manage jurisdiction if not connected as ATC diff --git a/AtopPlugin.csproj b/AtopPlugin.csproj index 57c38b1..77b37c7 100644 --- a/AtopPlugin.csproj +++ b/AtopPlugin.csproj @@ -38,6 +38,10 @@ + + + packages\Microsoft.NETFramework.ReferenceAssemblies.net48.1.0.3\build\.NETFramework\v4.8\System.Windows.Forms.dll + @@ -79,6 +83,27 @@ + + Form + + + SettingsWindow.cs + + + + + + + + SettingsWindow.cs + + + + + This project references NuGet package(s) that are missing on this computer. Enable NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105.The missing file is {0}. + + + \ No newline at end of file diff --git a/Display/TrackColorRenderer.cs b/Display/TrackColorRenderer.cs index 85e0106..005804d 100644 --- a/Display/TrackColorRenderer.cs +++ b/Display/TrackColorRenderer.cs @@ -32,7 +32,7 @@ public static class TrackColorRenderer private static CustomColour? GetConflictColour(FDP2.FDR fdr) { - return fdr.GetAtopState()?.Conflicts switch + return fdr.GetConflicts() switch { { ActualConflicts.Count: > 0 } or { ImminentConflicts.Count: > 0 } => CustomColors.Imminent, { AdvisoryConflicts.Count: > 0 } => CustomColors.Advisory, diff --git a/Extensions.cs b/Extensions.cs index 7a65b43..7d06ca1 100644 --- a/Extensions.cs +++ b/Extensions.cs @@ -1,4 +1,5 @@ -using AtopPlugin.State; +using AtopPlugin.Conflict; +using AtopPlugin.State; using vatsys; namespace AtopPlugin; @@ -15,6 +16,11 @@ public static class Extensions return AtopPluginStateManager.GetDisplayState(fdr.Callsign); } + public static ConflictProbe.Conflicts? GetConflicts(this FDP2.FDR fdr) + { + return AtopPluginStateManager.GetConflicts(fdr.Callsign); + } + public static int? GetTransponderCode(this FDP2.FDR fdr) { return fdr.CoupledTrack?.ActualAircraft.TransponderCode; diff --git a/State/AtopAircraftState.cs b/State/AtopAircraftState.cs index d9f5bf0..c66fae5 100644 --- a/State/AtopAircraftState.cs +++ b/State/AtopAircraftState.cs @@ -1,5 +1,4 @@ -using AtopPlugin.Conflict; -using AtopPlugin.Logic; +using AtopPlugin.Logic; using AtopPlugin.Models; using vatsys; @@ -17,7 +16,6 @@ public AtopAircraftState(FDP2.FDR fdr) } public FDP2.FDR Fdr { get; private set; } - public ConflictProbe.Conflicts Conflicts { get; private set; } public CalculatedFlightData CalculatedFlightData { get; private set; } public DirectionOfFlight DirectionOfFlight { get; private set; } public SccFlag? HighestSccFlag { get; private set; } @@ -33,7 +31,6 @@ public AtopAircraftState(FDP2.FDR fdr) public void UpdateFromFdr(FDP2.FDR updatedFdr) { Fdr = updatedFdr; - Conflicts = ConflictProbe.Probe(updatedFdr); CalculatedFlightData = FlightDataCalculator.GetCalculatedFlightData(updatedFdr); DirectionOfFlight = DirectionOfFlightCalculator.GetDirectionOfFlight(updatedFdr); diff --git a/State/AtopPluginStateManager.cs b/State/AtopPluginStateManager.cs index 26fb194..2804bcc 100644 --- a/State/AtopPluginStateManager.cs +++ b/State/AtopPluginStateManager.cs @@ -1,5 +1,6 @@ using System.Collections.Concurrent; using System.Threading.Tasks; +using AtopPlugin.Conflict; using vatsys; namespace AtopPlugin.State; @@ -10,6 +11,8 @@ public static class AtopPluginStateManager private static readonly ConcurrentDictionary AircraftStates = new(); private static readonly ConcurrentDictionary DisplayStates = new(); + private static readonly ConcurrentDictionary Conflicts = new(); + private static bool _probeEnabled = true; public static AtopAircraftState? GetAircraftState(string callsign) { @@ -23,6 +26,12 @@ public static class AtopPluginStateManager return found ? state : null; } + public static ConflictProbe.Conflicts? GetConflicts(string callsign) + { + var found = Conflicts.TryGetValue(callsign, out var state); + return found ? state : null; + } + public static async Task ProcessFdrUpdate(FDP2.FDR updated) { var callsign = updated.Callsign; @@ -64,9 +73,30 @@ public static async Task ProcessDisplayUpdate(FDP2.FDR fdr) } } + public static async Task RunConflictProbe(FDP2.FDR fdr) + { + if (_probeEnabled) + { + var newConflicts = await Task.Run(() => ConflictProbe.Probe(fdr)); + Conflicts.AddOrUpdate(fdr.Callsign, newConflicts, (_, _) => newConflicts); + } + } + + public static bool IsConflictProbeEnabled() + { + return _probeEnabled; + } + + public static void SetConflictProbe(bool conflictProbeEnabled) + { + _probeEnabled = conflictProbeEnabled; + if (!_probeEnabled) Conflicts.Clear(); + } + public static void Reset() { AircraftStates.Clear(); DisplayStates.Clear(); + Conflicts.Clear(); } } \ No newline at end of file diff --git a/State/FdrPropertyChangesListener.cs b/State/FdrPropertyChangesListener.cs index 051c893..ed81788 100644 --- a/State/FdrPropertyChangesListener.cs +++ b/State/FdrPropertyChangesListener.cs @@ -29,5 +29,6 @@ private static async void Handle(object sender, PropertyChangedEventArgs eventAr if (!RelevantProperties.Contains(eventArgs.PropertyName)) return; await AtopPluginStateManager.ProcessFdrUpdate(fdr); await AtopPluginStateManager.ProcessDisplayUpdate(fdr); + await AtopPluginStateManager.RunConflictProbe(fdr); } } \ No newline at end of file diff --git a/UI/SettingsWindow.Designer.cs b/UI/SettingsWindow.Designer.cs new file mode 100644 index 0000000..ab80d16 --- /dev/null +++ b/UI/SettingsWindow.Designer.cs @@ -0,0 +1,67 @@ +using System.ComponentModel; + +namespace AtopPlugin.UI; + +partial class SettingsWindow +{ + /// + /// Required designer variable. + /// + private IContainer components = null; + + /// + /// Clean up any resources being used. + /// + /// true if managed resources should be disposed; otherwise, false. + protected override void Dispose(bool disposing) + { + if (disposing && (components != null)) + { + components.Dispose(); + } + + base.Dispose(disposing); + } + + #region Windows Form Designer generated code + + /// + /// Required method for Designer support - do not modify + /// the contents of this method with the code editor. + /// + private void InitializeComponent() + { + this.probe = new System.Windows.Forms.CheckBox(); + this.SuspendLayout(); + // + // probe + // + this.probe.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom) | System.Windows.Forms.AnchorStyles.Left) | System.Windows.Forms.AnchorStyles.Right))); + this.probe.Appearance = System.Windows.Forms.Appearance.Button; + this.probe.CheckAlign = System.Drawing.ContentAlignment.MiddleCenter; + this.probe.Font = new System.Drawing.Font("Terminus (TTF)", 18F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, ((byte)(0))); + this.probe.Location = new System.Drawing.Point(25, 12); + this.probe.Name = "probe"; + this.probe.Size = new System.Drawing.Size(100, 50); + this.probe.TabIndex = 1; + this.probe.Text = "PROBE"; + this.probe.TextAlign = System.Drawing.ContentAlignment.MiddleCenter; + this.probe.UseVisualStyleBackColor = true; + this.probe.CheckedChanged += new System.EventHandler(this.probe_CheckedChanged); + // + // SettingsWindow + // + this.AutoScaleDimensions = new System.Drawing.SizeF(8F, 17F); + this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; + this.ClientSize = new System.Drawing.Size(146, 72); + this.Controls.Add(this.probe); + this.Name = "SettingsWindow"; + this.Text = "ATOP Settings"; + this.TopMost = true; + this.ResumeLayout(false); + } + + private System.Windows.Forms.CheckBox probe; + + #endregion +} \ No newline at end of file diff --git a/UI/SettingsWindow.cs b/UI/SettingsWindow.cs new file mode 100644 index 0000000..e91a4da --- /dev/null +++ b/UI/SettingsWindow.cs @@ -0,0 +1,19 @@ +using System; +using AtopPlugin.State; +using vatsys; + +namespace AtopPlugin.UI; + +public partial class SettingsWindow : BaseForm +{ + public SettingsWindow() + { + InitializeComponent(); + probe.Checked = AtopPluginStateManager.IsConflictProbeEnabled(); + } + + private void probe_CheckedChanged(object sender, EventArgs e) + { + AtopPluginStateManager.SetConflictProbe(probe.Checked); + } +} \ No newline at end of file diff --git a/UI/SettingsWindow.resx b/UI/SettingsWindow.resx new file mode 100644 index 0000000..d58980a --- /dev/null +++ b/UI/SettingsWindow.resx @@ -0,0 +1,120 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + \ No newline at end of file diff --git a/packages.config b/packages.config index 5a1dc50..85828e6 100644 --- a/packages.config +++ b/packages.config @@ -1,4 +1,5 @@  + \ No newline at end of file From 5b83b45fe9c94db6e1ac8e0594da441960a76ab5 Mon Sep 17 00:00:00 2001 From: Dominic Nguyen Date: Mon, 4 Mar 2024 11:53:26 -0800 Subject: [PATCH 69/76] CPDLC icon sized by labels xml --- Constants.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Constants.cs b/Constants.cs index 3a8d9c7..1f3f8f4 100644 --- a/Constants.cs +++ b/Constants.cs @@ -10,7 +10,7 @@ public static class CustomColors public static readonly CustomColour WestboundColour = new(240, 231, 140); public static readonly CustomColour NonRvsm = new(242, 133, 0); public static readonly CustomColour Probe = new(0, 255, 0); - public static readonly CustomColour NotCda = new(100, 0, 100); + public static readonly CustomColour NotCda = new(211, 28, 111); public static readonly CustomColour Advisory = new(255, 165, 0); public static readonly CustomColour Imminent = new(255, 0, 0); public static readonly CustomColour SpecialConditionCode = new(255, 255, 0); @@ -23,7 +23,7 @@ public static class Symbols public const string NoCpdlcNoAdsb = "⎕"; public const string CpdlcNoAdsb = "⧆"; - public const string CpdlcAndAdsb = "✱"; + public const string CpdlcAndAdsb = "*";//✱ public const string D30 = "3"; public const string D50 = "D"; From b9f3ee9d3f193bb55677426c0f7c69d47ecd688b Mon Sep 17 00:00:00 2001 From: Maxim Salikhov Date: Wed, 20 Mar 2024 23:37:47 -0400 Subject: [PATCH 70/76] Datablock bugfixes (#5) * Add padding for altitude label items * Fix RNP SCC flag showing up when RNP10 equipped * Show PRL as flight level when within tolerance --- Display/LabelItemRenderer.cs | 12 ++++++------ Logic/SccFlagCalculator.cs | 18 ++++++------------ State/AtopAircraftDisplayState.cs | 11 +++++++++-- 3 files changed, 21 insertions(+), 20 deletions(-) diff --git a/Display/LabelItemRenderer.cs b/Display/LabelItemRenderer.cs index 726cd2a..de0b489 100644 --- a/Display/LabelItemRenderer.cs +++ b/Display/LabelItemRenderer.cs @@ -79,14 +79,14 @@ private static CustomLabelItem ExcludeConflictColor(FDP2.FDR fdr, Track track, C LabelConstants.LabelItemLevel => displayState.AltitudeColor == null ? new CustomLabelItem { - Text = displayState.CurrentLevel, + Text = displayState.CurrentLevel.PadLeft(3), Border = displayState.AltitudeBorderFlags, BorderColourIdentity = Colours.Identities.Custom, CustomBorderColour = CustomColors.NotCda } : new CustomLabelItem { - Text = displayState.CurrentLevel, + Text = displayState.CurrentLevel.PadLeft(3), Border = displayState.AltitudeBorderFlags, BorderColourIdentity = Colours.Identities.Custom, CustomBorderColour = CustomColors.NotCda, @@ -97,14 +97,14 @@ private static CustomLabelItem ExcludeConflictColor(FDP2.FDR fdr, Track track, C LabelConstants.LabelItemVmi => displayState.AltitudeColor == null ? new CustomLabelItem { - Text = atopState.AltitudeFlag?.Value ?? "", + Text = (atopState.AltitudeFlag?.Value ?? "").PadLeft(1), Border = displayState.AltitudeBorderFlags, BorderColourIdentity = Colours.Identities.Custom, CustomBorderColour = CustomColors.NotCda } : new CustomLabelItem { - Text = atopState.AltitudeFlag?.Value ?? "", + Text = (atopState.AltitudeFlag?.Value ?? "").PadLeft(1), Border = displayState.AltitudeBorderFlags, BorderColourIdentity = Colours.Identities.Custom, CustomBorderColour = CustomColors.NotCda, @@ -115,14 +115,14 @@ private static CustomLabelItem ExcludeConflictColor(FDP2.FDR fdr, Track track, C LabelConstants.LabelItemClearedLevel => displayState.AltitudeColor == null ? new CustomLabelItem { - Text = displayState.ClearedLevel, + Text = displayState.ClearedLevel.PadLeft(3), Border = displayState.AltitudeBorderFlags, BorderColourIdentity = Colours.Identities.Custom, CustomBorderColour = CustomColors.NotCda } : new CustomLabelItem { - Text = displayState.ClearedLevel, + Text = displayState.ClearedLevel.PadLeft(3), Border = displayState.AltitudeBorderFlags, BorderColourIdentity = Colours.Identities.Custom, CustomBorderColour = CustomColors.NotCda, diff --git a/Logic/SccFlagCalculator.cs b/Logic/SccFlagCalculator.cs index c82e955..07e5a7b 100644 --- a/Logic/SccFlagCalculator.cs +++ b/Logic/SccFlagCalculator.cs @@ -12,18 +12,12 @@ public static class SccFlagCalculator public static SccFlag? CalculateHighestPriorityFlag(FDP2.FDR fdr, CalculatedFlightData calculatedFlightData) { var transponderCode = fdr.GetTransponderCode(); - switch (transponderCode) + return transponderCode switch { - case EmergencyCode: - return SccFlag.Emg; - case RadioFailureCode: - return SccFlag.Rcf; - case MilitaryInterceptCode: - return SccFlag.Mti; - } - - if (!calculatedFlightData.Rnp4 || !calculatedFlightData.Rnp10) return SccFlag.Rnp; - - return null; + EmergencyCode => SccFlag.Emg, + RadioFailureCode => SccFlag.Rcf, + MilitaryInterceptCode => SccFlag.Mti, + _ => calculatedFlightData is { Rnp4: false, Rnp10: false } ? SccFlag.Rnp : null + }; } } \ No newline at end of file diff --git a/State/AtopAircraftDisplayState.cs b/State/AtopAircraftDisplayState.cs index 536d99d..f89a550 100644 --- a/State/AtopAircraftDisplayState.cs +++ b/State/AtopAircraftDisplayState.cs @@ -1,4 +1,5 @@ -using System.Linq; +using System; +using System.Linq; using AtopPlugin.Logic; using AtopPlugin.Models; using vatsys; @@ -86,7 +87,13 @@ private static bool GetRestrictionsIndicatorToggled(AtopAircraftState atopAircra private static string GetCurrentLevel(AtopAircraftState atopAircraftState) { - var prlHundreds = atopAircraftState.Fdr.PRL / 100; + var fdr = atopAircraftState.Fdr; + var altitudeBlock = AltitudeBlock.ExtractAltitudeBlock(fdr); + + var prlHundreds = (int)Math.Round(atopAircraftState.Fdr.PRL / 100.0); + if (!atopAircraftState.PendingAltitudeChange || AltitudeCalculator.IsWithinThreshold(fdr.PRL, altitudeBlock)) + return prlHundreds == 0 ? "" : (int)Math.Round(prlHundreds / 10.0) + "0"; + return prlHundreds == 0 ? "" : prlHundreds.ToString(); } From f63e3e9407e7bf6b7467aec39a3e62c7ef87023a Mon Sep 17 00:00:00 2001 From: Maxim Salikhov Date: Wed, 20 Mar 2024 23:49:26 -0400 Subject: [PATCH 71/76] Don't dispose settings window on close (#6) --- UI/SettingsWindow.Designer.cs | 1 + 1 file changed, 1 insertion(+) diff --git a/UI/SettingsWindow.Designer.cs b/UI/SettingsWindow.Designer.cs index ab80d16..0ab4fa0 100644 --- a/UI/SettingsWindow.Designer.cs +++ b/UI/SettingsWindow.Designer.cs @@ -55,6 +55,7 @@ private void InitializeComponent() this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; this.ClientSize = new System.Drawing.Size(146, 72); this.Controls.Add(this.probe); + this.HideOnClose = true; this.Name = "SettingsWindow"; this.Text = "ATOP Settings"; this.TopMost = true; From 3462a475d04f265b1ead2cc612313d83a238ff48 Mon Sep 17 00:00:00 2001 From: Maxim Salikhov Date: Fri, 22 Mar 2024 22:29:35 -0400 Subject: [PATCH 72/76] Add OR SCC for when aircraft disconnected (#7) --- Extensions.cs | 6 ++++++ Logic/SccFlagCalculator.cs | 2 ++ Models/SccFlag.cs | 1 + State/JurisdictionManager.cs | 1 - 4 files changed, 9 insertions(+), 1 deletion(-) diff --git a/Extensions.cs b/Extensions.cs index 7d06ca1..39bd82d 100644 --- a/Extensions.cs +++ b/Extensions.cs @@ -31,6 +31,12 @@ public static bool IsJet(this FDP2.FDR fdr) return fdr.PerformanceData?.IsJet ?? false; } + public static bool IsConnected(this FDP2.FDR fdr) + { + return fdr.CoupledTrack?.ActualAircraft != null || + Network.GetOnlinePilots.Exists(pilot => pilot.Callsign == fdr.Callsign); + } + public static bool IsSelected(this Track track) { return MMI.SelectedTrack == track; diff --git a/Logic/SccFlagCalculator.cs b/Logic/SccFlagCalculator.cs index 07e5a7b..2fba290 100644 --- a/Logic/SccFlagCalculator.cs +++ b/Logic/SccFlagCalculator.cs @@ -11,6 +11,8 @@ public static class SccFlagCalculator public static SccFlag? CalculateHighestPriorityFlag(FDP2.FDR fdr, CalculatedFlightData calculatedFlightData) { + if (!fdr.IsConnected()) return SccFlag.Or; + var transponderCode = fdr.GetTransponderCode(); return transponderCode switch { diff --git a/Models/SccFlag.cs b/Models/SccFlag.cs index f19c608..591d753 100644 --- a/Models/SccFlag.cs +++ b/Models/SccFlag.cs @@ -13,4 +13,5 @@ private SccFlag(string value) public static SccFlag Emg => new("EMG"); public static SccFlag Rcf => new("RCF"); public static SccFlag Mti => new("MTI"); + public static SccFlag Or => new("OR"); // out of range flag to represent pilot has has disconnected } \ No newline at end of file diff --git a/State/JurisdictionManager.cs b/State/JurisdictionManager.cs index 626fe97..45e9237 100644 --- a/State/JurisdictionManager.cs +++ b/State/JurisdictionManager.cs @@ -9,7 +9,6 @@ public static class JurisdictionManager { public static async Task HandleFdrUpdate(FDP2.FDR fdr) { - // TODO(msalikhov): Because of this its impossible to cancel an FDR that's disconnected if (!fdr.ESTed && MMI.IsMySectorConcerned(fdr)) MMI.EstFDR(fdr); var isInControlledSector = await IsInControlledSector(fdr.GetLocation(), fdr.PRL); From d697597c221b845575f0122ea30267e1c1bfb5b9 Mon Sep 17 00:00:00 2001 From: Maxim Salikhov Date: Sat, 23 Mar 2024 11:36:37 -0400 Subject: [PATCH 73/76] Improve jurisdiction logic & add activation functionality (#8) * Change logic for when deciding whether to auto-accept jurisdiction Rather than going off whether the aircraft was previously tracked, we'll use whether its been handed off to a sector or to no one. * Setup menu for activating session * Only auto-assume when activated * Refactor & fix activation functionality --- AtopPlugin.cs | 21 +------------- AtopPlugin.csproj | 1 + State/AtopAircraftState.cs | 5 ++-- State/AtopPluginStateManager.cs | 34 ++++++++++++++++++++++ State/JurisdictionManager.cs | 11 ++++---- UI/AtopMenu.cs | 50 +++++++++++++++++++++++++++++++++ 6 files changed, 95 insertions(+), 27 deletions(-) create mode 100644 UI/AtopMenu.cs diff --git a/AtopPlugin.cs b/AtopPlugin.cs index 1c9b063..44b9aa8 100644 --- a/AtopPlugin.cs +++ b/AtopPlugin.cs @@ -1,5 +1,4 @@ using System.ComponentModel.Composition; -using System.Windows.Forms; using AtopPlugin.Display; using AtopPlugin.State; using AtopPlugin.UI; @@ -13,17 +12,10 @@ public class AtopPlugin : ILabelPlugin, IStripPlugin { public string Name => "ATOP Plugin"; - private static readonly SettingsWindow SettingsWindow; - - static AtopPlugin() - { - SettingsWindow = new SettingsWindow(); - } - public AtopPlugin() { RegisterEventHandlers(); - AddCustomMenuItems(); + AtopMenu.Initialize(); } private static void RegisterEventHandlers() @@ -36,17 +28,6 @@ private static void RegisterEventHandlers() FdrPropertyChangesListener.RegisterAllHandlers(); } - private static void AddCustomMenuItems() - { - var settingsMenu = new CustomToolStripMenuItem(CustomToolStripMenuItemWindowType.Main, - CustomToolStripMenuItemCategory.Custom, new ToolStripMenuItem("Settings")) - { - CustomCategoryName = "ATOP" - }; - settingsMenu.Item.Click += (_, _) => MMI.InvokeOnGUI(SettingsWindow.Show); - MMI.AddCustomMenuItem(settingsMenu); - } - public void OnFDRUpdate(FDP2.FDR updated) { AtopPluginStateManager.ProcessFdrUpdate(updated); diff --git a/AtopPlugin.csproj b/AtopPlugin.csproj index 77b37c7..bb6ee53 100644 --- a/AtopPlugin.csproj +++ b/AtopPlugin.csproj @@ -83,6 +83,7 @@ + Form diff --git a/State/AtopAircraftState.cs b/State/AtopAircraftState.cs index c66fae5..300ff07 100644 --- a/State/AtopAircraftState.cs +++ b/State/AtopAircraftState.cs @@ -12,7 +12,7 @@ public AtopAircraftState(FDP2.FDR fdr) UpdateFromFdr(fdr); DownlinkIndicator = false; RadarToggleIndicator = false; - PreviouslyTracked = false; + WasHandedOff = false; } public FDP2.FDR Fdr { get; private set; } @@ -23,7 +23,7 @@ public AtopAircraftState(FDP2.FDR fdr) public SectorsVolumes.Sector? NextSector { get; private set; } public bool DownlinkIndicator { get; set; } public bool RadarToggleIndicator { get; set; } - public bool PreviouslyTracked { get; set; } + public bool WasHandedOff { get; private set; } public bool PendingAltitudeChange { get; private set; } private AltitudeBlock PreviousAltitudeBlock { get; set; } @@ -34,6 +34,7 @@ public void UpdateFromFdr(FDP2.FDR updatedFdr) CalculatedFlightData = FlightDataCalculator.GetCalculatedFlightData(updatedFdr); DirectionOfFlight = DirectionOfFlightCalculator.GetDirectionOfFlight(updatedFdr); + WasHandedOff = !WasHandedOff && (updatedFdr.IsHandoff || updatedFdr.ControllingSector == null); HighestSccFlag = SccFlagCalculator.CalculateHighestPriorityFlag(updatedFdr, CalculatedFlightData); // ensure the bool for altitude change is calculated first since it is used in the altitude flag calculation diff --git a/State/AtopPluginStateManager.cs b/State/AtopPluginStateManager.cs index 2804bcc..66e2b6a 100644 --- a/State/AtopPluginStateManager.cs +++ b/State/AtopPluginStateManager.cs @@ -1,6 +1,8 @@ using System.Collections.Concurrent; using System.Threading.Tasks; +using System.Windows.Forms; using AtopPlugin.Conflict; +using AtopPlugin.UI; using vatsys; namespace AtopPlugin.State; @@ -13,6 +15,17 @@ public static class AtopPluginStateManager private static readonly ConcurrentDictionary DisplayStates = new(); private static readonly ConcurrentDictionary Conflicts = new(); private static bool _probeEnabled = true; + private static bool _activated = false; + + public static bool Activated + { + get => _activated; + set + { + _activated = value; + AtopMenu.SetActivationState(value); + } + } public static AtopAircraftState? GetAircraftState(string callsign) { @@ -93,10 +106,31 @@ public static void SetConflictProbe(bool conflictProbeEnabled) if (!_probeEnabled) Conflicts.Clear(); } + public static void ToggleActivated() + { + var newActivationState = !Activated; + + switch (newActivationState) + { + case true when !Network.IsConnected: + MessageBox.Show(@"Please connect to the network before activating"); + return; + case true: + MessageBox.Show(@"Session activated"); + break; + case false: + MessageBox.Show(@"Session deactivated"); + break; + } + + Activated = newActivationState; + } + public static void Reset() { AircraftStates.Clear(); DisplayStates.Clear(); Conflicts.Clear(); + Activated = false; } } \ No newline at end of file diff --git a/State/JurisdictionManager.cs b/State/JurisdictionManager.cs index 45e9237..8a6bcb8 100644 --- a/State/JurisdictionManager.cs +++ b/State/JurisdictionManager.cs @@ -15,14 +15,15 @@ public static async Task HandleFdrUpdate(FDP2.FDR fdr) var atopState = fdr.GetAtopState(); // check if aircraft previously tracked to avoid re-tracking manually dropped/handed off tracks - if (isInControlledSector && !fdr.IsTracked && atopState is { PreviouslyTracked: false }) - { + if (AtopPluginStateManager.Activated && isInControlledSector && !fdr.IsTracked && + atopState is { WasHandedOff: false }) MMI.AcceptJurisdiction(fdr); - atopState.PreviouslyTracked = true; - } // if they're outside sector, currently tracked, and not going to re-enter, drop them - if (!isInControlledSector && fdr.IsTrackedByMe && !await WillEnter(fdr)) MMI.HandoffToNone(fdr); + // also drop them if we are not activated + if ((!isInControlledSector && fdr.IsTrackedByMe && !await WillEnter(fdr)) || + (fdr.IsTrackedByMe && !AtopPluginStateManager.Activated)) + MMI.HandoffToNone(fdr); } public static async Task HandleRadarTrackUpdate(RDP.RadarTrack rt) diff --git a/UI/AtopMenu.cs b/UI/AtopMenu.cs new file mode 100644 index 0000000..fb312e2 --- /dev/null +++ b/UI/AtopMenu.cs @@ -0,0 +1,50 @@ +using System.Windows.Forms; +using AtopPlugin.State; +using vatsys; +using vatsys.Plugin; + +namespace AtopPlugin.UI; + +public static class AtopMenu +{ + private const string CategoryName = "ATOP"; + + private static readonly SettingsWindow SettingsWindow = new(); + private static readonly ToolStripMenuItem ActivationToggle = new("Activate"); + + static AtopMenu() + { + InitializeSettingsMenu(); + InitializeActivationToggle(); + } + + // empty method to force static class initialization to happen + public static void Initialize() {} + + private static void InitializeSettingsMenu() + { + var settingsMenuItem = new CustomToolStripMenuItem(CustomToolStripMenuItemWindowType.Main, + CustomToolStripMenuItemCategory.Custom, new ToolStripMenuItem("Settings")) + { + CustomCategoryName = CategoryName + }; + settingsMenuItem.Item.Click += (_, _) => MMI.InvokeOnGUI(SettingsWindow.Show); + MMI.AddCustomMenuItem(settingsMenuItem); + } + + private static void InitializeActivationToggle() + { + var activationMenuItem = new CustomToolStripMenuItem(CustomToolStripMenuItemWindowType.Main, + CustomToolStripMenuItemCategory.Custom, ActivationToggle) + { + CustomCategoryName = CategoryName + }; + activationMenuItem.Item.Click += (_, _) => MMI.InvokeOnGUI(AtopPluginStateManager.ToggleActivated); + MMI.AddCustomMenuItem(activationMenuItem); + } + + public static void SetActivationState(bool state) + { + ActivationToggle.Checked = state; + } +} \ No newline at end of file From ab84d7a16e6294ddc1a9c0239cceb52eec98dff2 Mon Sep 17 00:00:00 2001 From: Maxim Salikhov Date: Sat, 23 Mar 2024 11:37:17 -0400 Subject: [PATCH 74/76] Run formatter --- Constants.cs | 2 +- State/AtopPluginStateManager.cs | 2 +- UI/AtopMenu.cs | 6 +- UI/SettingsWindow.resx | 235 ++++++++++++++++---------------- packages.config | 5 +- 5 files changed, 129 insertions(+), 121 deletions(-) diff --git a/Constants.cs b/Constants.cs index 1f3f8f4..317e531 100644 --- a/Constants.cs +++ b/Constants.cs @@ -23,7 +23,7 @@ public static class Symbols public const string NoCpdlcNoAdsb = "⎕"; public const string CpdlcNoAdsb = "⧆"; - public const string CpdlcAndAdsb = "*";//✱ + public const string CpdlcAndAdsb = "*"; //✱ public const string D30 = "3"; public const string D50 = "D"; diff --git a/State/AtopPluginStateManager.cs b/State/AtopPluginStateManager.cs index 66e2b6a..ca03517 100644 --- a/State/AtopPluginStateManager.cs +++ b/State/AtopPluginStateManager.cs @@ -122,7 +122,7 @@ public static void ToggleActivated() MessageBox.Show(@"Session deactivated"); break; } - + Activated = newActivationState; } diff --git a/UI/AtopMenu.cs b/UI/AtopMenu.cs index fb312e2..935240e 100644 --- a/UI/AtopMenu.cs +++ b/UI/AtopMenu.cs @@ -17,9 +17,11 @@ static AtopMenu() InitializeSettingsMenu(); InitializeActivationToggle(); } - + // empty method to force static class initialization to happen - public static void Initialize() {} + public static void Initialize() + { + } private static void InitializeSettingsMenu() { diff --git a/UI/SettingsWindow.resx b/UI/SettingsWindow.resx index d58980a..f8317aa 100644 --- a/UI/SettingsWindow.resx +++ b/UI/SettingsWindow.resx @@ -1,120 +1,125 @@ - - - - - - - + + + + - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - text/microsoft-resx - - - 2.0 - - - System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, + PublicKeyToken=b77a5c561934e089 + + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, + PublicKeyToken=b77a5c561934e089 + + \ No newline at end of file diff --git a/packages.config b/packages.config index 85828e6..98ccd98 100644 --- a/packages.config +++ b/packages.config @@ -1,5 +1,6 @@  - - + + \ No newline at end of file From 9b103a555915d89d8790f279b9582e1202f02eae Mon Sep 17 00:00:00 2001 From: Maxim Salikhov Date: Sun, 24 Mar 2024 22:14:10 -0400 Subject: [PATCH 75/76] Add pop-up about activation on first launch (#9) --- AtopPlugin.cs | 1 + AtopPlugin.csproj | 1 + UI/TempActivationMessagePopup.cs | 37 ++++++++++++++++++++++++++++++++ 3 files changed, 39 insertions(+) create mode 100644 UI/TempActivationMessagePopup.cs diff --git a/AtopPlugin.cs b/AtopPlugin.cs index 44b9aa8..988ac8a 100644 --- a/AtopPlugin.cs +++ b/AtopPlugin.cs @@ -16,6 +16,7 @@ public AtopPlugin() { RegisterEventHandlers(); AtopMenu.Initialize(); + TempActivationMessagePopup.PopUpActivationMessageIfFirstTime(); } private static void RegisterEventHandlers() diff --git a/AtopPlugin.csproj b/AtopPlugin.csproj index bb6ee53..59e41d0 100644 --- a/AtopPlugin.csproj +++ b/AtopPlugin.csproj @@ -90,6 +90,7 @@ SettingsWindow.cs + diff --git a/UI/TempActivationMessagePopup.cs b/UI/TempActivationMessagePopup.cs new file mode 100644 index 0000000..7055320 --- /dev/null +++ b/UI/TempActivationMessagePopup.cs @@ -0,0 +1,37 @@ +using System.IO; +using System.Reflection; +using System.Threading.Tasks; +using System.Windows.Forms; + +namespace AtopPlugin.UI; + +public static class TempActivationMessagePopup +{ + private const string AcknowledgeFileName = ".atop_activation_ack"; + + public static void PopUpActivationMessageIfFirstTime() + { + if (ActivationAckFileExists()) return; + Task.Run(() => MessageBox.Show( + """Starting with this version of the ATOP vatSys plugin, you will have to activate your session by clicking the "Activate" button under the "ATOP" menu in order to use the full controlling functionalities.""", + @"vatSys ATOP Plugin" + )); + WriteActivationAckFile(); + } + + private static bool ActivationAckFileExists() + { + return File.Exists(GetAckFilePath()); + } + + private static void WriteActivationAckFile() + { + File.WriteAllBytes(GetAckFilePath(), new byte[] { }); + } + + private static string GetAckFilePath() + { + return Path.Combine(Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location)!, + AcknowledgeFileName); + } +} \ No newline at end of file From 6782543702330577b739f813f96311bf138c52f6 Mon Sep 17 00:00:00 2001 From: Maxim Salikhov Date: Mon, 25 Mar 2024 23:50:53 -0400 Subject: [PATCH 76/76] Add note about new repository --- readme.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/readme.md b/readme.md index a202cf9..a47ac32 100644 --- a/readme.md +++ b/readme.md @@ -1,3 +1,3 @@ -## Example Custom Label Item Plugin +# This repository is deprecated -TODO: Explain \ No newline at end of file +The code for the plugin will be updated here in the future: https://github.com/vzoa/vatsys-atop-plugin