public IssueAssignedToViewModel(IApplicationService applicationService)
        {
            _applicationService = applicationService;
            Users = new ReactiveCollection<BasicUserModel>();

            SelectUserCommand = new ReactiveCommand();
            SelectUserCommand.RegisterAsyncTask(async t =>
            {
                var selectedUser = t as BasicUserModel;
                if (selectedUser != null)
                    SelectedUser = selectedUser;

                if (SaveOnSelect)
                {
                    var assignee = SelectedUser != null ? SelectedUser.Login : null;
                    var updateReq = _applicationService.Client.Users[RepositoryOwner].Repositories[RepositoryName].Issues[IssueId].UpdateAssignee(assignee);
                    await _applicationService.Client.ExecuteAsync(updateReq);
                }

                DismissCommand.ExecuteIfCan();
            });

            LoadCommand.RegisterAsyncTask(t => 
                Users.SimpleCollectionLoad(applicationService.Client.Users[RepositoryOwner].Repositories[RepositoryName].GetAssignees(), t as bool?));
        }
Example #2
0
        public LoginViewModel(IAccountsService accountsService)
        {
            LoginCommand = new ReactiveCommand(this.WhenAny(x => x.Username, x => x.Password, x => x.Domain, (u, p, d) =>
                                                            !string.IsNullOrEmpty(u.Value) && !string.IsNullOrEmpty(p.Value) && !string.IsNullOrEmpty(d.Value)));

            LoginCommand.RegisterAsyncTask(async x =>
            {
                var domain = Domain.TrimEnd('/');
                var client = AtlassianStashSharp.StashClient.CrateBasic(new Uri(domain), Username, Password);
                var info   = await client.Users[Username].Get().ExecuteAsync();

                var account = new Account {
                    Username = Username, Password = Password, Domain = domain
                };
                if (string.IsNullOrEmpty(account.AvatarUrl))
                {
                    var selfLink = info.Data.Links["self"].FirstOrDefault();
                    if (selfLink != null && !string.IsNullOrEmpty(selfLink.Href))
                    {
                        account.AvatarUrl = selfLink.Href + "/avatar.png";
                    }
                }

                accountsService.Insert(account);
                accountsService.ActiveAccount = account;
                LoggedInAcconut = account;
                MessageBus.Current.SendMessage(new LogoutMessage());
                //DismissCommand.ExecuteIfCan();
            });
        }
        public IssueMilestonesViewModel(IApplicationService applicationService)
        {
            Milestones = new ReactiveCollection<MilestoneModel>();

            SelectMilestoneCommand = new ReactiveCommand();
            SelectMilestoneCommand.RegisterAsyncTask(async t =>
            {
                var milestone = t as MilestoneModel;
                if (milestone != null)
                    SelectedMilestone = milestone;

                if (SaveOnSelect)
                {
                    try
                    {
                        int? milestoneNumber = null;
                        if (SelectedMilestone != null) milestoneNumber = SelectedMilestone.Number;
                        var updateReq = applicationService.Client.Users[RepositoryOwner].Repositories[RepositoryName].Issues[IssueId].UpdateMilestone(milestoneNumber);
                        await applicationService.Client.ExecuteAsync(updateReq);
                    }
                    catch (Exception e)
                    {
                        throw new Exception("Unable to to save milestone! Please try again.", e);
                    }
                }

                DismissCommand.ExecuteIfCan();
            });

            LoadCommand.RegisterAsyncTask(t =>
                Milestones.SimpleCollectionLoad(
                    applicationService.Client.Users[RepositoryOwner].Repositories[RepositoryName].Milestones.GetAll(),
                    t as bool?));
        }
