hubstats 0.3.4 → 0.3.5

Sign up to get free protection for your applications and to get access to all the features.
Files changed (44) hide show
  1. checksums.yaml +8 -8
  2. data/CHANGELOG.markdown +1 -0
  3. data/app/assets/javascripts/hubstats/users.js +5 -1
  4. data/app/controllers/hubstats/deploys_controller.rb +21 -8
  5. data/app/controllers/hubstats/pull_requests_controller.rb +2 -1
  6. data/app/controllers/hubstats/repos_controller.rb +13 -8
  7. data/app/controllers/hubstats/users_controller.rb +4 -5
  8. data/app/models/hubstats/deploy.rb +3 -3
  9. data/app/models/hubstats/pull_request.rb +12 -1
  10. data/app/models/hubstats/repo.rb +1 -0
  11. data/app/models/hubstats/user.rb +11 -1
  12. data/app/views/hubstats/deploys/index.html.erb +4 -4
  13. data/app/views/hubstats/deploys/show.html.erb +4 -0
  14. data/app/views/hubstats/partials/_deploy-condensed.html.erb +9 -4
  15. data/app/views/hubstats/partials/_deploy.html.erb +5 -5
  16. data/app/views/hubstats/partials/_quick_addition_stats.html.erb +19 -0
  17. data/app/views/hubstats/partials/_quick_stats.html.erb +19 -18
  18. data/app/views/hubstats/partials/_repo.html.erb +4 -3
  19. data/app/views/hubstats/partials/_user.html.erb +18 -5
  20. data/app/views/hubstats/pull_requests/show.html.erb +10 -0
  21. data/app/views/hubstats/repos/dashboard.html.erb +6 -11
  22. data/app/views/hubstats/repos/show.html.erb +20 -5
  23. data/app/views/hubstats/tables/_deploys-condensed.html.erb +2 -2
  24. data/app/views/hubstats/tables/_users-condensed.html.erb +1 -1
  25. data/app/views/hubstats/tables/_users.html.erb +9 -2
  26. data/app/views/hubstats/users/index.html.erb +1 -1
  27. data/app/views/hubstats/users/show.html.erb +9 -3
  28. data/config/routes.rb +1 -1
  29. data/db/migrate/20150526154850_create_hubstats_deploys.rb +0 -1
  30. data/db/migrate/20150605184015_add_user_id_delete_deployed_by_to_deploy.rb +6 -0
  31. data/db/migrate/20150605190549_add_merged_by_column_to_pull_request.rb +5 -0
  32. data/db/seeds.rb +1 -1
  33. data/lib/hubstats/version.rb +1 -1
  34. data/spec/controllers/hubstats/deploys_controller_spec.rb +36 -25
  35. data/spec/factories/deploys.rb +8 -1
  36. data/spec/factories/pull_requests.rb +12 -0
  37. data/spec/models/hubstats/comment_spec.rb +2 -2
  38. data/spec/models/hubstats/deploy_spec.rb +20 -20
  39. data/spec/models/hubstats/label_spec.rb +3 -3
  40. data/spec/models/hubstats/pull_request_spec.rb +32 -1
  41. data/spec/models/hubstats/repo_spec.rb +7 -7
  42. data/spec/models/hubstats/user_spec.rb +1 -1
  43. data/test/dummy/db/schema.rb +2 -2
  44. metadata +5 -2
@@ -1,14 +1,15 @@
1
1
  <div class="row single-repo">
2
- <div class="repo-image-small col-lg-1 col-md-1 col-sm-1 col-xs-2" >
2
+ <div class="repo-image-small col-lg-1 col-md-1 col-sm-1 col-xs-1" >
3
3
  <span class="repo-octicon-small mega-octicon octicon-repo"></span>
4
-
5
4
  </div>
5
+
6
6
  <div class="repo-info col-lg-10 col-md-10 col-sm-10 col-xs-8">
7
7
  <h4>
8
8
  <%= link_to repo.name, repo_path(repo)%>
9
9
  </h4>
10
10
  updated <%= distance_of_time_in_words(DateTime.now,repo.updated_at) %> ago
11
11
  </div>
12
+
12
13
  <div class="col-lg-1 col-md-1 col-sm-1 col-xs-1">
13
14
  <div class="pull-right">
