コード例 #1
0
ファイル: Transcription.cs プロジェクト: sumitc91/M2E-2.0
        public ResponseModel<string> SubmitTranscriptionInputTableDataByRefKey(string username, string refKey, string surveyResult)
        {
            var response = new ResponseModel<string>();
            var UserMultipleJobMapping = _db.UserMultipleJobMappings.SingleOrDefault(x => x.refKey == refKey && x.username == username);
            var clientJobInfo = _db.CreateTemplateQuestionInfoes.SingleOrDefault(x => x.referenceId == refKey);
            if (UserMultipleJobMapping == null)
            {
                response.Status = 403;
                response.Message = "You can't submit answer for this transcription.";
                return response;
            }
            else if (UserMultipleJobMapping.status == Constants.status_done)
            {
                response.Status = 403;
                response.Message = "You have already submitted your answer.";
                return response;
            }
            else
            {
                UserMultipleJobMapping.status = Constants.status_done;
                UserMultipleJobMapping.surveyResult = surveyResult;
                try
                {
                    _db.SaveChanges();

                    //var payment = new UserReputationService().UpdateUserBalance(Constants.userType_user, username, Convert.ToDouble(_db.CreateTemplateQuestionInfoes.SingleOrDefault(x => x.referenceId == refKey).payPerUser), 0, Constants.payment_credit, clientJobInfo.title, clientJobInfo.type, clientJobInfo.subType);
                    //if (!payment)
                        //logger.Info("payment failed for user : "******" of amount : " + _db.CreateTemplateQuestionInfoes.SingleOrDefault(x => x.referenceId == refKey).payPerUser);

                    long JobId = clientJobInfo.Id;
                    long JobCompleted = _db.UserMultipleJobMappings.Where(x => x.refKey == refKey && x.status == Constants.status_done).Count();
                    long JobAssigned = _db.UserMultipleJobMappings.Where(x => x.refKey == refKey && x.status == Constants.status_assigned).Count();
                    long JobReviewed = (JobCompleted > 1) ? (JobCompleted) / 2 : 0;  // currently hard coded.

                    //var SignalRClientHub = new SignalRClientHub();
                    //var hubContext = GlobalHost.ConnectionManager.GetHubContext<SignalRClientHub>();
                    //dynamic client = SignalRManager.getSignalRDetail(clientJobInfo.username);
                    //if (client != null)
                    //{
                    //    client.updateClientProgressChart(Convert.ToString(JobId), clientJobInfo.totalThreads, Convert.ToString(JobCompleted), Convert.ToString(JobAssigned), Convert.ToString(JobReviewed));
                    //    //client.updateClientProgressChart("8", "20", "10", "8", "5");
                    //    //client.addMessage("add message signalR");
                    //}
                    bool status = new UserUpdatesClientRealTimeData().UpdateClientRealTimeData(JobId, JobCompleted, JobAssigned, JobReviewed, clientJobInfo.totalThreads, clientJobInfo.username);

                    response.Status = 200;
                    response.Message = "success-";
                    response.Payload = refKey;
                    return response;
                }
                catch (DbEntityValidationException e)
                {
                    DbContextException.LogDbContextException(e);
                    response.Status = 500;
                    response.Message = "Failed";
                    response.Payload = "Exception Occured";
                    return response;
                }
            }         
            
        }