Example #4
0
	    public IssueLabelsViewModel(IApplicationService applicationService)
	    {
	        Labels = new ReactiveCollection<LabelModel>();
            SelectedLabels = new ReactiveList<LabelModel>();

            SelectLabelsCommand = new ReactiveCommand();
	        SelectLabelsCommand.RegisterAsyncTask(async t =>
	        {
	            var selectedLabels = t as IEnumerable<LabelModel>;
                if (selectedLabels != null)
	                SelectedLabels.Reset(selectedLabels);

	            //If nothing has changed, dont do anything...
                if (OriginalLabels != null && OriginalLabels.Count() == SelectedLabels.Count() &&
                    OriginalLabels.Intersect(SelectedLabels).Count() == SelectedLabels.Count())
	            {
	                DismissCommand.ExecuteIfCan();
	                return;
	            }

	            if (SaveOnSelect)
	            {
	                try
	                {
                        var labels = (SelectedLabels != null && SelectedLabels.Count > 0) 
                                    ? SelectedLabels.Select(y => y.Name).ToArray() : null;
	                    var updateReq =
	                        applicationService.Client.Users[RepositoryOwner].Repositories[RepositoryName].Issues[IssueId]
	                            .UpdateLabels(labels);
                        await applicationService.Client.ExecuteAsync(updateReq);
	                }
	                catch (Exception e)
	                {
	                    throw new Exception("Unable to save labels! Please try again.", e);
	                }
	            }

                DismissCommand.ExecuteIfCan();
	        });

	        LoadCommand.RegisterAsyncTask(t =>
	            Labels.SimpleCollectionLoad(
	                applicationService.Client.Users[RepositoryOwner].Repositories[RepositoryName].Labels.GetAll(),
	                t as bool?));
	    }
Example #5
0
	    protected IssueModifyViewModel()
	    {
            SaveCommand = new ReactiveCommand();
	        SaveCommand.RegisterAsyncTask(t => Save());

            GoToAssigneeCommand = new ReactiveCommand();
	        GoToAssigneeCommand.Subscribe(_ =>
	        {
	            var vm = CreateViewModel<IssueAssignedToViewModel>();
	            vm.RepositoryOwner = RepositoryOwner;
	            vm.RepositoryName = RepositoryName;
	            vm.SelectedUser = AssignedTo;
	            vm.WhenAnyValue(x => x.SelectedUser).Subscribe(x => AssignedTo = x);
                ShowViewModel(vm);
	        });


            GoToMilestonesCommand = new ReactiveCommand();
            GoToMilestonesCommand.Subscribe(_ =>
            {
                var vm = CreateViewModel<IssueMilestonesViewModel>();
                vm.RepositoryOwner = RepositoryOwner;
                vm.RepositoryName = RepositoryName;
                vm.SelectedMilestone = Milestone;
                vm.WhenAnyValue(x => x.SelectedMilestone).Subscribe(x => Milestone = x);
                ShowViewModel(vm);
            });

            GoToLabelsCommand = new ReactiveCommand();
            GoToLabelsCommand.Subscribe(_ =>
            {
                var vm = CreateViewModel<IssueLabelsViewModel>();
                vm.RepositoryOwner = RepositoryOwner;
                vm.RepositoryName = RepositoryName;
                vm.SelectedLabels.Reset(Labels);
                vm.OriginalLabels = Labels;
                vm.WhenAnyValue(x => x.SelectedLabels).Subscribe(x => Labels = x.ToArray());
                ShowViewModel(vm);
            });
	    }
Example #6
0
        public GistCreateViewModel(IApplicationService applicationService)
        {
            _applicationService = applicationService;

            SaveCommand = new ReactiveCommand();
            SaveCommand.RegisterAsyncTask(async t =>
            {
                if (_files == null || _files.Count == 0)
                    throw new Exception("You cannot create a Gist without atleast one file! Please correct and try again.");

                var createGist = new GistCreateModel
                {
                    Description = Description,
                    Public = Public,
                    Files = Files.ToDictionary(x => x.Key, x => new GistCreateModel.File { Content = x.Value })
                };

                var newGist = (await _applicationService.Client.ExecuteAsync(_applicationService.Client.AuthenticatedUser.Gists.CreateGist(createGist))).Data;
                CreatedGist = newGist;
                DismissCommand.ExecuteIfCan();
            });
        }
        public RepositoriesExploreViewModel(IApplicationService applicationService, INetworkActivityService networkActivityService)
        {
            _applicationService = applicationService;
            Repositories = new ReactiveCollection<RepositorySearchModel.RepositoryModel>();

            SearchCommand = new ReactiveCommand(this.WhenAnyValue(x => x.SearchText, x => !string.IsNullOrEmpty(x)));
            SearchCommand.IsExecuting.Skip(1).Subscribe(x => 
            {
                if (x)
                    networkActivityService.PushNetworkActive();
                else
                    networkActivityService.PopNetworkActive();
            });
            SearchCommand.RegisterAsyncTask(async t =>
            {
                try
                {
                    var request = applicationService.Client.Repositories.SearchRepositories(new[] { SearchText }, new string[] { });
                    request.UseCache = false;
                    var response = await applicationService.Client.ExecuteAsync(request);
                    Repositories.Reset(response.Data.Items);
                }
                catch (Exception e)
                {
                    throw new Exception("Unable to search for repositories. Please try again.", e);
                }
            });

            GoToRepositoryCommand = new ReactiveCommand();
            GoToRepositoryCommand.OfType<RepositorySearchModel.RepositoryModel>().Subscribe(x =>
            {
                var vm = CreateViewModel<RepositoryViewModel>();
                vm.RepositoryOwner = x.Owner.Login;
                vm.RepositoryName = x.Name;
                ShowViewModel(vm);
            });
        }