14
15
  <a class="subtle" href=<%= repo.html_url %> >
@@ -17,4 +18,4 @@
17
18
  </span>
18
19
  </div>
19
20
  </div>
20
- </div>
21
+ </div>
@@ -14,6 +14,13 @@
14
14
  </a>
15
15
  </h4>
16
16
  </div>
17
+ <!-- Show the total number of deploys for this user -->
18
+ <div class="col-lg-2 col-md-2 col-sm-2">
19
+ <div class="text-center">
20
+ <span class="text-large"><%= user.deploy_count %></span>
21
+ <span class="mega-octicon octicon-rocket"></span>
22
+ </div>
23
+ </div>
17
24
  <div class="col-lg-2 col-md-2 col-sm-2">
18
25
  <div class="text-center">
19
26
  <span class="text-large"><%= user.pull_request_count %></span>
@@ -26,17 +33,23 @@
26
33
  <span class="mega-octicon octicon-comment"></span>
27
34
  </div>
28
35
  </div>
36
+ <!-- Show the net additions using the average_additions and the average_deletions -->
29
37
  <div class="col-lg-2 col-md-2 col-sm-2">
30
38
  <div class="text-center">
31
- <span class="text-large"><%= user.average_additions %></span>
32
- <span class="mega-octicon octicon-plus"></span>
39
+ <span class="text-large"><%= user.average_additions - user.average_deletions %></span>
33
40
  </div>
34
41
  </div>
35
- <div class="col-lg-2 col-md-2 col-sm-2">
42
+ <!-- <div class="col-lg-2 col-md-2 col-sm-2">
36
43
  <div class="text-center">
37
- <span class="text-large"><%= user.average_deletions %></span>
38
- <span class="mega-octicon octicon-dash"></span>
44
+ <span class="text-medium"><%= user.average_additions %></span>
45
+ <span class="octicon octicon-plus"></span>
39
46
  </div>
40
47
  </div>
48
+ <div class="col-lg-2 col-md-2 col-sm-2">
49
+ <div class="text-center">
50
+ <span class="text-medium"><%= user.average_deletions %></span>
51
+ <span class="octicon octicon-dash"></span>
52
+ </div>
53
+ </div> -->
41
54
 
42
55
  </div>
@@ -9,6 +9,16 @@
9
9
  <%= render 'hubstats/partials/quick_stats' %>
10
10
  </div>
11
11
 
12
+ <!-- If the pull request is closed, then show the deploy that merged this PR -->
13
+ <div class="col col-lg-8 col-lg-offset-2">
14
+ <div class="row">
15
+ <%if @pull_request.state == "closed"%>
16
+ <h4> Deployment </h4>
17
+ <%= render 'hubstats/tables/deploys-condensed' %>
18
+ <%end%>
19
+ </div>
20
+ </div>
21
+
12
22
  <div class="col col-lg-8 col-lg-offset-2">
13
23
  <div class="row">
14
24
  <h4> Comments </h4>
@@ -1,24 +1,19 @@
1
1
  <div class="container" id="splash">
2
2
  <div class="row text-center">
3
3
  <%= render 'hubstats/partials/quick_stats' %>
4
+ <br>
5
+ <br>
6
+ <br>
7
+ <br>
8
+ <br>
9
+ <%= render 'hubstats/partials/quick_addition_stats' %>
4
10
  </div>
5
11
 
6
12
  <div class="row">
7
13
  <div class="col col-lg-12">
8
14
  <h3> All Repositories </h3>
9
15
  <%= render 'hubstats/tables/repos' %>
10
- <!-- <% if @repo_count > 20 %>
11
- <p class="pull-right"><%= link_to "View All", repos_path %></p>
12
- <% end %>-->
13
16
  </div>
14
-
15
- <!-- <div class="col col-lg-6">
16
- <h3> Active Users </h3>
17
- <%= render 'hubstats/tables/users-condensed' %>
18
- <% if @user_count > 20 %>
19
- <p class="pull-right"><%= link_to "View All", users_path %></p>
20
- <% end %>
21
- </div> -->
22
17
 
23
18
  </div>
24
19
  </div>
@@ -2,11 +2,26 @@
2
2
 
3
3
  <div class="row">
4
4
  <h1 class="title text-center"><a href=<%=@repo.html_url%>> <%= @repo.name.titleize %> </a></h1>
