Пример #1
0
        private async Task FindIntersectingGraphicsAsync(DrawShape drawMode)
        {
            var messageSubLayers = _messageLayer.ChildLayers.Cast <MessageSubLayer>();

            IEnumerable <Graphic> results = Enumerable.Empty <Graphic>();

            int maxHits = 1;

            if (drawMode == DrawShape.Point)
            {
                var mapPoint = await MyMapView.Editor.RequestPointAsync();

                var screenPoint = MyMapView.LocationToScreen(mapPoint);
                foreach (var l in messageSubLayers)
                {
                    results = results.Concat(await l.HitTestAsync(MyMapView, screenPoint, maxHits));
                }
            }
            else
            {
                maxHits = 100;
                var geometry = await MyMapView.Editor.RequestShapeAsync(drawMode);

                var mapEnvelope = (geometry as Envelope).Extent;
                var upperLeft   = MyMapView.LocationToScreen
                                      (new MapPoint(mapEnvelope.XMin, mapEnvelope.YMax, geometry.SpatialReference));
                var lowerRight = MyMapView.LocationToScreen
                                     (new MapPoint(mapEnvelope.XMax, mapEnvelope.YMin, geometry.SpatialReference));
                var rect = new Rect(upperLeft, lowerRight);

                foreach (var l in messageSubLayers)
                {
                    results = results.Concat(await l.HitTestAsync(MyMapView, rect, maxHits));
                }
            }

            if (results.Count() == 0)
            {
                return;
            }

            foreach (var graphic in results)
            {
                MilitaryMessage message = _messageLayer.GetMessage(graphic.Attributes["_id"].ToString()) as MilitaryMessage;
                message.MessageAction = MilitaryMessageAction.Select;
                if (_messageLayer.ProcessMessage(message))
                {
                    selectedMessages.Add(message);
                }
                else
                {
                    MessageBox.Show("Failed");
                }
            }
        }
Пример #2
0
        private void SelectMessage(Message message, bool isSelected)
        {
            if (_militaryMessageLayer == null || message == null)
            {
                return;
            }

            _currentMessage = isSelected ? message : null;

            var msg = new MilitaryMessage(message.Id, MilitaryMessageType.PositionReport, isSelected ? MilitaryMessageAction.Select : MilitaryMessageAction.UnSelect);

            if (_militaryMessageLayer.ProcessMessage(msg))
            {
            }
        }
Пример #3
0
        private static bool TryProcessMessage(NvgPointElement nvgPointElement, MessageLayer messageLayer)
        {
            if (null != nvgPointElement)
            {
                if (!nvgPointElement.IsEmpty)
                {
                    var message = CreateMessage(nvgPointElement);
                    if (messageLayer.ProcessMessage(message))
                    {
                        return(true);
                    }
                }
            }

            return(false);
        }
Пример #4
0
        private bool ProcessMessage(MessageLayer messageLayer, Message msg)
        {
            if (messageLayer != null && msg != null)
            {
                var result = messageLayer.ProcessMessage(msg);

                if (!_phaseMessageDictionary.ContainsKey(messageLayer.ID))
                {
                    _phaseMessageDictionary.Add(messageLayer.ID, new List <string>());
                }

                if (!_phaseMessageDictionary[messageLayer.ID].Contains(msg.Id))
                {
                    // add
                    _phaseMessageDictionary[messageLayer.ID].Add(msg.Id);
                }

                return(result);
            }

            return(false);
        }
