commontator 4.0.2 → 4.1.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/README.md +3 -5
- data/app/assets/stylesheets/commontator/comments.css +16 -5
- data/app/assets/stylesheets/commontator/comments.css~ +98 -0
- data/app/controllers/commontator/application_controller.rb +6 -3
- data/app/controllers/commontator/application_controller.rb~ +30 -0
- data/app/controllers/commontator/threads_controller.rb +2 -0
- data/app/controllers/commontator/threads_controller.rb~ +44 -0
- data/app/helpers/commontator/threads_helper.rb +1 -8
- data/app/helpers/commontator/threads_helper.rb~ +11 -0
- data/app/mailers/commontator/subscriptions_mailer.rb +2 -4
- data/app/mailers/commontator/subscriptions_mailer.rb~ +50 -0
- data/app/models/commontator/comment.rb +23 -19
- data/app/models/commontator/comment.rb~ +106 -0
- data/app/models/commontator/thread.rb +10 -10
- data/app/models/commontator/thread.rb~ +124 -0
- data/app/views/commontator/comments/_show.html.erb +36 -34
- data/app/views/commontator/comments/_show.html.erb~ +47 -0
- data/app/views/commontator/comments/_votes.html.erb +6 -2
- data/app/views/commontator/comments/_votes.html.erb~ +61 -0
- data/app/views/commontator/comments/delete.js.erb +2 -2
- data/app/views/commontator/comments/delete.js.erb~ +17 -0
- data/app/views/commontator/comments/update.js.erb +2 -2
- data/app/views/commontator/comments/update.js.erb~ +7 -0
- data/app/views/commontator/subscriptions_mailer/comment_created.html.erb +2 -2
- data/app/views/commontator/subscriptions_mailer/comment_created.html.erb~ +6 -0
- data/app/views/commontator/threads/_show.html.erb +3 -7
- data/app/views/commontator/threads/_show.html.erb~ +58 -0
- data/config/initializers/commontator.rb +52 -47
- data/config/initializers/commontator.rb~ +176 -0
- data/lib/commontator.rb +6 -7
- data/lib/commontator.rb~ +61 -0
- data/lib/commontator/controller_includes.rb +1 -3
- data/lib/commontator/controller_includes.rb~ +22 -0
- data/lib/commontator/shared_helper.rb +3 -8
- data/lib/commontator/shared_helper.rb~ +37 -0
- data/lib/commontator/version.rb +1 -1
- data/lib/commontator/version.rb~ +3 -0
- data/spec/app/controllers/commontator/comments_controller_spec.rb +64 -45
- data/spec/app/controllers/commontator/comments_controller_spec.rb~ +580 -0
- data/spec/app/controllers/commontator/subscriptions_controller_spec.rb +3 -3
- data/spec/app/controllers/commontator/subscriptions_controller_spec.rb~ +99 -0
- data/spec/app/controllers/commontator/threads_controller_spec.rb +15 -9
- data/spec/app/controllers/commontator/threads_controller_spec.rb~ +126 -0
- data/spec/app/helpers/commontator/application_helper_spec.rb +1 -1
- data/spec/app/helpers/commontator/application_helper_spec.rb~ +9 -0
- data/spec/app/helpers/commontator/threads_helper_spec.rb +1 -5
- data/spec/app/helpers/commontator/threads_helper_spec.rb~ +13 -0
- data/spec/app/models/commontator/comment_spec.rb +4 -3
- data/spec/app/models/commontator/comment_spec.rb~ +62 -0
- data/spec/dummy/config/application.rb +1 -1
- data/spec/dummy/config/application.rb~ +27 -0
- data/spec/dummy/config/initializers/commontator.rb +67 -55
- data/spec/dummy/config/initializers/commontator.rb~ +176 -0
- data/spec/dummy/config/initializers/commontator2.rb~ +169 -0
- data/spec/dummy/db/test.sqlite3 +0 -0
- data/spec/dummy/log/test.log +84489 -0
- data/spec/dummy/tmp/cache/assets/test/sprockets/02d4b791eb831cf2057bf4703a1218d1 +0 -0
- data/spec/dummy/tmp/cache/assets/test/sprockets/0f196a1a50363b0a076ec6e1ee5417f6 +0 -0
- data/spec/dummy/tmp/cache/assets/test/sprockets/a41c8be5379abec3c0d0d98e2f0d5609 +0 -0
- data/spec/dummy/tmp/cache/assets/test/sprockets/e1f674c11941d62aac1764ef3a7134e4 +0 -0
- data/spec/dummy/tmp/cache/assets/test/sprockets/e85565206c3e5fdf9dfeb367c85557b1 +0 -0
- data/spec/lib/commontator/commontable_config_spec.rb +1 -1
- data/spec/lib/commontator/commontable_config_spec.rb~ +26 -0
- data/spec/lib/commontator/commontator_config_spec.rb +5 -5
- data/spec/lib/commontator/commontator_config_spec.rb~ +26 -0
- data/spec/lib/commontator_spec.rb +6 -4
- data/spec/lib/commontator_spec.rb~ +28 -0
- data/spec/test_helper.rb +4 -4
- data/spec/test_helper.rb~ +37 -0
- metadata +46 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 44192c2ae74567abb05fcbb08a8f9035435f8bd5
|
4
|
+
data.tar.gz: d99e1f12e46fbbbdaeb601b994ed5427d7a1bf7c
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: b5fd3c18561bb75f2fe5590dc462c72efe8931b00a2eea4e6aace1411fa37477f816de90daa881d5248b4aa3b21e62653140ef1853142848ba3980beaa8da97b
|
7
|
+
data.tar.gz: 0833ec342a5393094e9557a142503ac91ae9cf8d4676521fe3321ea0add1c0e5bac3690bdafe714f9fa204009d7e72743285c874cdfa8fc67a238e381554e8ec
|
data/README.md
CHANGED
@@ -95,12 +95,10 @@ Follow the steps below to add commontator to your models and views:
|
|
95
95
|
Where commontable is an instance of some model that acts_as_commontable.
|
96
96
|
Note that model's record must already exist in the database, so do not use this in new.html.erb, _form.html.erb or similar.
|
97
97
|
We recommend you use this in the model's show.html.erb.
|
98
|
-
When you do this, it is up to you to ensure that the user has the proper permission
|
99
|
-
to read the thread or else a SecurityTransgression will be raised.
|
100
98
|
|
101
99
|
3. Controllers
|
102
100
|
|
103
|
-
Instead of linking to the thread, you might want to have the thread display right away
|
101
|
+
Instead of linking to the thread, you might want to have the thread display right away when the corresponding view page is loaded.
|
104
102
|
If that's the case, add the following to the controller action that displays the view where the thread is located:
|
105
103
|
|
106
104
|
```ruby
|
@@ -109,7 +107,7 @@ Follow the steps below to add commontator to your models and views:
|
|
109
107
|
|
110
108
|
Note that the above method also checks the current user's read permission on the thread.
|
111
109
|
It will raise a SecurityTransgression if the user is not allowed to read the thread.
|
112
|
-
You can specify the
|
110
|
+
You can specify the proc that determines which users are allowed to read which threads in the initializer.
|
113
111
|
|
114
112
|
That's it! Commontator is now ready for use.
|
115
113
|
|
@@ -132,7 +130,7 @@ Note that acts_as_votable is currently incompatible with the protected_attribute
|
|
132
130
|
## Browser Support
|
133
131
|
|
134
132
|
No incompatibilities are currently known with any of the major browsers.
|
135
|
-
|
133
|
+
Commontator requires javascript enabled to function properly.
|
136
134
|
|
137
135
|
## Customization
|
138
136
|
|
@@ -25,18 +25,21 @@
|
|
25
25
|
|
26
26
|
.comment_body {
|
27
27
|
margin-left: 55px;
|
28
|
-
margin-top: -60px;
|
29
28
|
margin-right: 45px;
|
30
|
-
|
29
|
+
|
31
30
|
padding: 8px;
|
32
31
|
}
|
33
32
|
|
34
33
|
.comment_body p {
|
35
34
|
margin: 0px;
|
36
|
-
|
35
|
+
|
37
36
|
overflow: hidden;
|
38
37
|
}
|
39
38
|
|
39
|
+
.comment_div {
|
40
|
+
clear: both;
|
41
|
+
}
|
42
|
+
|
40
43
|
.comment_form_actions {
|
41
44
|
margin-top: 15px;
|
42
45
|
}
|
@@ -48,16 +51,20 @@
|
|
48
51
|
|
49
52
|
.comment_form_field textarea {
|
50
53
|
padding: 0px;
|
51
|
-
|
54
|
+
|
52
55
|
width: 100%;
|
53
56
|
}
|
54
57
|
|
55
|
-
.comment_gravatar_image
|
58
|
+
.comment_gravatar_image {
|
59
|
+
float: left;
|
60
|
+
|
56
61
|
margin-top: 5px;
|
62
|
+
margin-bottom: 5px;
|
57
63
|
}
|
58
64
|
|
59
65
|
.comment_timestamp {
|
60
66
|
color: #777;
|
67
|
+
display: inline-block;
|
61
68
|
}
|
62
69
|
|
63
70
|
.comment_votes {
|
@@ -74,6 +81,10 @@
|
|
74
81
|
margin: 0px;
|
75
82
|
}
|
76
83
|
|
84
|
+
.comment_votes form {
|
85
|
+
margin: 0px;
|
86
|
+
}
|
87
|
+
|
77
88
|
.comment_vote_count p {
|
78
89
|
margin: 0px;
|
79
90
|
}
|
@@ -0,0 +1,98 @@
|
|
1
|
+
.comment {
|
2
|
+
font-size: 12px;
|
3
|
+
font-weight: normal;
|
4
|
+
font-style: normal;
|
5
|
+
|
6
|
+
border-top: 1px solid;
|
7
|
+
border-left: 1px solid;
|
8
|
+
|
9
|
+
margin-top: 15px;
|
10
|
+
margin-bottom: 15px;
|
11
|
+
|
12
|
+
padding-top: 8px;
|
13
|
+
padding-left: 15px;
|
14
|
+
|
15
|
+
color: #000;
|
16
|
+
border-color: #ddd;
|
17
|
+
background-color: #fff;
|
18
|
+
|
19
|
+
clear: both;
|
20
|
+
}
|
21
|
+
|
22
|
+
.comment_actions {
|
23
|
+
float: right;
|
24
|
+
}
|
25
|
+
|
26
|
+
.comment_body {
|
27
|
+
margin-left: 55px;
|
28
|
+
margin-right: 45px;
|
29
|
+
|
30
|
+
padding: 8px;
|
31
|
+
}
|
32
|
+
|
33
|
+
.comment_body p {
|
34
|
+
margin: 0px;
|
35
|
+
|
36
|
+
overflow: hidden;
|
37
|
+
}
|
38
|
+
|
39
|
+
.comment_div {
|
40
|
+
clear: both;
|
41
|
+
}
|
42
|
+
|
43
|
+
.comment_form_actions {
|
44
|
+
margin-top: 15px;
|
45
|
+
}
|
46
|
+
|
47
|
+
.comment_form_field > .field_with_errors {
|
48
|
+
display: block;
|
49
|
+
padding-right: 4px;
|
50
|
+
}
|
51
|
+
|
52
|
+
.comment_form_field textarea {
|
53
|
+
padding: 0px;
|
54
|
+
|
55
|
+
width: 100%;
|
56
|
+
}
|
57
|
+
|
58
|
+
.comment_gravatar_image {
|
59
|
+
float: left;
|
60
|
+
|
61
|
+
margin-top: 5px;
|
62
|
+
margin-bottom: 5px;
|
63
|
+
}
|
64
|
+
|
65
|
+
.comment_timestamp {
|
66
|
+
color: #777;
|
67
|
+
display: inline-block;
|
68
|
+
}
|
69
|
+
|
70
|
+
.comment_votes {
|
71
|
+
float: right;
|
72
|
+
|
73
|
+
text-align: center;
|
74
|
+
}
|
75
|
+
|
76
|
+
.comment_votes input,
|
77
|
+
.comment_votes img {
|
78
|
+
border: none;
|
79
|
+
background-color: transparent;
|
80
|
+
padding: 0px;
|
81
|
+
margin: 0px;
|
82
|
+
}
|
83
|
+
|
84
|
+
.comment_votes form {
|
85
|
+
border: none;
|
86
|
+
background-color: transparent;
|
87
|
+
padding: 0px;
|
88
|
+
margin: 0px;
|
89
|
+
}
|
90
|
+
|
91
|
+
.comment_vote_count p {
|
92
|
+
margin: 0px;
|
93
|
+
}
|
94
|
+
|
95
|
+
.comment_votes span {
|
96
|
+
padding: 0px;
|
97
|
+
margin: 0px;
|
98
|
+
}
|
@@ -1,6 +1,6 @@
|
|
1
1
|
module Commontator
|
2
2
|
class ApplicationController < ActionController::Base
|
3
|
-
before_filter :get_user
|
3
|
+
before_filter :get_user, :ensure_user
|
4
4
|
|
5
5
|
cattr_accessor :commontable_url
|
6
6
|
|
@@ -9,8 +9,11 @@ module Commontator
|
|
9
9
|
protected
|
10
10
|
|
11
11
|
def get_user
|
12
|
-
@user =
|
13
|
-
|
12
|
+
@user = Commontator.current_user_proc.call(self)
|
13
|
+
end
|
14
|
+
|
15
|
+
def ensure_user
|
16
|
+
raise SecurityTransgression unless (@user && @user.is_commontator)
|
14
17
|
end
|
15
18
|
|
16
19
|
def get_thread
|
@@ -0,0 +1,30 @@
|
|
1
|
+
module Commontator
|
2
|
+
class ApplicationController < ActionController::Base
|
3
|
+
before_filter :get_user, :ensure_user
|
4
|
+
|
5
|
+
cattr_accessor :commontable_url
|
6
|
+
|
7
|
+
rescue_from SecurityTransgression, :with => lambda { head(:forbidden) }
|
8
|
+
|
9
|
+
protected
|
10
|
+
|
11
|
+
def get_user
|
12
|
+
@user = self.send Commontator.current_user_method
|
13
|
+
end
|
14
|
+
|
15
|
+
def ensure_user
|
16
|
+
raise SecurityTransgression unless (@user && @user.is_commontator)
|
17
|
+
end
|
18
|
+
|
19
|
+
def get_thread
|
20
|
+
@thread = params[:thread_id].blank? ? \
|
21
|
+
Commontator::Thread.find(params[:id]) : \
|
22
|
+
Commontator::Thread.find(params[:thread_id])
|
23
|
+
raise SecurityTransgression if @thread.commontable.nil?
|
24
|
+
end
|
25
|
+
|
26
|
+
def set_commontable_url
|
27
|
+
self.commontable_url = @thread.config.commontable_url_proc.call(main_app, @thread.commontable)
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
@@ -0,0 +1,44 @@
|
|
1
|
+
module Commontator
|
2
|
+
class ThreadsController < Commontator::ApplicationController
|
3
|
+
skip_before_filter :ensure_user, :only => :index
|
4
|
+
|
5
|
+
before_filter :get_thread
|
6
|
+
before_filter :set_commontable_url, :only => :show
|
7
|
+
|
8
|
+
# GET /threads/1
|
9
|
+
def show
|
10
|
+
commontator_thread_show(@thread.commontable)
|
11
|
+
|
12
|
+
respond_to do |format|
|
13
|
+
format.html { redirect_to commontable_url }
|
14
|
+
format.js
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
# PUT /threads/1/close
|
19
|
+
def close
|
20
|
+
raise SecurityTransgression unless @thread.can_be_edited_by?(@user)
|
21
|
+
|
22
|
+
@thread.errors.add(:base, 'This thread has already been closed.') \
|
23
|
+
unless @thread.close(@user)
|
24
|
+
|
25
|
+
respond_to do |format|
|
26
|
+
format.html { redirect_to @thread }
|
27
|
+
format.js { render :show }
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
# PUT /threads/1/reopen
|
32
|
+
def reopen
|
33
|
+
raise SecurityTransgression unless @thread.can_be_edited_by?(@user)
|
34
|
+
|
35
|
+
@thread.errors.add(:base, 'This thread is not closed.') \
|
36
|
+
unless @thread.reopen
|
37
|
+
|
38
|
+
respond_to do |format|
|
39
|
+
format.html { redirect_to @thread }
|
40
|
+
format.js { render :show }
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
@@ -1,14 +1,7 @@
|
|
1
1
|
module Commontator
|
2
2
|
module ThreadsHelper
|
3
3
|
def commontable_name(thread)
|
4
|
-
config
|
5
|
-
config.commontable_name.blank? ? \
|
6
|
-
thread.commontable.class.name : \
|
7
|
-
config.commontable_name
|
8
|
-
end
|
9
|
-
|
10
|
-
def commontable_id(thread)
|
11
|
-
thread.commontable.send(thread.config.commontable_id_method)
|
4
|
+
thread.config.commontable_name_proc.call(thread.commontable)
|
12
5
|
end
|
13
6
|
end
|
14
7
|
end
|
@@ -23,10 +23,9 @@ module Commontator
|
|
23
23
|
@config = @thread.config
|
24
24
|
|
25
25
|
@creator_name = commontator_name(@creator)
|
26
|
-
@
|
26
|
+
@comment_created_timestamp = @comment.created_timestamp
|
27
27
|
|
28
28
|
@commontable_name = commontable_name(@thread)
|
29
|
-
@commontable_id = commontable_id(@thread).to_s
|
30
29
|
|
31
30
|
@commontable_url = ApplicationController.commontable_url
|
32
31
|
|
@@ -37,9 +36,8 @@ module Commontator
|
|
37
36
|
params[:commontable] = @commontable
|
38
37
|
params[:config] = @config
|
39
38
|
params[:creator_name] = @creator_name
|
40
|
-
params[:
|
39
|
+
params[:comment_created_timestamp] = @comment_created_timestamp
|
41
40
|
params[:commontable_name] = @commontable_name
|
42
|
-
params[:commontable_id] = @commontable_id
|
43
41
|
params[:commontable_url] = @commontable_url
|
44
42
|
|
45
43
|
@bcc = recipients.collect{|s| commontator_email(s)}
|
@@ -0,0 +1,50 @@
|
|
1
|
+
module Commontator
|
2
|
+
class SubscriptionsMailer < ActionMailer::Base
|
3
|
+
include SharedHelper
|
4
|
+
include ThreadsHelper
|
5
|
+
|
6
|
+
def comment_created(comment, recipients)
|
7
|
+
setup_variables(comment, recipients)
|
8
|
+
|
9
|
+
mail :to => 'Undisclosed Recipients',
|
10
|
+
:bcc => @bcc,
|
11
|
+
:from => @from,
|
12
|
+
:subject => @subject
|
13
|
+
end
|
14
|
+
|
15
|
+
protected
|
16
|
+
|
17
|
+
def setup_variables(comment, recipients)
|
18
|
+
@comment = comment
|
19
|
+
@thread = @comment.thread
|
20
|
+
@creator = @comment.creator
|
21
|
+
|
22
|
+
@commontable = @thread.commontable
|
23
|
+
@config = @thread.config
|
24
|
+
|
25
|
+
@creator_name = commontator_name(@creator)
|
26
|
+
@comment_created_timestamp = @comment.created_timestamp
|
27
|
+
|
28
|
+
@commontable_name = commontable_name(@thread)
|
29
|
+
@commontable_id = commontable_id(@thread).to_s
|
30
|
+
|
31
|
+
@commontable_url = ApplicationController.commontable_url
|
32
|
+
|
33
|
+
params = Hash.new
|
34
|
+
params[:comment] = @comment
|
35
|
+
params[:thread] = @thread
|
36
|
+
params[:creator] = @creator
|
37
|
+
params[:commontable] = @commontable
|
38
|
+
params[:config] = @config
|
39
|
+
params[:creator_name] = @creator_name
|
40
|
+
params[:comment_created_timestamp] = @comment_created_timestamp
|
41
|
+
params[:commontable_name] = @commontable_name
|
42
|
+
params[:commontable_id] = @commontable_id
|
43
|
+
params[:commontable_url] = @commontable_url
|
44
|
+
|
45
|
+
@bcc = recipients.collect{|s| commontator_email(s)}
|
46
|
+
@from = @config.subscription_email_from_proc.call(params)
|
47
|
+
@subject = @config.subscription_email_subject_proc.call(params)
|
48
|
+
end
|
49
|
+
end
|
50
|
+
end
|
@@ -28,7 +28,7 @@ module Commontator
|
|
28
28
|
end
|
29
29
|
|
30
30
|
def get_vote_by(user)
|
31
|
-
return nil unless is_votable?
|
31
|
+
return nil unless is_votable? && user && user.is_commontator
|
32
32
|
votes.where(:voter_type => user.class.name, :voter_id => user.id).first
|
33
33
|
end
|
34
34
|
|
@@ -54,12 +54,16 @@ module Commontator
|
|
54
54
|
self.save
|
55
55
|
end
|
56
56
|
|
57
|
-
def
|
57
|
+
def created_timestamp
|
58
58
|
config = thread.config
|
59
59
|
"#{config.comment_create_verb_past.capitalize} on " + \
|
60
|
-
created_at.strftime(config.timestamp_format)
|
61
|
-
|
62
|
-
|
60
|
+
created_at.strftime(config.timestamp_format)
|
61
|
+
end
|
62
|
+
|
63
|
+
def updated_timestamp
|
64
|
+
config = thread.config
|
65
|
+
is_modified? ? ("Last #{config.comment_edit_verb_past} on " + \
|
66
|
+
updated_at.strftime(config.timestamp_format)) : ''
|
63
67
|
end
|
64
68
|
|
65
69
|
##################
|
@@ -67,28 +71,28 @@ module Commontator
|
|
67
71
|
##################
|
68
72
|
|
69
73
|
def can_be_read_by?(user)
|
70
|
-
(thread.
|
71
|
-
|
72
|
-
|
74
|
+
((!is_deleted? || thread.config.deleted_comments_are_visible) &&\
|
75
|
+
thread.can_be_read_by?(user)) ||\
|
76
|
+
thread.can_be_edited_by?(user)
|
73
77
|
end
|
74
78
|
|
75
79
|
def can_be_created_by?(user)
|
76
|
-
!thread.is_closed? && thread.can_be_read_by?(user)
|
80
|
+
!thread.is_closed? && user == creator && thread.can_be_read_by?(user)
|
77
81
|
end
|
78
82
|
|
79
83
|
def can_be_edited_by?(user)
|
80
|
-
!thread.is_closed? && !is_deleted? &&\
|
81
|
-
(
|
82
|
-
|
83
|
-
|
84
|
+
(!thread.is_closed? && !is_deleted? &&\
|
85
|
+
(thread.comments.last == self || thread.config.can_edit_old_comments) &&\
|
86
|
+
user == creator && thread.config.can_edit_own_comments && thread.can_be_read_by?(user)) ||\
|
87
|
+
(thread.config.admin_can_edit_comments && thread.can_be_edited_by?(user))
|
84
88
|
end
|
85
89
|
|
86
90
|
def can_be_deleted_by?(user)
|
87
|
-
(!thread.is_closed? &&\
|
88
|
-
(
|
89
|
-
|
90
|
-
|
91
|
-
|
91
|
+
(!thread.is_closed? && (!is_deleted? || editor == user) &&\
|
92
|
+
(thread.comments.last == self || thread.config.can_delete_old_comments) &&\
|
93
|
+
user == creator && thread.config.can_delete_own_comments &&\
|
94
|
+
thread.can_be_read_by?(user)) ||\
|
95
|
+
thread.can_be_edited_by?(user)
|
92
96
|
end
|
93
97
|
|
94
98
|
def can_be_voted_on?
|
@@ -96,7 +100,7 @@ module Commontator
|
|
96
100
|
end
|
97
101
|
|
98
102
|
def can_be_voted_on_by?(user)
|
99
|
-
can_be_voted_on? &&
|
103
|
+
can_be_voted_on? && user && user.is_commontator && user != creator && thread.can_be_read_by?(user)
|
100
104
|
end
|
101
105
|
end
|
102
106
|
end
|