示例#1
0
 private void Listen()
 {
     while (_listening)
     {
         try
         {
             var ctx = _server.GetContext();
             using var reader = new StreamReader(ctx.Request.InputStream, ctx.Request.ContentEncoding);
             var stringReq = reader.ReadToEnd();
             var jsonReq   = JObject.Parse(stringReq);
             if (jsonReq.ContainsKey(Request.MethodKey))
             {
                 RequestReceived?.Invoke(new Request(jsonReq));
             }
             else if (jsonReq.ContainsKey(Response.ErrorKey) || jsonReq.ContainsKey(Response.ResultKey))
             {
                 ResponseReceived?.Invoke(new Response(jsonReq));
             }
             else
             {
                 Log.F($"Received unknown message type: \n{jsonReq}", "http_server.log");
             }
             ctx.Response.StatusCode = 200;
             ctx.Response.Close();
         }
         catch (Exception e)
         {
             Log.F($"Error while parsing request: {e}", "http_server.log");
         }
     }
     _listening = false;
 }
示例#2
0
        /// <summary>
        ///     Adds the specified <paramref name="slimResponse"/> to the list of responses after applying the filters specified
        ///     in the search options.
        /// </summary>
        /// <param name="slimResponse">The response to add.</param>
        public void TryAddResponse(SearchResponseSlim slimResponse)
        {
            // ensure the search is still active, the token matches and that the response meets basic filtering criteria we check
            // the slim response for fitness prior to extracting the file list from it for performance reasons.
            if (!Disposed && State.HasFlag(SearchStates.InProgress) && slimResponse.Token == Token && SlimResponseMeetsOptionCriteria(slimResponse))
            {
                // extract the file list from the response and filter it
                var fullResponse  = SearchResponseFactory.FromSlimResponse(slimResponse);
                var filteredFiles = fullResponse.Files.Where(f => Options.FileFilter?.Invoke(f) ?? true);

                fullResponse = new SearchResponse(fullResponse.Username, fullResponse.Token, filteredFiles.Count(), fullResponse.FreeUploadSlots, fullResponse.UploadSpeed, fullResponse.QueueLength, filteredFiles);

                // ensure the filtered file count still meets the response criteria
                if ((Options.FilterResponses && fullResponse.FileCount < Options.MinimumResponseFileCount) || !(Options.ResponseFilter?.Invoke(fullResponse) ?? true))
                {
                    return;
                }

                Interlocked.Increment(ref responseCount);
                Interlocked.Add(ref fileCount, fullResponse.Files.Count);

                ResponseReceived?.Invoke(fullResponse);
                SearchTimeoutTimer.Reset();

                if (responseCount >= Options.ResponseLimit)
                {
                    Complete(SearchStates.ResponseLimitReached);
                }
                else if (fileCount >= Options.FileLimit)
                {
                    Complete(SearchStates.FileLimitReached);
                }
            }
        }
示例#3
0
    private IEnumerator PostRequest(string url, string jsonBody)
    {
        UnityWebRequest request = new UnityWebRequest(url, "POST");

        byte[] rawBody = new System.Text.UTF8Encoding().GetBytes(jsonBody);
        request.uploadHandler   = (UploadHandler) new UploadHandlerRaw(rawBody);
        request.downloadHandler = (DownloadHandler) new DownloadHandlerBuffer();
        request.SetRequestHeader("Content-Type", "application/json");

        yield return(request.SendWebRequest());

        PostMessageResponse response = JsonUtility.FromJson <PostMessageResponse>(request.downloadHandler.text);

        if (request.isHttpError || request.isNetworkError)
        {
            Debug.LogWarning("Request returned web error");
            emotionRequest = null;
            yield break;
        }

        Debug.Log("Emotion: " + response.emotion);
        ResponseReceived?.Invoke(response.emotion);

        emotionRequest = null;
    }
示例#4
0
        private bool OnResponseReceived(DownloadResponse response)
        {
            var args = new ResponseReceivedEventArgs(Request, response);

            ResponseReceived?.Invoke(this, args);
            return(args.Abort);
        }
        protected bool OnResponseReceived(DownloadResponse response)
        {
            var eventArgs = new ResponseReceivedEventArgs(Request, response);

            ResponseReceived?.Invoke(this, eventArgs);
            return(eventArgs.Abort);
        }