Пример #5
0
        // Request geometry and new message to the layer
        private async Task AddSymbolAsync(DrawShape requestedShape)
        {
            try
            {
                // Keep adding messages until next symbol is selected
                while (true)
                {
                    Esri.ArcGISRuntime.Geometry.Geometry geometry = null;
                    try
                    {
                        geometry = await MyMapView.Editor.RequestShapeAsync(requestedShape, null, null);
                    }
                    catch { }

                    if (geometry == null)
                    {
                        return;
                    }

                    // Create a new message
                    Message msg = new Message();

                    // Set the ID and other parts of the message
                    msg.Id = Guid.NewGuid().ToString();
                    msg.Add("_type", "position_report");
                    msg.Add("_action", "update");
                    msg.Add("_wkid", MyMapView.SpatialReference.Wkid.ToString());
                    msg.Add("sic", _selectedSymbol.SymbolID);
                    msg.Add("uniquedesignation", "1");

                    // Construct the Control Points based on the geometry type of the drawn geometry.
                    switch (requestedShape)
                    {
                    case DrawShape.Point:
                        MapPoint point = geometry as MapPoint;
                        msg.Add("_control_points", point.X.ToString(CultureInfo.InvariantCulture) + "," + point.Y.ToString(CultureInfo.InvariantCulture));
                        break;

                    case DrawShape.Polygon:
                        Polygon polygon = geometry as Polygon;
                        string  cpts    = string.Empty;
                        foreach (var pt in polygon.Parts[0].GetPoints())
                        {
                            cpts += ";" + pt.X.ToString(CultureInfo.InvariantCulture) + "," + pt.Y.ToString(CultureInfo.InvariantCulture);
                        }
                        msg.Add("_control_points", cpts);
                        break;

                    case DrawShape.Polyline:
                        Polyline polyline = geometry as Polyline;
                        cpts = string.Empty;
                        foreach (var pt in polyline.Parts[0].GetPoints())
                        {
                            cpts += ";" + pt.X.ToString(CultureInfo.InvariantCulture) + "," + pt.Y.ToString(CultureInfo.InvariantCulture);
                        }
                        msg.Add("_control_points", cpts);
                        break;
                    }

                    // Process the message
                    if (!_messageLayer.ProcessMessage(msg))
                    {
                        await new MessageDialog("Failed to process message.", "Symbol Dictionary Search Sample").ShowAsync();
                    }
                }
            }
            catch (Exception ex)
            {
                var _x = new MessageDialog(ex.Message, "Symbol Dictionary Search Sample").ShowAsync();
            }
        }
        private async void ProcessMessagesButton_Click(object sender, RoutedEventArgs e)
        {
            try
            {
                // This function simulates real time message processing by processing a static set of messages from an XML document.

                /*
                 * |== Example Message ==|
                 *
                 * <message>
                 *      <_type>position_report</_type>
                 *      <_action>update</_action>
                 *      <_id>16986029-8295-48d1-aa6a-478f400a53c0</_id>
                 *      <_wkid>3857</_wkid>
                 *      <sic>GFGPOLKGS-----X</sic>
                 *      <_control_points>-226906.99878,6679149.88998;-228500.51759,6677576.8009;-232194.67644,6675625.78198</_control_points>
                 *      <uniquedesignation>DIRECTION OF ATTACK</uniquedesignation>
                 * </message>
                 */

                var file = await ApplicationData.Current.LocalFolder.TryGetItemAsync(DATA_PATH);

                if (file == null)
                {
                    throw new Exception("Local message data not found. Please download sample data from 'Sample Data Settings'");
                }

                // Load the XML document
                XDocument xmlDocument = XDocument.Load(file.Path, LoadOptions.None);

                // Create a collection of messages
                IEnumerable <XElement> messagesXml = from n in xmlDocument.Root.Elements()
                                                     where n.Name == "message"
                                                     select n;

                // Iterate through the messages passing each to the ProcessMessage method on the MessageProcessor.
                foreach (XElement messageXml in messagesXml)
                {
                    Message message = new Message(from n in messageXml.Elements() select new KeyValuePair <string, string>(n.Name.ToString(), n.Value));
                    var     messageProcessingSuccesful = _messageLayer.ProcessMessage(message);

                    if (messageProcessingSuccesful == false)
                    {
                        var _x = new MessageDialog("Could not process the message.", "Message Processing Sample").ShowAsync();
                    }
                }

                /*
                 * Alternatively you can programmatically construct the message and set the attributes.
                 * e.g.
                 *
                 * // Create a new message
                 * Message msg = new Message();
                 *
                 * // Set the ID and other parts of the message
                 * msg.Id = messageID;
                 * msg.Add("_type", "position_report");
                 * msg.Add("_action", "update");
                 * msg.Add("_control_points", X.ToString(CultureInfo.InvariantCulture) + "," + Y.ToString(CultureInfo.InvariantCulture));
                 * msg.Add("_wkid", "3857");
                 * msg.Add("sic", symbolID);
                 * msg.Add("uniquedesignation", "1");
                 *
                 * // Process the message using the MessageProcessor within the MessageGroupLayer
                 * _messageLayer.ProcessMessage(msg);
                 */
            }
            catch (Exception ex)
            {
                var _x = new MessageDialog(ex.Message, "Message Processing Sample").ShowAsync();
            }
        }
		private async void ProcessMessages()
		{
			try
			{
				await MyMapView.LayersLoadedAsync();

				_messageLayer = MyMapView.Map.Layers.OfType<MessageLayer>().First();

				// This function simulates real time message processing by processing a static set of messages from an XML document.
				/* 
				* |== Example Message ==|
				* 
				* <message>
				*      <_type>position_report</_type>
				*      <_action>update</_action>
				*      <_id>16986029-8295-48d1-aa6a-478f400a53c0</_id>
				*      <_wkid>3857</_wkid>
				*      <sic>GFGPOLKGS-----X</sic>
				*      <_control_points>-226906.99878,6679149.88998;-228500.51759,6677576.8009;-232194.67644,6675625.78198</_control_points>
				*      <uniquedesignation>DIRECTION OF ATTACK</uniquedesignation>
				* </message>
				*/

				var file = await ApplicationData.Current.LocalFolder.TryGetItemAsync(DATA_PATH);
				if (file == null)
					throw new Exception("Local message data not found. Please download sample data from 'Sample Data Settings'");

				// Load the XML document
				XDocument xmlDocument = XDocument.Load(file.Path, LoadOptions.None);

				// Create a collection of messages
				IEnumerable<XElement> messagesXml = from n in xmlDocument.Root.Elements()
													where n.Name == "message"
													select n;

				// Iterate through the messages passing each to the ProcessMessage method on the MessageProcessor.
				foreach (XElement messageXml in messagesXml)
				{
					Message message = new Message(from n in messageXml.Elements() select new KeyValuePair<string, string>(n.Name.ToString(), n.Value));
					var messageProcessingSuccessful = _messageLayer.ProcessMessage(message);

					if (messageProcessingSuccessful == false)
					{
						var _x = new MessageDialog("Could not process the message.", "Message Processing Sample").ShowAsync();
					}
				}

				EnableSelection.IsEnabled = true;

				/*
				* Alternatively you can programmatically construct the message and set the attributes.
				* e.g.
				* 
				* // Create a new message
				* Message msg = new Message();           
				* 
				* // Set the ID and other parts of the message
				* msg.Id = messageID;
				* msg.Add("_type", "position_report");
				* msg.Add("_action", "update");
				* msg.Add("_control_points", X.ToString(CultureInfo.InvariantCulture) + "," + Y.ToString(CultureInfo.InvariantCulture));
				* msg.Add("_wkid", "3857");
				* msg.Add("sic", symbolID);
				* msg.Add("uniquedesignation", "1");
				* 
				* // Process the message using the MessageProcessor within the MessageGroupLayer
				* _messageLayer.ProcessMessage(msg);
				*/
			}
			catch (Exception ex)
			{
				var _x = new MessageDialog(ex.Message, "Message Processing Sample").ShowAsync();
			}
		}