コード例 #2
0
        public ResponseModel<String> ValidateFacebookLike(string username, string refKey)
        {
            var response = new ResponseModel<String>();            
            var checkIfUserConnectedWithFacebook = _db.FacebookAuths.SingleOrDefault(x => x.username == username);
            if (checkIfUserConnectedWithFacebook == null)
            {
                response.Status = 205;
                response.Message = "User is not connected with facebook";
                return response;
            }
            else
            {
                //checkIfUserConnectedWithFacebook.AuthToken;
            }
            var facebookLikeTemplateData = _db.CreateTemplateFacebookLikes.SingleOrDefault(x => x.referenceId == refKey);
            
            var fb = new FacebookClient(checkIfUserConnectedWithFacebook.AuthToken);
            bool alreadyLikedByUser = false;
            try
            {
                dynamic result = fb.Get("fql",
                            new { q = "SELECT page_id FROM page_fan WHERE uid=" + checkIfUserConnectedWithFacebook.facebookId + " AND page_id=" + facebookLikeTemplateData.pageId });
                foreach (var item in result.data)
                {
                    alreadyLikedByUser = true; // exists   
                }
            }
            catch (Exception ex)
            {
                response.Status = 206;
                response.Message = "Facebook Auth Token Expired";
                return response; ;
            }
            if (alreadyLikedByUser)
            {
                var facebookLikeListMap = _db.facebookPageLikeMappings.SingleOrDefault(x => x.username == username && x.refKey == refKey);
                if (facebookLikeListMap != null)
                {
                    response.Status = 208;
                    response.Message = "You have already earned for this page like.";
                }
                else
                {
                    var facebookPageLikeMapData = new facebookPageLikeMapping
                    {
                        PageId = facebookLikeTemplateData.pageId,
                        refKey = facebookLikeTemplateData.referenceId,
                        UserFacebookId = checkIfUserConnectedWithFacebook.facebookId,
                        username = checkIfUserConnectedWithFacebook.username,
                        DateTime = DateTime.Now
                    };

                    _db.facebookPageLikeMappings.Add(facebookPageLikeMapData);

                    try
                    {
                        _db.SaveChanges();

                        //var payment = new UserReputationService().UpdateUserBalance(Constants.userType_user, username, Convert.ToDouble(_db.CreateTemplateFacebookLikes.SingleOrDefault(x => x.referenceId == refKey).payPerUser), 0, Constants.payment_credit, facebookLikeTemplateData.title, facebookLikeTemplateData.type, facebookLikeTemplateData.subType);
                        //if (!payment)
                            //logger.Info("payment failed for user : "******" of amount : " + _db.CreateTemplateQuestionInfoes.SingleOrDefault(x => x.referenceId == refKey).payPerUser);

                        long JobId = facebookLikeTemplateData.Id;
                        long JobCompleted = _db.facebookPageLikeMappings.Where(x => x.refKey == refKey).Count();
                        if (JobCompleted > Convert.ToInt32(facebookLikeTemplateData.totalThreads))
                            JobCompleted = Convert.ToInt32(facebookLikeTemplateData.totalThreads);

                        long JobAssigned = 0;
                        long JobReviewed = JobCompleted;

                        //var SignalRClientHub = new SignalRClientHub();
                        //var hubContext = GlobalHost.ConnectionManager.GetHubContext<SignalRClientHub>();
                        //dynamic client = SignalRManager.getSignalRDetail(clientJobInfo.username);
                        //if (client != null)
                        //{
                        //    client.updateClientProgressChart(Convert.ToString(JobId), clientJobInfo.totalThreads, Convert.ToString(JobCompleted), Convert.ToString(JobAssigned), Convert.ToString(JobReviewed));
                        //    //client.updateClientProgressChart("8", "20", "10", "8", "5");
                        //    //client.addMessage("add message signalR");
                        //}
                        bool status = new UserUpdatesClientRealTimeData().UpdateClientRealTimeData(JobId, JobCompleted, JobAssigned, JobReviewed, facebookLikeTemplateData.totalThreads, facebookLikeTemplateData.username);

                    }
                    catch (DbEntityValidationException e)
                    {
                        DbContextException.LogDbContextException(e);                        
                    }
                    response.Status = 200;
                    response.Message = "User liked the page";
                }                
                
            }
            else
            {
                response.Status = 207;
                response.Message = "User didn't like the page yet";
            }
            return response;
        }