示例#6
0
 private void OnResponseReceived(object sender, SpeechResponseEventArgs e)
 {
     Console.WriteLine(e.PhraseResponse.RecognitionStatus);
     if (e.PhraseResponse.RecognitionStatus == RecognitionStatus.InitialSilenceTimeout ||
         e.PhraseResponse.RecognitionStatus == RecognitionStatus.DictationEndSilenceTimeout)
     {
         Task.Run(() =>
         {
             lock (speechClientLocker)
             {
                 speechClient = SpeechRecognitionServiceFactory.CreateMicrophoneClient(SpeechRecognitionMode.LongDictation, "en-US", cloudCreds.SpeechAPIKey);
                 speechClient.OnPartialResponseReceived += OnPartialResponseReceived;
                 speechClient.OnResponseReceived        += OnResponseReceived;
                 speechClient.StartMicAndRecognition();
             }
         });
     }
     else
     {
         var result = e.PhraseResponse.Results?.OrderByDescending(i => i.Confidence).Select(i => i.DisplayText).FirstOrDefault();
         if (!string.IsNullOrEmpty(result))
         {
             ResponseReceived?.Invoke(result);
         }
     }
 }
示例#7
0
 protected virtual void OnResponseReceived(string message)
 {
     ResponseReceived?.Invoke(this, new VoiceCommandControllerEventArgs()
     {
         Data = message
     });
 }
示例#8
0
        /// <summary>
        ///     Adds the specified <paramref name="slimResponse"/> to the list of responses after applying the filters specified in
        ///     the search options.
        /// </summary>
        /// <param name="slimResponse">The response to add.</param>
        public void AddResponse(SearchResponseSlim slimResponse)
        {
            if (State.HasFlag(SearchStates.InProgress) && slimResponse.Token == Token && ResponseMeetsOptionCriteria(slimResponse))
            {
                var fullResponse = new SearchResponse(slimResponse);
                fullResponse = new SearchResponse(fullResponse, fullResponse.Files.Where(f => FileMeetsOptionCriteria(f)).ToList());

                if (Options.FilterResponses && fullResponse.FileCount < Options.MinimumResponseFileCount)
                {
                    return;
                }

                Interlocked.Add(ref resultCount, fullResponse.Files.Count);

                ResponseList.Add(fullResponse);

                ResponseReceived?.Invoke(this, fullResponse);
                SearchTimeoutTimer.Reset();

                if (resultCount >= Options.FileLimit)
                {
                    Complete(SearchStates.FileLimitReached);
                }
            }
        }
示例#9
0
        private async Task QueueListener_ResponseReceived(object sender, ResponseReceivedEventArgs e)
        {
            var iMessages = Counters.IncrementMessages();

            try
            {
                Counters.IncrementReceivingTime(e.Message.Header.Response.TotalTime);
                Core.Log.InfoDetail("Response message received with CorrelationId = {0} . Current messages processing = {1}", e.Message.CorrelationId, iMessages);
                if (ResponseReceived != null)
                {
                    await ResponseReceived.InvokeAsync(sender, e).ConfigureAwait(false);
                }
                if (MQueueServerEvents.ResponseReceived != null)
                {
                    await MQueueServerEvents.ResponseReceived.InvokeAsync(sender, e).ConfigureAwait(false);
                }
                Counters.DecrementMessages();
                Counters.IncrementTotalMessagesProccesed();
            }
            catch (Exception)
            {
                Counters.IncrementTotalExceptions();
                Counters.DecrementMessages();
                throw;
            }
        }
        public override async Task ReceiveAsync(WebSocketReceiveResult result, byte[] buffer)
        {
            var response = JsonConvert.DeserializeObject <ElectronResponse>(
                System.Text.Encoding.UTF8.GetString(buffer, 0, result.Count)
                );

            await ResponseReceived?.Invoke(response);
        }
示例#11
0
文件: Bot.cs 项目: icedream/icebot
        protected void OnResponseReceived(IrcResponse resp)
        {
            IrcResponseEventArgs e = new IrcResponseEventArgs(resp);

            if (ResponseReceived != null)
            {
                ResponseReceived.Invoke(this, e);
            }
        }
        private void HandleResponse(AmfCommandMessage command, RtmpMessage message)
        {
            var result = new CommandArgs
            {
                Command = command
            };

            ResponseReceived?.Invoke(this, result);
        }