Пример #8
0
        private async void ProcessMessages()
        {
            try
            {
                await MyMapView.LayersLoadedAsync();

                _messageLayer = MyMapView.Map.Layers.OfType <MessageLayer>().First();

                // This function simulates real time message processing by processing a static set of messages from an XML document.

                /*
                 * |== Example Message ==|
                 *
                 * <message>
                 *      <_type>position_report</_type>
                 *      <_action>update</_action>
                 *      <_id>16986029-8295-48d1-aa6a-478f400a53c0</_id>
                 *      <_wkid>3857</_wkid>
                 *      <sic>GFGPOLKGS-----X</sic>n
                 *      <_control_points>-226906.99878,6679149.88998;-228500.51759,6677576.8009;-232194.67644,6675625.78198</_control_points>
                 *      <uniquedesignation>DIRECTION OF ATTACK</uniquedesignation>
                 * </message>
                 */

                var file = await ApplicationData.Current.LocalFolder.GetFileAsync(DATA_PATH);

                using (var stream = await file.OpenStreamForReadAsync())
                {
                    XDocument xmlDocument = XDocument.Load(stream);

                    // Create a collection of messages
                    IEnumerable <XElement> messagesXml = from n in xmlDocument.Root.Elements()
                                                         where n.Name == "message"
                                                         select n;

                    // Iterate through the messages passing each to the ProcessMessage method on the MessageProcessor.
                    foreach (XElement messageXml in messagesXml)
                    {
                        Message message = new Message(from n in messageXml.Elements() select new KeyValuePair <string, string>(n.Name.ToString(), n.Value));
                        var     messageProcessingSuccessful = _messageLayer.ProcessMessage(message);

                        if (messageProcessingSuccessful == false)
                        {
                            var _x = new MessageDialog("Could not process the message.", "Message Processing Sample").ShowAsync();
                        }
                    }
                }

                EnableSelection.IsEnabled = true;

                /*
                 * Alternatively you can programmatically construct the message and set the attributes.
                 * e.g.
                 *
                 * // Create a new message
                 * Message msg = new Message();
                 *
                 * // Set the ID and other parts of the message
                 * msg.Id = messageID;
                 * msg.Add("_type", "position_report");
                 * msg.Add("_action", "update");
                 * msg.Add("_control_points", X.ToString(CultureInfo.InvariantCulture) + "," + Y.ToString(CultureInfo.InvariantCulture));
                 * msg.Add("_wkid", "3857");
                 * msg.Add("sic", symbolID);
                 * msg.Add("uniquedesignation", "1");
                 *
                 * // Process the message using the MessageProcessor within the MessageGroupLayer
                 * _messageLayer.ProcessMessage(msg);
                 */
            }
            catch (Exception ex)
            {
                var _x = new MessageDialog(ex.Message, "Message Processing Sample").ShowAsync();
            }
        }