コード例 #3
0
        private ResponseModel<string> AllocateSingleAssignTypeThreadToUserByRefKey(CreateTemplateQuestionInfo clientJobInfo, string refKey, string username)
        {
            var response = new ResponseModel<string>();
            var ifAlreadyAllocated = _db.UserJobMappings.SingleOrDefault(x => x.refKey == refKey && x.username == username);
            if (ifAlreadyAllocated != null)
            {
                response.Status = 403;
                response.Message = "already applied";
                return response;
            }
            else if (_db.UserJobMappings.Where(x => x.refKey == refKey).Count() >= Convert.ToInt32((clientJobInfo.totalThreads)))
            {
                response.Status = 405;
                response.Message = "all threads are already allocated !!!";
                return response;
            }
            int expectedDeliveryTimeInMinutes = 15;
            var UserJobMapping = new UserJobMapping();
            UserJobMapping.refKey = refKey;
            UserJobMapping.username = username;
            UserJobMapping.startTime = DateTime.Now.ToString();
            UserJobMapping.expectedDeliveryTime = DateTime.Now.AddMinutes(expectedDeliveryTimeInMinutes).ToString();
            UserJobMapping.endTime = "NA";
            UserJobMapping.status = Constants.status_assigned;

            _db.UserJobMappings.Add(UserJobMapping);
            try
            {
                _db.SaveChanges();

                long JobId = clientJobInfo.Id;
                long JobCompleted = _db.UserJobMappings.Where(x => x.refKey == refKey && x.status == Constants.status_done).Count();
                long JobAssigned = _db.UserJobMappings.Where(x => x.refKey == refKey && x.status == Constants.status_assigned).Count();
                long JobReviewed = (JobCompleted > 1) ? (JobCompleted) / 2 : 0;  // currently hard coded.

                //var SignalRClientHub = new SignalRClientHub();
                //var hubContext = GlobalHost.ConnectionManager.GetHubContext<SignalRClientHub>();
                //dynamic client = SignalRManager.getSignalRDetail(clientJobInfo.username);
                //if (client != null)
                //{
                //    client.updateClientProgressChart(Convert.ToString(JobId), clientJobInfo.totalThreads, Convert.ToString(JobCompleted), Convert.ToString(JobAssigned), Convert.ToString(JobReviewed));
                //    //client.updateClientProgressChart("8", "20", "10", "8", "5");
                //    //client.addMessage("add message signalR");
                //}
                bool status = new UserUpdatesClientRealTimeData().UpdateClientRealTimeData(JobId, JobCompleted, JobAssigned, JobReviewed, clientJobInfo.totalThreads, clientJobInfo.username);

                response.Status = 200;
                response.Message = "success-";
                response.Payload = refKey;
            }
            catch (DbEntityValidationException e)
            {
                DbContextException.LogDbContextException(e);
                response.Status = 500;
                response.Message = "Failed";
                response.Payload = "Exception Occured";
            }

            return response;
        }