示例#13
0
        public override Task ReceiveAsync(WebSocketReceiveResult result, byte[] buffer)
        {
            var response = JsonConvert.DeserializeObject <ElectronResponse>(
                System.Text.Encoding.UTF8.GetString(buffer, 0, result.Count)
                );

            ResponseReceived?.Invoke(this, response);
            return(Task.CompletedTask);
        }
示例#14
0
文件: App.xaml.cs 项目: xmaux72/Exrin
        private void ProcessResponse(string item)
        {
            try
            {
                var response = JsonConvert.DeserializeObject <VisualStateResponse>(item);

                ResponseReceived?.Invoke(response);
            }
            catch { }
        }
        public async Task GetResponse()
        {
            var responseRestService = Container.Instance.Resolve <ResponseRestService>();
            var responsesViewModel  = Container.Instance.Resolve <ResponsesViewModel>();
            var response            = await responseRestService.GetResponse(ResponseId);

            Response = response;
            ResponseReceived?.Invoke();
            responsesViewModel.HandleResponseModelReceived(response);
        }
示例#16
0
        private void _HandleResponse(ResponseMessage message)
        {
            Debug("Handle Response", message);

            if (_responses.ContainsKey(message.Id))
            {
                _responses[message.Id] = message;
            }

            ResponseReceived?.Invoke(this, message);
        }
示例#17
0
        /// <summary>
        /// Execute TCP Application Client Command.
        /// </summary>
        /// <param name="command"></param>
        /// <param name="timeout"></param>
        /// <returns></returns>
        private TcpAppCommandResult ExecuteTcpAppCommand(string command, int timeout = 1000)
        {
            TcpAppCommandResult result = new TcpAppCommandResult();

            try
            {
                SuspendDataReceivedEvent = true;
                string commandKeyword = command.Split(' ').First();

                //Verify command registered in function list, only active after Connect() sequence completed.
                if (Initialized)
                {
                    if (!Commands.Contains(commandKeyword, StringComparer.InvariantCultureIgnoreCase))
                    {
                        throw new TcpAppClientException("Invalid Command: " + commandKeyword);
                    }
                }

                string tcpCommand = command + TcpAppCommon.Delimiter;
                CommandSend?.Invoke(this, new TcpAppEventArgs(command));
                Write(tcpCommand);

                DateTime startTime = DateTime.Now;
                while ((DateTime.Now - startTime).TotalMilliseconds < timeout)
                //while(true)
                {
                    string response = ReadString();
                    ResponseReceived?.Invoke(this, new TcpAppEventArgs(response));
                    string[] resultParams = response.Split(' ');
                    if ((string.Compare(resultParams[0], commandKeyword, true) == 0))
                    {
                        result.Status = (TcpAppCommandStatus)Enum.Parse(typeof(TcpAppCommandStatus), resultParams[1]);
                        if (resultParams.Length > 2)
                        {
                            result.ReturnMessage = string.Join(" ", resultParams.Skip(2)).Trim();                          //Remove trailing CRLF
                        }
                        return(result);
                    }
                    Thread.Sleep(100); //Wait 100ms, retry.
                }//while
            }
            catch (TcpAppClientException) { throw; }
            catch (Exception ex)
            {
                throw new TcpAppClientException("Exception raised!", ex);
            }
            finally
            {
                SuspendDataReceivedEvent = false;
            }
            throw new TcpAppClientException("TIMEOUT: No response received from server!");
        }
示例#18
0
        private async Task HandleReceivedResponse(Response response)
        {
            ResponseReceived?.Invoke(this, response);
            foreach (var handler in ResponsePipeline.GetHandlers())
            {
                var result = await handler.Invoke(response);

                if (result)
                {
                    break;
                }
            }
        }
示例#19
0
        private void ServiceOnDataReceived(CommunicationMessage message)
        {
            switch (message.Type)
            {
            case MessageType.Response:
                ResponseReceived?.Invoke(message);
                break;

            default:
                MessageReceived?.Invoke(message);
                break;
            }
        }