5
- <%= render 'hubstats/partials/quick_stats' %>
5
+ <%= render 'hubstats/partials/quick_stats' %>
6
+ <br>
7
+ <br>
8
+ <br>
9
+ <br>
10
+ <br>
11
+ <%= render 'hubstats/partials/quick_addition_stats' %>
6
12
  </div>
7
13
 
8
14
  <div class="row">
9
15
 
16
+ <!-- Show all of the deploys for this repository -->
17
+ <div class="col col-lg-6">
18
+ <h3> Deploys </h3>
19
+ <%= render "hubstats/tables/deploys-condensed" %>
20
+ <% if @deploy_count > 20 %>
21
+ <p class="pull-right"><%= link_to "View All", deploys_path(:repos => @repo.id) %></p>
22
+ <% end %>
23
+ </div>
24
+
10
25
  <div class="col col-lg-6">
11
26
  <h3> Pull Requests</h3>
12
27
  <%= render 'hubstats/tables/pulls-condensed'%>
@@ -15,10 +30,10 @@
15
30
  <% end %>
16
31
  </div>
17
32
 
18
- <div class="col col-lg-6">
19
- <h3> Active Users </h3>
20
- <%= render 'hubstats/tables/users-condensed' %>
21
- </div>
33
+ <!-- <div class="col col-lg-6"> -->
34
+ <!-- <h3> Active Users </h3> -->
35
+ <!-- <%= render 'hubstats/tables/users-condensed' %> -->
36
+ <!-- </div> -->
22
37
 
23
38
  </div>
24
39
 
@@ -1,7 +1,7 @@
1
1
  <% if @deploys.length > 0 %>
2
2
  <div class="deploys">
3
- <%= render partial: 'hubstats/partials/deploys-condensed', collection: @deploys, as: :deploy %>
3
+ <%= render partial: 'hubstats/partials/deploy-condensed', collection: @deploys, as: :deploy %>
4
4
  </div>
5
5
  <% else %>
6
- <p> No deploys to show </p>
6
+ <p> No deployment information available</p>
7
7
  <% end %>
@@ -4,4 +4,4 @@
4
4
  </div>
5
5
  <% else %>
6
6
  <p> No users to show </p>
7
- <% end %>
7
+ <% end %>
@@ -3,21 +3,28 @@
3
3
  <div class="row single-user header">
4
4
  <div class="col-lg-4 col-md-4 col-sm-4">
5
5
  </div>
6
+ <div class="col-lg-2 col-md-2 col-sm-2">
7
+ <a class="header desc" id="deploys"> Deploys <span class="octicon"></span> </a>
8
+ </div>
6
9
  <div class="col-lg-2 col-md-2 col-sm-2">
7
10
  <a class="header desc" id="pulls"> Pulls <span class="octicon"></span> </a>
8
11
  </div>
9
12
  <div class="col-lg-2 col-md-2 col-sm-2">
10
13
  <a class="header desc" id="comments"> Comments <span class="octicon"></span></a>
11
14
  </div>
15
+ <!-- Show the net additions instead of the additions and deletions separately -->
12
16
  <div class="col-lg-2 col-md-2 col-sm-2">
17
+ <a class="header desc" id="additions"> Net Additions <span class="octicon"></span></a>
18
+ </div>
19
+ <!-- <div class="col-lg-2 col-md-2 col-sm-2">
13
20
  <a class="header desc" id="additions"> Additions <span class="octicon"></span></a>
14
21
  </div>
15
22
  <div class="col-lg-2 col-md-2 col-sm-2">
16
23
  <a class="header desc" id="deletions"> Deletions <span class="octicon"></span></a>
17
- </div>
24
+ </div> -->
18
25
  </div>
19
26
  <%= render partial: 'hubstats/partials/user', collection: @users, as: :user %>
20
27
  </div>
21
28
  <% else %>
22
29
  <p> No users to show </p>
23
- <% end %>
30
+ <% end %>
@@ -20,4 +20,4 @@
20
20
  </div>
21
21
  </div>
22
22
  </div>
23
- </div>
23
+ </div>
@@ -13,9 +13,15 @@
13
13
  <% end %>
14
14
  </div>
15
15
 