コード例 #4
0
        private ResponseModel<string> AllocateMultipleTasksMultipleAssignTypeThreadToUserByRefKey(CreateTemplateQuestionInfo clientJobInfo, string refKey, string username)
        {
            var response = new ResponseModel<string>();
            var ifAlreadyAllocated = _db.UserMultipleJobMappings.SingleOrDefault(x => x.refKey == refKey && x.username == username);
            if (ifAlreadyAllocated != null)
            {
                response.Status = 403;
                response.Message = "You have already applied for this job";
                return response;
            }
            else if (_db.UserMultipleJobMappings.Where(x => x.refKey == refKey && x.isFirst == Constants.status_true).Count() >= Convert.ToInt32((clientJobInfo.totalThreads)))
            {
                response.Status = 405;
                response.Message = "all threads are already allocated !!!";
                return response;
            }
            const int expectedDeliveryTimeInMinutes = 15;

            

            var availableJobLists = _db.CreateTemplateImgurImagesLists.Where(x => x.referenceKey == refKey && x.status == Constants.status_open).ToList();
            if (availableJobLists != null)
            {
                if (availableJobLists.Count == 0)
                {
                    response.Status = 406;
                    response.Message = "All Threads of this job is already assigned.";
                    return response;
                }

                lock (this)
                {
                    int endCount = Constants.picPerUserImageModeration;
                    if (availableJobLists.Count <= endCount)
                    {
                        endCount = availableJobLists.Count;
                    }

                    for (int i = 0; i < endCount; i++)
                    {
                        var transcriptionTask = availableJobLists[i];
                        var UserMultipleJobMapping = new UserMultipleJobMapping();
                        UserMultipleJobMapping.endTime = Constants.NA;
                        UserMultipleJobMapping.expectedDelivery = DateTime.Now.AddMinutes(expectedDeliveryTimeInMinutes).ToString();
                        UserMultipleJobMapping.refKey = refKey;
                        UserMultipleJobMapping.startTime = DateTime.Now.ToString();
                        UserMultipleJobMapping.status = Constants.status_assigned;

                        if (clientJobInfo.type == Constants.type_moderation && clientJobInfo.subType == Constants.subType_moderatingPhotos)
                        {
                            UserMultipleJobMapping.subType = Constants.subType_moderatingPhotos;
                            UserMultipleJobMapping.type = Constants.type_moderation;
                        }
                        else if (clientJobInfo.type == Constants.type_dataEntry && clientJobInfo.subType == Constants.subType_Transcription)
                        {
                            UserMultipleJobMapping.subType = Constants.subType_Transcription;
                            UserMultipleJobMapping.type = Constants.type_dataEntry;
                        }
                        UserMultipleJobMapping.surveyResult = Constants.NA;
                        UserMultipleJobMapping.username = username;

                        UserMultipleJobMapping.imageKey = transcriptionTask.imgurLink;                        

                        var updateImgurImageMapAfterAssigning = _db.CreateTemplateImgurImagesLists.SingleOrDefault(x => x.Id == transcriptionTask.Id);
                        if (i == 0)
                            UserMultipleJobMapping.isFirst = Constants.status_true;

                        if (updateImgurImageMapAfterAssigning.alocatedCount == null)
                        {
                            updateImgurImageMapAfterAssigning.alocatedCount = 1;                            
                        }
                        else
                            updateImgurImageMapAfterAssigning.alocatedCount += 1;
                        if (updateImgurImageMapAfterAssigning.alocatedCount > (Constants.picPerUserImageModeration-1))
                        {                           
                            updateImgurImageMapAfterAssigning.status = Constants.status_assigned;
                        }
                        _db.UserMultipleJobMappings.Add(UserMultipleJobMapping);
                    }

                    try
                    {

                        _db.SaveChanges();
                        long JobId = clientJobInfo.Id;
                        long JobCompleted = _db.UserMultipleJobMappings.Where(x => x.refKey == refKey && x.status == Constants.status_done).Count();
                        long JobAssigned = _db.UserMultipleJobMappings.Where(x => x.refKey == refKey && x.status == Constants.status_assigned).Count();
                        long JobReviewed = (JobCompleted > 1) ? (JobCompleted) / 2 : 0;  // currently hard coded.

                        bool status = new UserUpdatesClientRealTimeData().UpdateClientRealTimeData(JobId, JobCompleted, JobAssigned, JobReviewed, clientJobInfo.totalThreads, clientJobInfo.username);
                        response.Status = 200;
                        response.Message = "success-";
                        response.Payload = refKey;
                    }
                    catch (DbEntityValidationException e)
                    {

                        DbContextException.LogDbContextException(e);
                        response.Status = 500;
                        response.Message = "Failed";
                        response.Payload = "Exception Occured";
                    }
                }

            }

            return response;
        }