示例#20
0
        public async Task <string> GetPage()
        {
            var responce = await _client.GetAsync(_url);

            string source = null;

            Console.WriteLine("responce");
            source = await responce?.Content.ReadAsStringAsync();

            ResponseCode = (int)responce?.StatusCode;
            Console.WriteLine("received");
            ResponseReceived?.Invoke(this, new Response(ResponseCode, responce?.ReasonPhrase, responce?.Content.ToString(), responce?.Headers.ToString(), responce.IsSuccessStatusCode, responce?.Version.ToString()));
            Console.WriteLine("received");
            return(source);
        }
示例#21
0
        /// <summary>
        ///     Adds the specified <paramref name="response"/> to the list of responses after applying the filters specified in
        ///     the search options.
        /// </summary>
        /// <param name="response">The response to add.</param>
        public void TryAddResponse(SearchResponse response)
        {
            if (!Disposed && State.HasFlag(SearchStates.InProgress) && response.Token == Token)
            {
                if (!ResponseMeetsOptionCriteria(response))
                {
                    return;
                }

                if (Options.FilterResponses)
                {
                    // apply custom filter, if one was provided
                    if (!(Options.ResponseFilter?.Invoke(response) ?? true))
                    {
                        return;
                    }

                    // apply individual file filter, if one was provided
                    var filteredFiles       = response.Files.Where(f => Options.FileFilter?.Invoke(f) ?? true);
                    var filteredLockedFiles = response.LockedFiles.Where(f => Options.FileFilter?.Invoke(f) ?? true);

                    response = new SearchResponse(response, filteredFiles, filteredLockedFiles);

                    // ensure the filtered file count still meets the response criteria
                    if (response.FileCount + response.LockedFileCount < Options.MinimumResponseFileCount)
                    {
                        return;
                    }
                }

                Interlocked.Increment(ref responseCount);
                Interlocked.Add(ref fileCount, response.FileCount);
                Interlocked.Add(ref lockedFileCount, response.LockedFileCount);

                ResponseReceived?.Invoke(response);
                SearchTimeoutTimer.Reset();

                if (responseCount >= Options.ResponseLimit)
                {
                    Complete(SearchStates.ResponseLimitReached);
                }
                else if (fileCount >= Options.FileLimit)
                {
                    Complete(SearchStates.FileLimitReached);
                }
            }
        }
        /// <summary>
        /// Creates and sends request to reverse geocode service.
        /// </summary>
        /// <param name="pointGeocoordinates">Coordinates of the point.</param>
        public async void CreateReverseGeocodeRequest(PointGeocoordinates pointGeocoordinates)
        {
            try
            {
                var request  = _mapService.CreateReverseGeocodeRequest(pointGeocoordinates.Latitude, pointGeocoordinates.Longitude);
                var response = await request.GetResponseAsync();

                foreach (var result in response)
                {
                    ResponseReceived?.Invoke(this, new ReverseGeocodingResponseArgs(true, result.ToString()));
                }
            }
            catch (Exception)
            {
                ResponseReceived?.Invoke(this, new ReverseGeocodingResponseArgs(false));
            }
        }