16
+ <!-- <div class="col-lg-6 col-md-6 col-sm-6 col-xs-6"> -->
17
+ <!-- <h3> Comments </h3> -->
18
+ <!-- <%= render 'hubstats/tables/comments-condensed' %> -->
19
+ <!-- </div> -->
20
+
21
+ <!-- Show all of the deploys this user did -->
16
22
  <div class="col-lg-6 col-md-6 col-sm-6 col-xs-6">
17
- <h3> Comments </h3>
18
- <%= render 'hubstats/tables/comments-condensed' %>
23
+ <h3> Deploys </h3>
24
+ <%= render 'hubstats/tables/deploys-condensed' %>
19
25
  </div>
20
26
  </div>
21
- </div>
27
+ </div>
data/config/routes.rb CHANGED
@@ -6,7 +6,7 @@ Hubstats::Engine.routes.draw do
6
6
  get "/pulls" => "pull_requests#index", :as => :pulls #routes to list of pulls
7
7
  get "/users" => "users#index", :as => :users #routes to list of users
8
8
  get "/user/:id" => "users#show", :as => :user #routes to specific user's contributions
9
- get "/repos" => "repos#dashboard", :as => :repos #routes to list of repos and stats
9
+ get "/repos" => "repos#index", :as => :repos #route is for the repo filter on the pull request and deploys page
10
10
  get "/:repo" => "repos#show", :as => :repo #routes to specific repo's stats
11
11
  scope "/:repo", :as => :repo do
12
12
  get '/pull/:id' => "pull_requests#show", :as => :pull
@@ -5,7 +5,6 @@ class CreateHubstatsDeploys < ActiveRecord::Migration
5
5
  t.integer :repo_id
6
6
  t.timestamp :deployed_at
7
7
  t.string :deployed_by
8
- t.integer :user_id
9
8
  end
10
9
  end
11
10
  end