コード例 #5
0
        private ResponseModel<string> AllocateMultipleAssignTypeThreadToUserByRefKey(CreateTemplateQuestionInfo clientJobInfo, string refKey, string username)
        {
            var response = new ResponseModel<string>();
            var ifAlreadyAllocated = _db.UserMultipleJobMappings.SingleOrDefault(x => x.refKey == refKey && x.username == username);
            if (ifAlreadyAllocated != null)
            {
                response.Status = 403;
                response.Message = "You have already applied for this job";
                return response;
            }
            else if (_db.UserMultipleJobMappings.Where(x => x.refKey == refKey && x.isFirst == Constants.status_true).Count() >= Convert.ToInt32((clientJobInfo.totalThreads)))
            {
                response.Status = 405;
                response.Message = "all threads are already allocated !!!";
                return response;
            }

            const int expectedDeliveryTimeInMinutes = 15;

            var UserMultipleJobMapping = new UserMultipleJobMapping();
            UserMultipleJobMapping.endTime = Constants.NA;
            UserMultipleJobMapping.expectedDelivery = DateTime.Now.AddMinutes(expectedDeliveryTimeInMinutes).ToString();
            UserMultipleJobMapping.refKey = refKey;
            UserMultipleJobMapping.startTime = DateTime.Now.ToString();
            UserMultipleJobMapping.status = Constants.status_assigned;

            if (clientJobInfo.type == Constants.type_moderation && clientJobInfo.subType == Constants.subType_moderatingPhotos)
            {
                UserMultipleJobMapping.subType = Constants.subType_moderatingPhotos;
                UserMultipleJobMapping.type = Constants.type_moderation;
            }
            else if (clientJobInfo.type == Constants.type_dataEntry && clientJobInfo.subType == Constants.subType_Transcription)
            {
                UserMultipleJobMapping.subType = Constants.subType_Transcription;
                UserMultipleJobMapping.type = Constants.type_dataEntry;
            }
            UserMultipleJobMapping.surveyResult = Constants.NA;
            UserMultipleJobMapping.username = username;

            var availableJobLists = _db.CreateTemplateImgurImagesLists.Where(x => x.referenceKey == refKey && x.status == Constants.status_open).ToList();
            if (availableJobLists != null)
            {
                if (availableJobLists.Count == 0)
                {
                    response.Status = 406;
                    response.Message = "All Threads of this job is already assigned.";
                    return response;
                }
                var transcriptionTask = availableJobLists.First();
                try
                {
                    //to be inclucded in lock
                    lock (this)
                    {
                        UserMultipleJobMapping.imageKey = transcriptionTask.imgurLink;
                        var updateImgurImageMapAfterAssigning = _db.CreateTemplateImgurImagesLists.SingleOrDefault(x => x.Id == transcriptionTask.Id);
                        updateImgurImageMapAfterAssigning.status = Constants.status_assigned;
                        _db.UserMultipleJobMappings.Add(UserMultipleJobMapping);
                        _db.SaveChanges();
                    }
                    //to be inclucded in lock


                    long JobId = clientJobInfo.Id;
                    long JobCompleted = _db.UserMultipleJobMappings.Where(x => x.refKey == refKey && x.status == Constants.status_done).Count();
                    long JobAssigned = _db.UserMultipleJobMappings.Where(x => x.refKey == refKey && x.status == Constants.status_assigned).Count();
                    long JobReviewed = (JobCompleted > 1) ? (JobCompleted) / 2 : 0;  // currently hard coded.

                    //var SignalRClientHub = new SignalRClientHub();
                    //var hubContext = GlobalHost.ConnectionManager.GetHubContext<SignalRClientHub>();
                    //dynamic client = SignalRManager.getSignalRDetail(clientJobInfo.username);
                    //if (client != null)
                    //{
                    //    client.updateClientProgressChart(Convert.ToString(JobId), clientJobInfo.totalThreads, Convert.ToString(JobCompleted), Convert.ToString(JobAssigned), Convert.ToString(JobReviewed));
                    //    //client.updateClientProgressChart("8", "20", "10", "8", "5");
                    //    //client.addMessage("add message signalR");
                    //}
                    bool status = new UserUpdatesClientRealTimeData().UpdateClientRealTimeData(JobId, JobCompleted, JobAssigned, JobReviewed, clientJobInfo.totalThreads, clientJobInfo.username);
                    response.Status = 200;
                    response.Message = "success-";
                    response.Payload = refKey;
                }
                catch (DbEntityValidationException e)
                {
                    DbContextException.LogDbContextException(e);
                    response.Status = 500;
                    response.Message = "Failed";
                    response.Payload = "Exception Occured";
                }
            }
            //UserMultipleJobMapping.imageKey = 


            return response;
        }