Example #8
0
        public RepositoryViewModel(IApplicationService applicationService)
        {
            ApplicationService = applicationService;

            ToggleStarCommand = new ReactiveCommand(this.WhenAnyValue(x => x.IsStarred, x => x.HasValue));
            ToggleStarCommand.RegisterAsyncTask(t => ToggleStar());

            ToggleWatchCommand = new ReactiveCommand(this.WhenAnyValue(x => x.IsWatched, x => x.HasValue));
            ToggleWatchCommand.RegisterAsyncTask(t => ToggleWatch());

            GoToOwnerCommand = new ReactiveCommand();
            GoToOwnerCommand.Subscribe(_ =>
            {
                var vm = CreateViewModel<ProfileViewModel>();
                vm.Username = RepositoryOwner;
                ShowViewModel(vm);
            });

            PinCommand = new ReactiveCommand(this.WhenAnyValue(x => x.Repository, x => x != null));
            PinCommand.Subscribe(x => PinRepository());

            GoToForkParentCommand = new ReactiveCommand(this.WhenAnyValue(x => x.Repository, x => x != null && x.Fork && x.Parent != null));
            GoToForkParentCommand.Subscribe(x =>
            {
                var vm = CreateViewModel<RepositoryViewModel>();
                vm.RepositoryOwner = Repository.Parent.Owner.Login;
                vm.RepositoryName = Repository.Parent.Name;
                vm.Repository = Repository.Parent;
                ShowViewModel(vm);
            });

            GoToStargazersCommand = new ReactiveCommand();
            GoToStargazersCommand.Subscribe(_ =>
            {
                var vm = CreateViewModel<RepositoryStargazersViewModel>();
                vm.RepositoryOwner = RepositoryOwner;
                vm.RepositoryName = RepositoryName;
                ShowViewModel(vm);
            });

            GoToWatchersCommand = new ReactiveCommand();
            GoToWatchersCommand.Subscribe(_ =>
            {
                var vm = CreateViewModel<RepositoryWatchersViewModel>();
                vm.RepositoryOwner = RepositoryOwner;
                vm.RepositoryName = RepositoryName;
                ShowViewModel(vm);
            });

            GoToEventsCommand = new ReactiveCommand();
            GoToEventsCommand.Subscribe(_ =>
            {
                var vm = CreateViewModel<RepositoryEventsViewModel>();
                vm.RepositoryOwner = RepositoryOwner;
                vm.RepositoryName = RepositoryName;
                ShowViewModel(vm);
            });

            GoToIssuesCommand = new ReactiveCommand();
            GoToIssuesCommand.Subscribe(_ =>
            {
                var vm = CreateViewModel<IssuesViewModel>();
                vm.RepositoryOwner = RepositoryOwner;
                vm.RepositoryName = RepositoryName;
                ShowViewModel(vm);
            });

            GoToReadmeCommand = new ReactiveCommand();
            GoToReadmeCommand.Subscribe(_ =>
            {
                var vm = CreateViewModel<ReadmeViewModel>();
                vm.RepositoryOwner = RepositoryOwner;
                vm.RepositoryName = RepositoryName;
                ShowViewModel(vm);
            });

            GoToCommitsCommand = new ReactiveCommand();
            GoToCommitsCommand.Subscribe(_ =>
            {
                if (Branches != null && Branches.Count == 1)
                {
                    var vm = CreateViewModel<ChangesetsViewModel>();
                    vm.RepositoryOwner = RepositoryOwner;
                    vm.RepositoryName = RepositoryName;
                    ShowViewModel(vm);
                }
                else
                {
                    var vm = CreateViewModel<ChangesetBranchesViewModel>();
                    vm.RepositoryOwner = RepositoryOwner;
                    vm.RepositoryName = RepositoryName;
                    ShowViewModel(vm);
                }
            });

            GoToPullRequestsCommand = new ReactiveCommand();
            GoToPullRequestsCommand.Subscribe(_ =>
            {
                var vm = CreateViewModel<PullRequestsViewModel>();
                vm.RepositoryOwner = RepositoryOwner;
                vm.RepositoryName = RepositoryName;
                ShowViewModel(vm);
            });

            GoToSourceCommand = new ReactiveCommand();
            GoToSourceCommand.Subscribe(_ =>
            {
                var vm = CreateViewModel<BranchesAndTagsViewModel>();
                vm.RepositoryOwner = RepositoryOwner;
                vm.RepositoryName = RepositoryName;
                ShowViewModel(vm);
            });

            GoToCollaboratorsCommand = new ReactiveCommand();
            GoToCollaboratorsCommand.Subscribe(_ =>
            {
                var vm = CreateViewModel<RepositoryCollaboratorsViewModel>();
                vm.RepositoryOwner = RepositoryOwner;
                vm.RepositoryName = RepositoryName;
                ShowViewModel(vm);
            });

            GoToHtmlUrlCommand = new ReactiveCommand(this.WhenAnyValue(x => x.Repository, x => x != null && !string.IsNullOrEmpty(x.HtmlUrl)));
            GoToHtmlUrlCommand.Subscribe(_ => GoToUrlCommand.ExecuteIfCan(Repository.HtmlUrl));

            LoadCommand.RegisterAsyncTask(t =>
            {
                var forceCacheInvalidation = t as bool?;

                var t1 = this.RequestModel(ApplicationService.Client.Users[RepositoryOwner].Repositories[RepositoryName].Get(), 
                    forceCacheInvalidation, response => Repository = response.Data);

                this.RequestModel(ApplicationService.Client.Users[RepositoryOwner].Repositories[RepositoryName].GetReadme(),
                    forceCacheInvalidation, response => Readme = response.Data).FireAndForget();

                this.RequestModel(ApplicationService.Client.Users[RepositoryOwner].Repositories[RepositoryName].GetBranches(),
                    forceCacheInvalidation, response => Branches = response.Data).FireAndForget();

                this.RequestModel(ApplicationService.Client.Users[RepositoryOwner].Repositories[RepositoryName].IsWatching(),
                    forceCacheInvalidation, response => IsWatched = response.Data).FireAndForget();

                this.RequestModel(ApplicationService.Client.Users[RepositoryOwner].Repositories[RepositoryName].IsStarred(),
                    forceCacheInvalidation, response => IsStarred = response.Data).FireAndForget();

                this.RequestModel(ApplicationService.Client.Users[RepositoryOwner].Repositories[RepositoryName].GetCollaborators(),
                    forceCacheInvalidation, response => Collaborators = response.Data.Count).FireAndForget();

                return t1;
            });
        }