@@ -0,0 +1,6 @@
1
+ class AddUserIdDeleteDeployedByToDeploy < ActiveRecord::Migration
2
+ def change
3
+ add_column :hubstats_deploys, :user_id, :integer
4
+ remove_column :hubstats_deploys, :deployed_by
5
+ end
6
+ end
@@ -0,0 +1,5 @@
1
+ class AddMergedByColumnToPullRequest < ActiveRecord::Migration
2
+ def change
3
+ add_column :hubstats_pull_requests, :merged_by, :integer
4
+ end
5
+ end
data/db/seeds.rb CHANGED
@@ -13,7 +13,7 @@ deploy_list = [
13
13
  ["is93h1n", "sportngin/janky", "2014-12-31 09:00:00 -0500", "EvaMartinuzzi", 6384174, "3274757, 5708038"],
14
14
  ["kdiq13j", "sportngin/ngin", "2013-11-17 04:00:00 -0500", "Olson3R", 6902485, "10444039, 11917574"],
15
15
  ["ciap1kd", "sportngin/statcore_ice_hockey", "2010-08-29 01:00:00 -0500", "odelltuttle", 7231089, "25856007"],
16
- ["iek9s0d", "sportngin/freshbooks.rb", "2015-05-13 12:00:00 -0500", "tombadaczewski", 4095632, "4534280, 3557640"],
16
+ ["iek9s0d", "sportngin/thinking-sphinx", "2015-05-13 12:00:00 -0500", "tombadaczewski", 4095632, "4534280, 3557640"],
17
17
  ["918240d", "sportngin/pocket_ngin", "2015-04-01 03:00:00 -0500", "plaincheesepizza", 5577837, "27117320, 1967369, 20911625"],
18
18
  ["dis8203", "sportngin/sport_ngin_live", "2015-02-27 08:00:00 -0500", "GeoffreyHinck", 5167099, "9657609, 4745225, 35976969, 5180938"],
19
19
  ["2kd9sac", "sportngin/jarvis", "2015-05-26 03:00:00 -0500", "Bleisz22", 7452482, "23303693, 2990349"],
@@ -1,3 +1,3 @@
1
1
  module Hubstats
2
- VERSION = "0.3.4"
2
+ VERSION = "0.3.5"
3
3
  end
@@ -6,89 +6,97 @@ module Hubstats
6
6
  describe "#create" do
7
7
 
8
8
  before :each do
9
- create(:repo, :full_name => "sportngin/ngin")
9
+ create(:pull_request, :number => 33364992, :merged_by => 202020)
10
10
  end
11
11
 
12
12
  it 'should create a deploy' do
13
13
  post(:create, {"git_revision" => "c1a2b37",
14
- "repo_name" => "sportngin/ngin",
14
+ "repo_name" => "hub/hubstats",
15
15
  "deployed_at" => "2009-02-03 03:00:00 -0500",
16
- "deployed_by" => "emmasax1",
17
16
  "pull_request_ids" => "33364992, 5870592, 33691392"})
18
17
  expect(assigns(:deploy).git_revision).to eq("c1a2b37")
19
18
  expect(assigns(:deploy).deployed_at).to eq("2009-02-03 03:00:00 -0500")
20
- expect(assigns(:deploy).deployed_by).to eq("emmasax1")
21
19
  expect(assigns(:deploy).repo_id).to eq(101010)
22
20
  expect(assigns(:pull_request_id_array)).to eq([33364992, 5870592, 33691392])
21
+ expect(assigns(:deploy).user_id).to eq(202020)
23
22
  expect(response).to have_http_status(200)
24
23
  end
25
24
 
26
25
  it 'should create a deploy without a deployed_at because nil time turns into current time' do
27
26
  post(:create, {"git_revision" => "c1a2b37",
28
- "repo_name" => "sportngin/ngin",
27
+ "repo_name" => "hub/hubstats",
29
28
  "deployed_at" => nil,
30
- "deployed_by" => "emmasax1",
31
29
  "pull_request_ids" => "33364992, 5870592, 33691392"})
32
30
  expect(assigns(:deploy).git_revision).to eq("c1a2b37")
33
- expect(assigns(:deploy).deployed_by).to eq("emmasax1")
34
31
  expect(assigns(:deploy).repo_id).to eq(101010)
35
32
  expect(assigns(:pull_request_id_array)).to eq([33364992, 5870592, 33691392])
33
+ expect(assigns(:deploy).user_id).to eq(202020)
36
34
  expect(response).to have_http_status(200)
37
35
  end
38
36
 
39
37
  it 'should NOT create a deploy without a git_revision' do
40
38
  post(:create, {"git_revision" => nil,
41
- "repo_name" => "sportngin/ngin",
39
+ "repo_name" => "hub/hubstats",
42
40
  "deployed_at" => "2009-02-03 03:00:00 -0500",
43
- "deployed_by" => "emmasax1",
44
41
  "pull_request_ids" => "33364992, 5870592, 33691392"})
45
42
  expect(response).to have_http_status(400)
46
43
  end
47
44
 
48
- it 'should NOT create a deploy without a deployed_by' do
45
+ it 'should create a deploy without a user_id' do
49
46
  post(:create, {"git_revision" => "c1a2b37",
50
- "repo_name" => "sportngin/ngin",
47
+ "repo_name" => "hub/hubstats",
51
48
  "deployed_at" => "2009-02-03 03:00:00 -0500",
52
- "deployed_by" => nil,
53
49
  "pull_request_ids" => "33364992, 5870592, 33691392"})
54
- expect(response).to have_http_status(400)
50
+ expect(response).to have_http_status(200)
55
51
  end
56
52
 
57
53
  it 'should NOT create a deploy without a repo_name' do
58
54
  post(:create, {"git_revision" => "c1a2b37",
59
55
  "repo_name" => nil,
60
56
  "deployed_at" => "2009-02-03 03:00:00 -0500",
61
- "deployed_by" => "emmasax1",
62
57
  "pull_request_ids" => "33364992, 5870592, 33691392"})
63
58
  expect(response).to have_http_status(400)
64
59
  end
65
60
 
66
61
  it 'should NOT create a deploy when given a non existing repo_name' do
67
62
  post(:create, {"git_revision" => "c1a2b37",
68
- "repo_name" => "sportngin/make_resourceful",
63
+ "repo_name" => "sportngin/example",
69
64
  "deployed_at" => "2009-02-03 03:00:00 -0500",
70
- "deployed_by" => "emmasax1",
71
65
  "pull_request_ids" => "33364992, 5870592, 33691392"})
72
66
  expect(response).to have_http_status(400)
73
67
  end
74
68
 
75
69
  it 'should NOT create a deploy without pull request ids' do
76
70
  post(:create, {"git_revision" => "c1a2b37",
77
- "repo_name" => "sportngin/make_resourceful",
71
+ "repo_name" => "hub/hubstats",
78
72
  "deployed_at" => "2009-02-03 03:00:00 -0500",
79
- "deployed_by" => "emmasax1",
80
73
  "pull_request_ids" => nil})
81
74
  expect(response).to have_http_status(400)
82
75
  end
83
76
 
84
77
  it 'should NOT create a deploy when given empty pull request ids' do
85
78
  post(:create, {"git_revision" => "c1a2b37",
86
- "repo_name" => "sportngin/make_resourceful",
79
+ "repo_name" => "hub/hubstats",
87
80
  "deployed_at" => "2009-02-03 03:00:00 -0500",
88
- "deployed_by" => "emmasax1",
89
81
  "pull_request_ids" => ""})
90
82
  expect(response).to have_http_status(400)
91
83
  end
84
+
85
+ it 'should NOT create a deploy when given something that are not pull request ids' do
86
+ post(:create, {"git_revision" => "c1a2b37",
87
+ "repo_name" => "hub/hubstats",
88
+ "deployed_at" => "2009-02-03 03:00:00 -0500",
89
+ "pull_request_ids" => "blah bleh blooh"})
90
+ expect(response).to have_http_status(400)
91
+ end
92
+
93
+ it 'should NOT create a deploy when given invalid pull request ids' do
94
+ post(:create, {"git_revision" => "c1a2b37",
95
+ "repo_name" => "hub/hubstats",
96
+ "deployed_at" => "2009-02-03 03:00:00 -0500",
97
+ "pull_request_ids" => "77, 81, 92"})
98
+ expect(response).to have_http_status(400)
99
+ end
92
100
  end
93
101
 
94
102
  describe "#index" do
@@ -101,15 +109,19 @@ module Hubstats
101
109
  deploy1 = create(:deploy, :git_revision => "c1a2b37",
102
110
  :repo_id => 101010,
103
111
  :deployed_at => "2009-02-03 03:00:00 -0500",
104
- :deployed_by => "emmasax1")
112
+ :user_id => 404040)
105
113
  deploy2 = create(:deploy, :git_revision => "kd9c102",
106
114
  :repo_id => 101010,
107
115
  :deployed_at => "2015-02-03 03:00:00 -0500",
108
- :deployed_by => "emmasax1")
116
+ :user_id => 303030)
109
117
  deploy3 = create(:deploy, :git_revision => "owk19sf",
110
118
  :repo_id => 101010,
111
119
  :deployed_at => "2011-02-03 03:00:00 -0500",
112
- :deployed_by => "emmasax1")
120
+ :user_id => 202020)
121
+ deploy4 = create(:deploy, :git_revision => "owk19sf",
122
+ :repo_id => 101010,
123
+ :deployed_at => "2011-02-03 03:00:00 -0500",
124
+ :user_id => nil)
113
125
  deploys_ordered = [deploy2, deploy3, deploy1]