コード例 #6
0
        public ResponseModel<string> SubmitTemplateSurveyResultByRefKey(UserSurveyResultRequest EntireSurveyResult, string refKey,string username)
        {
            var response = new ResponseModel<string>();
            const string status_done = "done";
            const string status_assigned = "assigned";
            const string status_reviewed = "reviewed";

            if (EntireSurveyResult == null)
            {
                response.Status = 403;
                response.Message = "No data to save to database.";
                return response;
            }
            var UserAlreadySubmittedForThisSurvey = _db.UserJobMappings.SingleOrDefault(x => x.refKey == refKey && x.username == username && x.status == status_done);
            if(UserAlreadySubmittedForThisSurvey != null)
            {
                response.Status = 405;
                response.Message = "You cann't submit same survey Twice.";
                return response;
            }
            if (EntireSurveyResult.surveySingleAnswerQuestion != null)
            {
                foreach (var userSurveyResult in EntireSurveyResult.surveySingleAnswerQuestion)
                {
                    var surveyResponse = new UserSurveyResultToBeRevieweds1();
                    surveyResponse.questionId = userSurveyResult.key.Split('-')[1];
                    surveyResponse.type = userSurveyResult.key.Split('-')[0];
                    surveyResponse.answer = userSurveyResult.value;
                    surveyResponse.refKey = refKey;
                    surveyResponse.username = username;                    
                    _db.UserSurveyResultToBeRevieweds1.Add(surveyResponse);
                }
            }

            if (EntireSurveyResult.surveyMultipleAnswerQuestion != null)
            {
                foreach (var userSurveyResult in EntireSurveyResult.surveyMultipleAnswerQuestion)
                {
                    string[] optionValues = userSurveyResult.value.Split(';');
                    for (int i = 0; i < optionValues.Length - 1; i++)
                    {
                        var surveyResponse = new UserSurveyResultToBeRevieweds1();
                        surveyResponse.questionId = userSurveyResult.key.Split('-')[1];
                        surveyResponse.type = userSurveyResult.key.Split('-')[0];
                        surveyResponse.answer = optionValues[i];
                        surveyResponse.refKey = refKey;
                        surveyResponse.username = username;
                        _db.UserSurveyResultToBeRevieweds1.Add(surveyResponse);
                    }

                }
            }

            if (EntireSurveyResult.surveyListBoxAnswerQuestion != null)
            {
                foreach (var userSurveyResult in EntireSurveyResult.surveyListBoxAnswerQuestion)
                {
                    var surveyResponse = new UserSurveyResultToBeRevieweds1();
                    surveyResponse.questionId = userSurveyResult.key.Split('-')[1];
                    surveyResponse.type = userSurveyResult.key.Split('-')[0];
                    surveyResponse.answer = userSurveyResult.value;
                    surveyResponse.refKey = refKey;
                    surveyResponse.username = username;
                    _db.UserSurveyResultToBeRevieweds1.Add(surveyResponse);
                }
            }

            if (EntireSurveyResult.surveyTextBoxAnswerQuestion != null)
            {
                foreach (var userSurveyResult in EntireSurveyResult.surveyTextBoxAnswerQuestion)
                {
                    var surveyResponse = new UserSurveyResultToBeRevieweds1();
                    surveyResponse.questionId = userSurveyResult.key.Split('-')[1];
                    surveyResponse.type = userSurveyResult.key.Split('-')[0];
                    surveyResponse.answer = userSurveyResult.value;
                    surveyResponse.refKey = refKey;
                    surveyResponse.username = username;
                    _db.UserSurveyResultToBeRevieweds1.Add(surveyResponse);
                }
            }
            
            var surveyThreadUserJobMapping = _db.UserJobMappings.SingleOrDefault(x => x.username == username && x.refKey == refKey);
            
            surveyThreadUserJobMapping.status = status_done;
            surveyThreadUserJobMapping.endTime = DateTime.Now.ToString();
            try
            {
                _db.SaveChanges();
                var clientJobInfo = _db.CreateTemplateQuestionInfoes.SingleOrDefault(x => x.referenceId == refKey);
                //var payment = new UserReputationService().UpdateUserBalance(Constants.userType_user, username, Convert.ToDouble(_db.CreateTemplateQuestionInfoes.SingleOrDefault(x => x.referenceId == refKey).payPerUser), 0, Constants.payment_credit, clientJobInfo.title, clientJobInfo.type, clientJobInfo.subType);
                //if (!payment)
                    //logger.Info("payment failed for user : "******" of amount : " + _db.CreateTemplateQuestionInfoes.SingleOrDefault(x => x.referenceId == refKey).payPerUser);
                long JobId = clientJobInfo.Id;
                long JobCompleted = _db.UserJobMappings.Where(x => x.refKey == refKey && x.status == status_done).Count();
                long JobAssigned = _db.UserJobMappings.Where(x => x.refKey == refKey && x.status == status_assigned).Count();
                long JobReviewed = (JobCompleted > 1) ? (JobCompleted) / 2 : 0;  // currently hard coded.

                bool status = new UserUpdatesClientRealTimeData().UpdateClientRealTimeData(JobId, JobCompleted, JobAssigned, JobReviewed, clientJobInfo.totalThreads, clientJobInfo.username);
                response.Status = 200;
                response.Message = "success-";
                response.Payload = refKey;
            }
            catch (DbEntityValidationException e)
            {
                DbContextException.LogDbContextException(e);
                response.Status = 500;
                response.Message = "Failed";
                response.Payload = "Exception Occured";
            }

            return response;
        }