Example #9
0
        public ProfileViewModel(IApplicationService applicationService)
        {
            _applicationService = applicationService;

            ToggleFollowingCommand = new ReactiveCommand(this.WhenAnyValue(x => x.IsFollowing, x => x.HasValue));
            ToggleFollowingCommand.RegisterAsyncTask(t => ToggleFollowing());

            GoToGistsCommand = new ReactiveCommand();
            GoToGistsCommand.Subscribe(_ =>
            {
                var vm = CreateViewModel<UserGistsViewModel>();
                vm.Username = Username;
                ShowViewModel(vm);
            });

            GoToRepositoriesCommand = new ReactiveCommand();
            GoToRepositoriesCommand.Subscribe(_ =>
            {
                var vm = CreateViewModel<UserRepositoriesViewModel>();
                vm.Username = Username;
                ShowViewModel(vm);
            });

            GoToOrganizationsCommand = new ReactiveCommand();
            GoToOrganizationsCommand.Subscribe(_ =>
            {
                var vm = CreateViewModel<OrganizationsViewModel>();
                vm.Username = Username;
                ShowViewModel(vm);
            });

            GoToEventsCommand = new ReactiveCommand();
            GoToEventsCommand.Subscribe(_ =>
            {
                var vm = CreateViewModel<UserEventsViewModel>();
                vm.Username = Username;
                ShowViewModel(vm);
            });

            GoToFollowingCommand = new ReactiveCommand();
            GoToFollowingCommand.Subscribe(_ =>
            {
                var vm = CreateViewModel<UserFollowingsViewModel>();
                vm.Username = Username;
                ShowViewModel(vm);
            });

            GoToFollowersCommand = new ReactiveCommand();
            GoToFollowersCommand.Subscribe(_ =>
            {
                var vm = CreateViewModel<UserFollowersViewModel>();
                vm.Username = Username;
                ShowViewModel(vm);
            });

            LoadCommand.RegisterAsyncTask(t =>
            {
                this.RequestModel(applicationService.Client.AuthenticatedUser.IsFollowing(Username), t as bool?, x => IsFollowing = x.Data).FireAndForget();
                return this.RequestModel(applicationService.Client.Users[Username].Get(), t as bool?, response => User = response.Data);
            });
        }