示例#23
0
        private Task <SocketError> ServerResponseReceived(SIPEndPoint localSIPEndPoint, SIPEndPoint remoteEndPoint, SIPTransaction sipTransaction, SIPResponse sipResponse)
        {
            try
            {
                string reasonPhrase = (sipResponse.ReasonPhrase.IsNullOrBlank()) ? sipResponse.Status.ToString() : sipResponse.ReasonPhrase;
                logger.LogDebug("Server response " + sipResponse.StatusCode + " " + reasonPhrase + " received for " + sipTransaction.TransactionRequest.Method + " to " + m_callDescriptor.Uri + ".");

                if (sipResponse.Status == SIPResponseStatusCodesEnum.ProxyAuthenticationRequired || sipResponse.Status == SIPResponseStatusCodesEnum.Unauthorised)
                {
                    if (sipResponse.Header.HasAuthenticationHeader)
                    {
                        if ((m_callDescriptor.Username != null || m_callDescriptor.AuthUsername != null) && m_callDescriptor.Password != null)
                        {
                            string     username             = (m_callDescriptor.AuthUsername != null) ? m_callDescriptor.AuthUsername : m_callDescriptor.Username;
                            SIPRequest authenticatedRequest = sipTransaction.TransactionRequest.DuplicateAndAuthenticate(
                                sipResponse.Header.AuthenticationHeaders, username, m_callDescriptor.Password);

                            SIPNonInviteTransaction authTransaction = new SIPNonInviteTransaction(m_sipTransport, authenticatedRequest, m_outboundProxy);
                            authTransaction.NonInviteTransactionFinalResponseReceived += AuthResponseReceived;
                            authTransaction.NonInviteTransactionFailed += TransactionFailed;
                            authTransaction.SendRequest();
                        }
                        else
                        {
                            logger.LogDebug("Send request received an authentication required response but no credentials were available.");
                            ResponseReceived?.Invoke(sipResponse);
                        }
                    }
                    else
                    {
                        logger.LogDebug("Send request failed with " + sipResponse.StatusCode + " but no authentication header was supplied for " + sipTransaction.TransactionRequest.Method + " to " + m_callDescriptor.Uri + ".");
                        ResponseReceived?.Invoke(sipResponse);
                    }
                }
                else
                {
                    ResponseReceived?.Invoke(sipResponse);
                }
            }
            catch (Exception excp)
            {
                logger.LogError("Exception SIPNonInviteClientUserAgent ServerResponseReceived (" + remoteEndPoint + "). " + excp.Message);
            }

            return(Task.FromResult(SocketError.Success));
        }
        private void WaitForResponse()
        {
            while (!_cancellationTokenSource.IsCancellationRequested)
            {
                IPEndPoint endPoint = null;
                byte[]     buffer   = _listenerSocket.Receive(ref endPoint);
                if (buffer.Length == 0)
                {
                    continue;
                }

                JObject response;
                if (TryParseResponse(buffer, out response))
                {
                    ResponseReceived?.Invoke(this, new DiscoveryResponseReceivedEventArgs(endPoint, response));
                }
            }
        }