Пример #9
0
        private async void ProcessMessages()
        {
            try
            {
                await MyMapView.LayersLoadedAsync();

                _messageLayer = MyMapView.Map.Layers.OfType <MessageLayer>().First();

                // This function simulates real time message processing by processing a static set of messages from an XML document.

                /*
                 * |== Example Message ==|
                 *
                 * <message>
                 *      <_type>position_report</_type>
                 *      <_action>update</_action>
                 *      <_id>16986029-8295-48d1-aa6a-478f400a53c0</_id>
                 *      <_wkid>3857</_wkid>
                 *      <sic>GFGPOLKGS-----X</sic>
                 *      <_control_points>-226906.99878,6679149.88998;-228500.51759,6677576.8009;-232194.67644,6675625.78198</_control_points>
                 *      <uniquedesignation>DIRECTION OF ATTACK</uniquedesignation>
                 * </message>
                 */

                var file = new FileInfo(DATA_PATH);

                // Load the XML document
                XDocument xmlDocument = XDocument.Load(file.FullName, LoadOptions.None);

                // Create a collection of messages
                IEnumerable <XElement> messagesXml = from n in xmlDocument.Root.Elements()
                                                     where n.Name == "message"
                                                     select n;

                // Iterate through the messages passing each to the ProcessMessage method on the MessageProcessor.
                // The MessageGroupLayer associated with this MessageProcessor will handle the creation of any
                // GraphicsLayers and Graphic objects necessary to display the message.
                foreach (XElement messageXml in messagesXml)
                {
                    Message message = new Message(from n in messageXml.Elements() select new KeyValuePair <string, string>(n.Name.ToString(), n.Value));
                    _messageLayer.ProcessMessage(message);
                }

                /*
                 * Alternatively you can programmatically construct the message and set the attributes.
                 * e.g.
                 *
                 * // Create a new message
                 * Message msg = new Message();
                 *
                 * // Set the ID and other parts of the message
                 * msg.Id = messageID;
                 * msg.Add("_type", "position_report");
                 * msg.Add("_action", "update");
                 * msg.Add("_control_points", X.ToString(CultureInfo.InvariantCulture) + "," + Y.ToString(CultureInfo.InvariantCulture));
                 * msg.Add("_wkid", "3857");
                 * msg.Add("sic", symbolID);
                 * msg.Add("uniquedesignation", "1");
                 *
                 * // Process the message using the MessageProcessor within the MessageGroupLayer
                 * _messageLayer.ProcessMessage(msg);
                 */
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message, "Message Processing Sample");
            }
        }
        // Request geometry and new message to the layer
        private async void AddSymbolAsync(SymbolViewModel symbolViewModel)
        {
            try
            {
                Dictionary <string, string> values = (Dictionary <string, string>)symbolViewModel.Model.Values;
                string    geometryControlType      = values["GeometryType"];
                DrawShape requestedShape           = DrawShape.Point;

                switch (geometryControlType)
                {
                case "Point":
                    requestedShape = DrawShape.Point;
                    break;

                case "Line":
                    requestedShape = DrawShape.Polyline;
                    break;

                case "Polygon":
                    requestedShape = DrawShape.Polygon;
                    break;

                case "Circle":
                    requestedShape = DrawShape.Circle;
                    break;

                case "Rectangular":
                    requestedShape = DrawShape.Rectangle;
                    break;

                default:
                    await new MessageDialog("Selected symbol is not supported in this sample", "Symbol Dictionary Search Sample").ShowAsync();
                    return;
                }

                Esri.ArcGISRuntime.Geometry.Geometry geometry = null;

                try
                {
                    geometry = await MyMapView.Editor.RequestShapeAsync(requestedShape, null, null);
                }
                catch { }

                if (geometry == null)
                {
                    return;
                }

                // Create a new message
                Message msg = new Message();

                // Set the ID and other parts of the message
                msg.Id = Guid.NewGuid().ToString();
                msg.Add("_type", "position_report");
                msg.Add("_action", "update");
                msg.Add("_wkid", MyMapView.SpatialReference.Wkid.ToString());
                msg.Add("sic", _selectedSymbol.SymbolID);
                msg.Add("uniquedesignation", "1");

                // Construct the Control Points based on the geometry type of the drawn geometry.
                switch (requestedShape)
                {
                case DrawShape.Point:
                    MapPoint point = geometry as MapPoint;
                    msg.Add("_control_points", point.X.ToString(CultureInfo.InvariantCulture) + "," + point.Y.ToString(CultureInfo.InvariantCulture));
                    break;

                case DrawShape.Polygon:
                    Polygon polygon = geometry as Polygon;
                    string  cpts    = string.Empty;
                    foreach (var pt in polygon.Parts[0].GetPoints())
                    {
                        cpts += ";" + pt.X.ToString(CultureInfo.InvariantCulture) + "," + pt.Y.ToString(CultureInfo.InvariantCulture);
                    }
                    msg.Add("_control_points", cpts);
                    break;

                case DrawShape.Polyline:
                    Polyline polyline = geometry as Polyline;
                    cpts = string.Empty;
                    foreach (var pt in polyline.Parts[0].GetPoints())
                    {
                        cpts += ";" + pt.X.ToString(CultureInfo.InvariantCulture) + "," + pt.Y.ToString(CultureInfo.InvariantCulture);
                    }
                    msg.Add("_control_points", cpts);
                    break;
                }

                // Process the message
                if (!_messageLayer.ProcessMessage(msg))
                {
                    await new MessageDialog("Failed to process message.", "Symbol Dictionary Search Sample").ShowAsync();
                }
            }
            catch (Exception ex)
            {
                var _ = new MessageDialog(ex.Message, "Symbol Dictionary Search Sample").ShowAsync();
            }
        }
		private async void ProcessMessages()
		{
			try
			{
				await MyMapView.LayersLoadedAsync();

				_messageLayer = MyMapView.Map.Layers.OfType<MessageLayer>().First();

				// This function simulates real time message processing by processing a static set of messages from an XML document.
				/* 
				* |== Example Message ==|
				* 
				* <message>
				*      <_type>position_report</_type>
				*      <_action>update</_action>
				*      <_id>16986029-8295-48d1-aa6a-478f400a53c0</_id>
				*      <_wkid>3857</_wkid>
				*      <sic>GFGPOLKGS-----X</sic>
				*      <_control_points>-226906.99878,6679149.88998;-228500.51759,6677576.8009;-232194.67644,6675625.78198</_control_points>
				*      <uniquedesignation>DIRECTION OF ATTACK</uniquedesignation>
				* </message>
				*/

				var file = new FileInfo(DATA_PATH);

				// Load the XML document
				XDocument xmlDocument = XDocument.Load(file.FullName, LoadOptions.None);

				// Create a collection of messages
				IEnumerable<XElement> messagesXml = from n in xmlDocument.Root.Elements()
													where n.Name == "message"
													select n;

				// Iterate through the messages passing each to the ProcessMessage method on the MessageProcessor.
				// The MessageGroupLayer associated with this MessageProcessor will handle the creation of any 
				// GraphicsLayers and Graphic objects necessary to display the message.
				foreach (XElement messageXml in messagesXml)
				{
					Message message = new Message(from n in messageXml.Elements() select new KeyValuePair<string, string>(n.Name.ToString(), n.Value));
					_messageLayer.ProcessMessage(message);
				}

				/*
				* Alternatively you can programmatically construct the message and set the attributes.
				* e.g.
				* 
				* // Create a new message
				* Message msg = new Message();           
				* 
				* // Set the ID and other parts of the message
				* msg.Id = messageID;
				* msg.Add("_type", "position_report");
				* msg.Add("_action", "update");
				* msg.Add("_control_points", X.ToString(CultureInfo.InvariantCulture) + "," + Y.ToString(CultureInfo.InvariantCulture));
				* msg.Add("_wkid", "3857");
				* msg.Add("sic", symbolID);
				* msg.Add("uniquedesignation", "1");
				* 
				* // Process the message using the MessageProcessor within the MessageGroupLayer
				* _messageLayer.ProcessMessage(msg);
				*/
			}
			catch (Exception ex)
			{
				MessageBox.Show(ex.Message, "Message Processing Sample");
			}
		}
        private bool ProcessMessage(MessageLayer messageLayer, Message msg)
        {
            if (messageLayer != null && msg != null)
            {
                var result = messageLayer.ProcessMessage(msg);

                if (!_phaseMessageDictionary.ContainsKey(messageLayer.ID))
                {
                    _phaseMessageDictionary.Add(messageLayer.ID, new List<string>());
                }

                if (!_phaseMessageDictionary[messageLayer.ID].Contains(msg.Id))
                {
                    // add
                    _phaseMessageDictionary[messageLayer.ID].Add(msg.Id);
                }

                DoCloneMission(null);

                return result;
            }

            return false;
        }
        // Request geometry and new message to the layer
        private async Task AddSymbolAsync(DrawShape requestedShape)
        {
            try
            {
                // Keep adding messages until next symbol is selected
                while (true)
                {
                    var geometry = await mapView.Editor.RequestShapeAsync(requestedShape, null, null);

                    // Create a new message
                    Message msg = new Message();

                    // Set the ID and other parts of the message
                    msg.Id = Guid.NewGuid().ToString();
                    msg.Add("_type", "position_report");
                    msg.Add("_action", "update");
                    msg.Add("_wkid", "3857");
                    msg.Add("sic", _selectedSymbol.SymbolID);
                    msg.Add("uniquedesignation", "1");

                    // Construct the Control Points based on the geometry type of the drawn geometry.
                    switch (requestedShape)
                    {
                    case DrawShape.Point:
                        MapPoint point = geometry as MapPoint;
                        msg.Add("_control_points", point.X.ToString(CultureInfo.InvariantCulture) + "," + point.Y.ToString(CultureInfo.InvariantCulture));
                        break;

                    case DrawShape.Polygon:
                        Polygon polygon = geometry as Polygon;
                        string  cpts    = string.Empty;
                        foreach (var pt in polygon.Rings[0])
                        {
                            cpts += ";" + pt.X.ToString(CultureInfo.InvariantCulture) + "," + pt.Y.ToString(CultureInfo.InvariantCulture);
                        }
                        msg.Add("_control_points", cpts);
                        break;

                    case DrawShape.Polyline:
                        Polyline polyline = geometry as Polyline;
                        cpts = string.Empty;
                        foreach (var pt in polyline.Paths[0])
                        {
                            cpts += ";" + pt.X.ToString(CultureInfo.InvariantCulture) + "," + pt.Y.ToString(CultureInfo.InvariantCulture);
                        }
                        msg.Add("_control_points", cpts);
                        break;
                    }

                    // Process the message
                    if (!_messageLayer.ProcessMessage(msg))
                    {
                        MessageBox.Show("Failed to process message.");
                    }
                }
            }
            catch (TaskCanceledException taskCanceledException)
            {
                // Requsting geometry was canceled.
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message, "Symbol Dictionary Search Sample");
            }
        }