114
126
  expect(Hubstats::Deploy).to receive_message_chain("group_by.order_with_timespan.paginate").and_return(deploys_ordered)
115
127
  get :index
@@ -127,8 +139,7 @@ module Hubstats
127
139
  it "should show the pull requests of the specific deploy" do
128
140
  deploy = create(:deploy, :git_revision => "c1a2b37",
129
141
  :repo_id => 101010,
130
- :deployed_at => "2009-02-03 03:00:00 -0500",
131
- :deployed_by => "emmasax1")
142
+ :deployed_at => "2009-02-03 03:00:00 -0500")
132
143
  get :show, id: deploy.id
133
144
  expect(assigns(:deploy)).to eq(deploy)
134
145
  expect(assigns(:deploy).repo_id).to eq(101010)
@@ -3,6 +3,13 @@ FactoryGirl.define do
3
3
  git_revision "3dis01"
4
4
  repo_id 101010
5
5
  deployed_at "2015-02-03 03:00:00 -0500"
6
- deployed_by "emmasax1"
6
+ user_id 202020
7
+ end
8
+
9
+ factory :deploy_no_user, :class => Hubstats::Deploy do
10
+ git_revision "3dis01"
11
+ repo_id 101010
12
+ deployed_at "2015-02-03 03:00:00 -0500"
13
+ user_id nil
7
14
  end
8
15
  end