示例#25
0
        private void _watchr_FileChanged(object sender, EventArgs e)
        {
            if (_watchr == null)
            {
                return;
            }

            if (!TryGetEnvelope(out ApprovalEnvelope <T> envelope,
                                _watchr.TargetFile))
            {
                return;
            }

            if (envelope.IsApproved.HasValue)
            {
                ResponseReceived?.Invoke(this, envelope);
            }
        }
        private void HandleResponsePacket(CommandPacket packet)
        {
            Log.Debug("RECV: {PacketType}:{CommandType} -- {ResponsePacketData}", packet.PacketType,
                      packet.CommandType, BitConverter.ToString(packet.ConvertToBuffer()));
            switch (packet.PacketType)
            {
            case PacketType.NormalCommand:
                Log.Debug("RESP: Command in place of response");
                ResponseReceived?.Invoke(this,
                                         new CommandPacketResponseReceivedEventArgs(
                                             new DeviceResponseException("Invalid response from LCD device -- normal bits set")));
                break;

            case PacketType.NormalResponse:
                Log.Debug("RESP: Recognized command response");
                ResponseReceived?.Invoke(this, new CommandPacketResponseReceivedEventArgs(packet));
                break;

            case PacketType.NormalReport:
                if (packet.CommandType == CommandType.KeyActivity)
                {
                    var action = (KeypadAction)packet.Data[0];
                    Log.Debug("RESP: Keypad event: {KeypadEvent}", action);
                    KeypadActivity?.BeginInvoke(this,
                                                new KeypadActivityEventArgs(action.ConvertToKeyFlags(), action), null, null);
                }
                // TODO: handle temperature report with event
                break;

            case PacketType.ErrorResponse:
                Log.Debug("RESP: Error for {ErrorCommandType}", packet.CommandType);
                ResponseReceived?.Invoke(this,
                                         new CommandPacketResponseReceivedEventArgs(
                                             new DeviceResponseException($"Error returned from LCD device for command '{packet.CommandType}'")));
                break;

            default:
                Log.Debug("RESP: Unknown response");
                ResponseReceived?.Invoke(this,
                                         new CommandPacketResponseReceivedEventArgs(
                                             new DeviceResponseException("Unknown response packet type from LCD device")));
                break;
            }
        }
        private void ServerResponseReceived(SIPEndPoint localSIPEndPoint, SIPEndPoint remoteEndPoint, SIPTransaction sipTransaction, SIPResponse sipResponse)
        {
            try
            {
                string reasonPhrase = (sipResponse.ReasonPhrase.IsNullOrBlank()) ? sipResponse.Status.ToString() : sipResponse.ReasonPhrase;
                Log_External(new SIPMonitorConsoleEvent(SIPMonitorServerTypesEnum.UserAgentClient, SIPMonitorEventTypesEnum.DialPlan, "Server response " + sipResponse.StatusCode + " " + reasonPhrase + " received for " + sipTransaction.TransactionRequest.Method + " to " + m_callDescriptor.Uri + ".", m_owner));

                if (sipResponse.Status == SIPResponseStatusCodesEnum.ProxyAuthenticationRequired || sipResponse.Status == SIPResponseStatusCodesEnum.Unauthorised)
                {
                    if (sipResponse.Header.AuthenticationHeader != null)
                    {
                        if ((m_callDescriptor.Username != null || m_callDescriptor.AuthUsername != null) && m_callDescriptor.Password != null)
                        {
                            SIPRequest authenticatedRequest         = GetAuthenticatedRequest(sipTransaction.TransactionRequest, sipResponse);
                            SIPNonInviteTransaction authTransaction = m_sipTransport.CreateNonInviteTransaction(authenticatedRequest, m_outboundProxy);
                            authTransaction.NonInviteTransactionFinalResponseReceived += AuthResponseReceived;
                            authTransaction.NonInviteTransactionTimedOut += RequestTimedOut;
                            m_sipTransport.SendSIPReliable(authTransaction);
                        }
                        else
                        {
                            Log_External(new SIPMonitorConsoleEvent(SIPMonitorServerTypesEnum.UserAgentClient, SIPMonitorEventTypesEnum.DialPlan, "Send request received an authentication required response but no credentials were available.", m_owner));

                            ResponseReceived?.Invoke(sipResponse);
                        }
                    }
                    else
                    {
                        Log_External(new SIPMonitorConsoleEvent(SIPMonitorServerTypesEnum.UserAgentClient, SIPMonitorEventTypesEnum.DialPlan, "Send request failed with " + sipResponse.StatusCode + " but no authentication header was supplied for " + sipTransaction.TransactionRequest.Method + " to " + m_callDescriptor.Uri + ".", m_owner));

                        ResponseReceived?.Invoke(sipResponse);
                    }
                }
                else
                {
                    ResponseReceived?.Invoke(sipResponse);
                }
            }
            catch (Exception excp)
            {
                logger.LogError("Exception SIPNonInviteClientUserAgent ServerResponseReceived (" + remoteEndPoint + "). " + excp.Message);
            }
        }
        public override async Task <bool> PromptPurchase()
        {
            Task <InAppPurchaseHelper.PurchaseResponse> responseTask;

            if (IsNewPurchaseOperation)
            {
                responseTask = InAppPurchaseHelper.PurchaseAsync();
            }
            else
            {
                responseTask = InAppPurchaseHelper.RestoreAsync();
            }

            var response = await responseTask;

            ResponseReceived?.Invoke(null, response);

            return(response.Success);
        }
        async private Task PostJson(string json)
        {
            SendingData = true;

            try
            {
                var response = await Client.PostAsync(Url, new StringContent(json, Encoding.UTF8, "application/json"));

                var content = await response.Content.ReadAsStringAsync();

                ResponseReceived?.Invoke(this, content);
            }
            catch (HttpRequestException e)
            {
                ResponseReceived?.Invoke(this, "Request failed");
            }
            finally
            {
                SendingData = false;
            }
        }
示例#30
0
        private async Task <IResponse> DoRequest(IRequest request)
        {
            await ApplyAuthenticator(request).ConfigureAwait(false);

            _httpLogger?.OnRequest(request);
            IResponse response = await _httpClient.DoRequest(request).ConfigureAwait(false);

            _httpLogger?.OnResponse(response);
            ResponseReceived?.Invoke(this, response);
            if (_retryHandler != null)
            {
                response = await _retryHandler.HandleRetry(request, response, async (newRequest) =>
                {
                    await ApplyAuthenticator(request).ConfigureAwait(false);
                    var newResponse = await _httpClient.DoRequest(request).ConfigureAwait(false);
                    _httpLogger?.OnResponse(newResponse);
                    ResponseReceived?.Invoke(this, response);
                    return(newResponse);
                }).ConfigureAwait(false);
            }
            ProcessErrors(response);
            return(response);
        }