Example #10
0
        public PullRequestViewModel(IApplicationService applicationService, IMarkdownService markdownService, IShareService shareService)
        {
            _applicationService = applicationService;
            _markdownService = markdownService;

            Comments = new ReactiveCollection<IssueCommentModel>();
            Events = new ReactiveCollection<IssueEventModel>();

            MergeCommand = new ReactiveCommand(this.WhenAnyValue(x => x.PullRequest, x => 
                x != null && x.Merged.HasValue && !x.Merged.Value && x.Mergable.HasValue && x.Mergable.Value));
            MergeCommand.RegisterAsyncTask(async t =>
            {
                try
                {
                    var response = await _applicationService.Client.ExecuteAsync(_applicationService.Client.Users[RepositoryOwner].Repositories[RepositoryName].PullRequests[PullRequestId].Merge());
                    if (!response.Data.Merged)
                        throw new Exception(response.Data.Message);
                    var pullRequest = _applicationService.Client.Users[RepositoryOwner].Repositories[RepositoryName].PullRequests[PullRequestId].Get();
                    await this.RequestModel(pullRequest, true, r => PullRequest = r.Data);
                }
                catch (Exception e)
                {
                    throw new Exception("Unable to Merge: " + e.Message, e);
                }
            });

            ToggleStateCommand = new ReactiveCommand(this.WhenAnyValue(x => x.PullRequest, x => x != null));
            ToggleStateCommand.RegisterAsyncTask(async t =>
            {
                var close = string.Equals(PullRequest.State, "open", StringComparison.OrdinalIgnoreCase);

                try
                {
                    var data = await _applicationService.Client.ExecuteAsync(
                        _applicationService.Client.Users[RepositoryOwner].Repositories[RepositoryName].PullRequests[PullRequestId].UpdateState(close ? "closed" : "open"));
                    PullRequest = data.Data;
                }
                catch (Exception e)
                {
                    throw new Exception("Unable to " + (close ? "close" : "open") + " the item. " + e.Message, e);
                }
            });

            GoToCommitsCommand = new ReactiveCommand();
            GoToCommitsCommand.Subscribe(_ =>
            {
                var vm = CreateViewModel<PullRequestCommitsViewModel>();
                vm.RepositoryOwner = RepositoryOwner;
                vm.RepositoryName = RepositoryName;
                vm.PullRequestId = PullRequestId;
                ShowViewModel(vm);
            });

            GoToFilesCommand = new ReactiveCommand();
            GoToFilesCommand.Subscribe(_ =>
            {
                var vm = CreateViewModel<PullRequestFilesViewModel>();
                vm.Username = RepositoryOwner;
                vm.Repository = RepositoryName;
                vm.PullRequestId = PullRequestId;
                ShowViewModel(vm);
            });

            ShareCommand = new ReactiveCommand(this.WhenAnyValue(x => x.PullRequest, x => x != null && !string.IsNullOrEmpty(x.HtmlUrl)));
            ShareCommand.Subscribe(_ => shareService.ShareUrl(PullRequest.HtmlUrl));

            GoToEditCommand = new ReactiveCommand();
            GoToEditCommand.Subscribe(_ =>
            {
                var vm = CreateViewModel<IssueEditViewModel>();
                vm.RepositoryOwner = RepositoryOwner;
                vm.RepositoryName = RepositoryName;
                vm.Id = PullRequestId;
                vm.Issue = Issue;
                vm.WhenAnyValue(x => x.Issue).Skip(1).Subscribe(x => Issue = x);
                ShowViewModel(vm);
            });

            GoToLabelsCommand = new ReactiveCommand(this.WhenAnyValue(x => x.Issue, x => x != null));
            GoToLabelsCommand.Subscribe(_ =>
            {
                var vm = CreateViewModel<IssueLabelsViewModel>();
                vm.RepositoryOwner = RepositoryOwner;
                vm.RepositoryName = RepositoryName;
                vm.IssueId = PullRequestId;
                vm.SaveOnSelect = true;
                vm.SelectedLabels.Reset(Issue.Labels);
                vm.WhenAnyValue(x => x.Labels).Skip(1).Subscribe(x =>
                {
                    Issue.Labels = x.ToList();
                    this.RaisePropertyChanged("Issue");
                });
                ShowViewModel(vm);
            });

            GoToMilestoneCommand = new ReactiveCommand(this.WhenAnyValue(x => x.Issue, x => x != null));
            GoToMilestoneCommand.Subscribe(_ =>
            {
                var vm = CreateViewModel<IssueMilestonesViewModel>();
                vm.RepositoryOwner = RepositoryOwner;
                vm.RepositoryName = RepositoryName;
                vm.IssueId = PullRequestId;
                vm.SaveOnSelect = true;
                vm.SelectedMilestone = Issue.Milestone;
                vm.WhenAnyValue(x => x.SelectedMilestone).Skip(1).Subscribe(x =>
                {
                    Issue.Milestone = x;
                    this.RaisePropertyChanged("Issue");
                });
                ShowViewModel(vm);
            });

            GoToAssigneeCommand = new ReactiveCommand(this.WhenAnyValue(x => x.Issue, x => x != null));
            GoToAssigneeCommand.Subscribe(_ =>
            {
                var vm = CreateViewModel<IssueAssignedToViewModel>();
                vm.RepositoryOwner = RepositoryOwner;
                vm.RepositoryName = RepositoryName;
                vm.IssueId = PullRequestId;
                vm.SaveOnSelect = true;
                vm.SelectedUser = Issue.Assignee;
                vm.WhenAnyValue(x => x.SelectedUser).Skip(1).Subscribe(x =>
                {
                    Issue.Assignee = x;
                    this.RaisePropertyChanged("Issue");
                });
                ShowViewModel(vm);
            });

            GoToAddCommentCommand = new ReactiveCommand();
            GoToAddCommentCommand.Subscribe(_ =>
            {
                var vm = CreateViewModel<CommentViewModel>();
                vm.SaveCommand.RegisterAsyncTask(async t =>
                {
                    var req =
                        _applicationService.Client.Users[RepositoryOwner]
                        .Repositories[RepositoryName].Issues[PullRequestId].CreateComment(vm.Comment);
                    var comment = await _applicationService.Client.ExecuteAsync(req);
                    Comments.Add(comment.Data);
                    vm.DismissCommand.ExecuteIfCan();
                });
            });

            LoadCommand.RegisterAsyncTask(t =>
            {
                var forceCacheInvalidation = t as bool?;
                var pullRequest = _applicationService.Client.Users[RepositoryOwner].Repositories[RepositoryName].PullRequests[PullRequestId].Get();
                var t1 = this.RequestModel(pullRequest, forceCacheInvalidation, response => PullRequest = response.Data);
                Events.SimpleCollectionLoad(_applicationService.Client.Users[RepositoryOwner].Repositories[RepositoryName].Issues[PullRequestId].GetEvents(), forceCacheInvalidation).FireAndForget();
                Comments.SimpleCollectionLoad(_applicationService.Client.Users[RepositoryOwner].Repositories[RepositoryName].Issues[PullRequestId].GetComments(), forceCacheInvalidation).FireAndForget();
                this.RequestModel(_applicationService.Client.Users[RepositoryOwner].Repositories[RepositoryName].Issues[PullRequestId].Get(), forceCacheInvalidation, response => Issue = response.Data).FireAndForget();
                return t1;
            });
        }