Module: Inkwell::ActsAsInkwellCommunity::InstanceMethods
- Includes:
- Common, Constants
- Defined in:
- lib/acts_as_inkwell_community/base.rb
Instance Method Summary
collapse
Methods included from Common
#category_class, #check_post, #check_user, #community_class, #community_id_attr, #get_class_for_item_type, #get_item_type, #get_owner_type, #post_class, #user_class, #user_id_attr
Instance Method Details
#accept_invitation_request(options = {}) ⇒ Object
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
|
# File 'lib/acts_as_inkwell_community/base.rb', line 488
def accept_invitation_request(options = {})
options.symbolize_keys!
user = options[:user]
admin = options[:admin]
check_user user
check_user admin
raise "admin is not admin in this community" unless self.include_admin? admin
relation = ::Inkwell::CommunityUser.where( => self.id, user_id_attr => user.id).first
raise "this user is already in this community" if relation.active
raise "there is no invitation request for this user" unless relation.asked_invitation
self.add_user :user => user
self.invitation_count -= 1
self.save
end
|
#add_admin(options = {}) ⇒ Object
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
|
# File 'lib/acts_as_inkwell_community/base.rb', line 254
def add_admin(options = {})
options.symbolize_keys!
user = options[:user]
admin = options[:admin]
raise "user should be passed in params" unless user
raise "admin should be passed in params" unless admin
check_user user
check_user admin
relation = ::Inkwell::CommunityUser.where(user_id_attr => user.id, => self.id).first
raise "user should be in the community" unless relation
raise "user is already admin" if relation.is_admin
raise "admin is not admin" unless self.include_admin? admin
raise "user should be a member of this community" unless relation
if relation.muted
relation.muted = false
self.muted_count -= 1
end
unless relation.user_access == CommunityAccessLevels::WRITE
relation.user_access = CommunityAccessLevels::WRITE
self.writer_count += 1
end
relation.admin_level = admin_level_of(admin) + 1
relation.is_admin = true
relation.save
self.admin_count += 1
self.save
end
|
#add_post(options = {}) ⇒ Object
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
|
# File 'lib/acts_as_inkwell_community/base.rb', line 315
def add_post(options = {})
options.symbolize_keys!
user = options[:user]
post = options[:post]
raise "user should be passed in params" unless user
raise "user should be a member of community" unless self.include_user? user
raise "user is muted" if self.include_muted_user? user
raise "post should be passed in params" unless post
check_post post
user_id_attr = "#{::Inkwell::Engine::config.user_table.to_s.singularize}_id"
raise "user tried to add post of another user" unless post.send(user_id_attr) == user.id
raise "post is already added to this community" if post.communities_row.include? self.id
::Inkwell::BlogItem.create :owner_id => self.id, :owner_type => OwnerTypes::COMMUNITY, :item_id => post.id, :item_type => ItemTypes::POST
communities_ids = ActiveSupport::JSON.decode post.communities_ids
communities_ids << self.id
post.communities_ids = ActiveSupport::JSON.encode communities_ids
post.save
users_with_existing_items = [user.id]
::Inkwell::TimelineItem.where(:item_id => post.id, :item_type => ItemTypes::POST).each do |item|
users_with_existing_items << item.owner_id
item.has_many_sources = true
from_source = ActiveSupport::JSON.decode item.from_source
from_source << Hash['community_id' => self.id]
item.from_source = ActiveSupport::JSON.encode from_source
item.save
end
self.users_row.each do |uid|
next if users_with_existing_items.include? uid
::Inkwell::TimelineItem.create :item_id => post.id, :owner_id => uid, :owner_type => OwnerTypes::USER, :item_type => ItemTypes::POST,
:from_source => ActiveSupport::JSON.encode([Hash['community_id' => self.id]])
end
end
|
#add_user(options = {}) ⇒ Object
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
|
# File 'lib/acts_as_inkwell_community/base.rb', line 38
def add_user(options = {})
options.symbolize_keys!
user = options[:user]
check_user user
relation = ::Inkwell::CommunityUser.where(user_id_attr => user.id, => self.id).first
if relation
raise "this user is already in this community" if relation.active
raise "this user is banned" if relation.banned
relation.asked_invitation = false if relation.asked_invitation
relation.user_access = self.default_user_access
relation.active = true
relation.save
else
relation = ::Inkwell::CommunityUser.create user_id_attr => user.id, => self.id, :user_access => self.default_user_access, :active => true
end
self.user_count += 1
self.writer_count += 1 if relation.user_access == CommunityAccessLevels::WRITE
self.save
user. += 1
user.save
::Inkwell::BlogItem.where(:owner_id => self.id, :owner_type => OwnerTypes::COMMUNITY).order("created_at DESC").limit(10).each do |blog_item|
next if post_class.find(blog_item.item_id).send(user_id_attr) == user.id
item = ::Inkwell::TimelineItem.where(:item_id => blog_item.item_id, :item_type => blog_item.item_type, :owner_id => user.id, :owner_type => OwnerTypes::USER).first
if item
item.has_many_sources = true unless item.has_many_sources
sources = ActiveSupport::JSON.decode item.from_source
sources << Hash['community_id' => self.id]
item.from_source = ActiveSupport::JSON.encode sources
item.save
else
sources = [Hash['community_id' => self.id]]
::Inkwell::TimelineItem.create :item_id => blog_item.item_id, :item_type => blog_item.item_type, :owner_id => user.id, :owner_type => OwnerTypes::USER,
:from_source => ActiveSupport::JSON.encode(sources), :created_at => blog_item.created_at
end
end
end
|
#admin_level_of(admin) ⇒ Object
303
304
305
306
307
308
|
# File 'lib/acts_as_inkwell_community/base.rb', line 303
def admin_level_of(admin)
relation = ::Inkwell::CommunityUser.where(user_id_attr => admin.id, => self.id).first
raise "this user is not community member" unless relation
raise "admin is not admin" unless relation.is_admin
relation.admin_level
end
|
#admins_row ⇒ Object
461
462
463
464
465
466
467
468
|
# File 'lib/acts_as_inkwell_community/base.rb', line 461
def admins_row
relations = ::Inkwell::CommunityUser.where => self.id, :is_admin => true
result = []
relations.each do |rel|
result << rel.send(user_id_attr)
end
result
end
|
#ban_user(options = {}) ⇒ Object
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
|
# File 'lib/acts_as_inkwell_community/base.rb', line 192
def ban_user(options = {})
options.symbolize_keys!
user = options[:user]
admin = options[:admin]
raise "user should be passed in params" unless user
raise "admin should be passed in params" unless admin
check_user user
check_user admin
raise "admin is not admin" unless self.include_admin? admin
raise "admin has no permissions to ban this user" if (self.include_admin? user) && (admin_level_of(admin) >= admin_level_of(user))
relation = ::Inkwell::CommunityUser.where(user_id_attr => user.id, => self.id).first
raise "user should be a member of community or send invitation request to it" unless relation
raise "this user is already banned" if relation.banned
relation.banned = true
relation.active = false
if relation.asked_invitation
relation.asked_invitation = false
self.invitation_count -= 1
else
self.user_count -= 1
end
relation.save
self.banned_count += 1
self.save
end
|
#banned_row ⇒ Object
245
246
247
248
249
250
251
252
|
# File 'lib/acts_as_inkwell_community/base.rb', line 245
def banned_row
relations = ::Inkwell::CommunityUser.where => self.id, :banned => true
result = []
relations.each do |relation|
result << relation.send(user_id_attr)
end
result
end
|
#blogline(options = {}) ⇒ Object
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
|
# File 'lib/acts_as_inkwell_community/base.rb', line 387
def blogline(options = {})
options.symbolize_keys!
last_shown_obj_id = options[:last_shown_obj_id]
limit = options[:limit] || 10
for_user = options[:for_user]
category = options[:category]
if category
child_categories = ActiveSupport::JSON.decode category.child_ids
category_ids = [category.id] + child_categories
if last_shown_obj_id
blog_items_categories = ::Inkwell::BlogItemCategory.where(:category_id => category_ids).where("blog_item_created_at < ?", Inkwell::BlogItem.find(last_shown_obj_id).created_at).order("blog_item_created_at DESC").limit(limit)
else
blog_items_categories = ::Inkwell::BlogItemCategory.where(:category_id => category_ids).order("blog_item_created_at DESC").limit(limit)
end
blog_items_ids = []
blog_items_categories.each do |record|
blog_items_ids << record.blog_item_id
end
blog_items = ::Inkwell::BlogItem.where(:id => blog_items_ids, :owner_id => self.id, :owner_type => OwnerTypes::COMMUNITY).order("created_at DESC")
else
if last_shown_obj_id
blog_items = ::Inkwell::BlogItem.where(:owner_id => self.id, :owner_type => OwnerTypes::COMMUNITY).where("created_at < ?", Inkwell::BlogItem.find(last_shown_obj_id).created_at).order("created_at DESC").limit(limit)
else
blog_items = ::Inkwell::BlogItem.where(:owner_id => self.id, :owner_type => OwnerTypes::COMMUNITY).order("created_at DESC").limit(limit)
end
end
result = []
blog_items.each do |item|
if item.item_type == ItemTypes::COMMENT
blog_obj = ::Inkwell::Comment.find item.item_id
else
blog_obj = post_class.find item.item_id
end
blog_obj.item_id_in_line = item.id
blog_obj.is_reblog_in_blogline = item.is_reblog
if for_user
blog_obj.is_reblogged = for_user.reblog? blog_obj
blog_obj.is_favorited = for_user.favorite? blog_obj
end
result << blog_obj
end
result
end
|
#change_default_access_to_read ⇒ Object
544
545
546
547
548
549
|
# File 'lib/acts_as_inkwell_community/base.rb', line 544
def change_default_access_to_read
unless self.default_user_access == CommunityAccessLevels::READ
self.default_user_access = CommunityAccessLevels::READ
self.save
end
end
|
#change_default_access_to_write ⇒ Object
#create_category(options = {}) ⇒ Object
wrappers for category methods
597
598
599
600
601
602
|
# File 'lib/acts_as_inkwell_community/base.rb', line 597
def create_category(options = {})
options.symbolize_keys!
options[:owner_id] = self.id
options[:owner_type] = OwnerTypes::COMMUNITY
category_class.create options
end
|
#create_invitation_request(user) ⇒ Object
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
|
# File 'lib/acts_as_inkwell_community/base.rb', line 470
def create_invitation_request(user)
check_user user
relation = ::Inkwell::CommunityUser.where( => self.id, user_id_attr => user.id).first
if relation
raise "invitation request was already created" if relation.asked_invitation
raise "it is impossible to create request. user is banned in this community" if relation.banned
raise "user is already community member" if relation.active
raise "there is relation for user who is not member of community and he is not banned and not asked invitation to it"
end
raise "it is impossible to create request for public community" if self.public
::Inkwell::CommunityUser.create => self.id, user_id_attr => user.id, :asked_invitation => true, :active => false
self.invitation_count += 1
self.save
end
|
#get_categories ⇒ Object
604
605
606
|
# File 'lib/acts_as_inkwell_community/base.rb', line 604
def get_categories
category_class.get_categories_for :object => self, :type => OwnerTypes::COMMUNITY
end
|
#include_admin?(user) ⇒ Boolean
310
311
312
313
|
# File 'lib/acts_as_inkwell_community/base.rb', line 310
def include_admin?(user)
check_user user
::Inkwell::CommunityUser.exists? user_id_attr => user.id, => self.id, :is_admin => true, :active => true
end
|
#include_banned_user?(user) ⇒ Boolean
241
242
243
|
# File 'lib/acts_as_inkwell_community/base.rb', line 241
def include_banned_user?(user)
::Inkwell::CommunityUser.exists? :community_id => self.id, :user_id => user.id, :banned => true
end
|
#include_invitation_request?(user) ⇒ Boolean
523
524
525
526
|
# File 'lib/acts_as_inkwell_community/base.rb', line 523
def include_invitation_request?(user)
raise "invitations work only for private community. this community is public." if self.public
::Inkwell::CommunityUser.exists? => self.id, user_id_attr => user.id, :asked_invitation => true
end
|
#include_muted_user?(user) ⇒ Boolean
178
179
180
181
|
# File 'lib/acts_as_inkwell_community/base.rb', line 178
def include_muted_user?(user)
check_user user
::Inkwell::CommunityUser.exists? user_id_attr => user.id, => self.id, :muted => true, :active => true
end
|
#include_user?(user) ⇒ Boolean
126
127
128
129
|
# File 'lib/acts_as_inkwell_community/base.rb', line 126
def include_user?(user)
check_user user
::Inkwell::CommunityUser.exists? user_id_attr => user.id, => self.id, :active => true
end
|
#include_writer?(user) ⇒ Boolean
121
122
123
124
|
# File 'lib/acts_as_inkwell_community/base.rb', line 121
def include_writer?(user)
check_user user
::Inkwell::CommunityUser.exists? user_id_attr => user.id, => self.id, :user_access => CommunityAccessLevels::WRITE, :active => true
end
|
#invitations_row ⇒ Object
528
529
530
531
532
533
534
535
|
# File 'lib/acts_as_inkwell_community/base.rb', line 528
def invitations_row
relations = ::Inkwell::CommunityUser.where => self.id, :asked_invitation => true
result = []
relations.each do |relation|
result << relation.send(user_id_attr)
end
result
end
|
#mute_user(options = {}) ⇒ Object
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
|
# File 'lib/acts_as_inkwell_community/base.rb', line 131
def mute_user(options = {})
options.symbolize_keys!
user = options[:user]
admin = options[:admin]
raise "user should be passed in params" unless user
raise "admin should be passed in params" unless admin
check_user user
check_user admin
relation = ::Inkwell::CommunityUser.where(user_id_attr => user.id, => self.id).first
raise "admin is not admin" unless self.include_admin? admin
raise "user should be a member of this community" unless relation
raise "this user is already muted" if relation.muted
raise "it is impossible to mute yourself" if user == admin
raise "admin has no permissions to mute this user" if (relation.is_admin) && (admin_level_of(admin) >= relation.admin_level)
relation.muted = true
relation.save
self.muted_count += 1
self.save
end
|
#muted_row ⇒ Object
183
184
185
186
187
188
189
190
|
# File 'lib/acts_as_inkwell_community/base.rb', line 183
def muted_row
relations = ::Inkwell::CommunityUser.where => self.id, :muted => true
result = []
relations.each do |relation|
result << relation.send(user_id_attr)
end
result
end
|
#reader_count ⇒ Object
591
592
593
|
# File 'lib/acts_as_inkwell_community/base.rb', line 591
def reader_count
self.user_count - self.writer_count
end
|
#readers_row ⇒ Object
455
456
457
458
459
|
# File 'lib/acts_as_inkwell_community/base.rb', line 455
def readers_row
users_row = self.users_row
writers_row = self.writers_row
users_row - writers_row
end
|
#reject_invitation_request(options = {}) ⇒ Object
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
|
# File 'lib/acts_as_inkwell_community/base.rb', line 506
def reject_invitation_request(options = {})
options.symbolize_keys!
user = options[:user]
admin = options[:admin]
check_user user
check_user admin
relation = ::Inkwell::CommunityUser.where( => self.id, user_id_attr => user.id).first
raise "there is no invitation request for this user" unless relation || relation.asked_invitation
raise "admin is not admin in this community" unless self.include_admin? admin
relation.destroy
self.invitation_count -= 1
self.save
end
|
#remove_admin(options = {}) ⇒ Object
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
|
# File 'lib/acts_as_inkwell_community/base.rb', line 286
def remove_admin(options = {})
options.symbolize_keys!
user = options[:user]
admin = options[:admin]
raise "user should be passed in params" unless user
raise "admin should be passed in params" unless admin
raise "user is not admin" unless self.include_admin?(user)
raise "admin is not admin" unless self.include_admin?(admin)
raise "admin has no permissions to delete this user from admins" if (admin_level_of(admin) >= admin_level_of(user)) && (user != admin)
raise "community owner can not be removed from admins" if admin_level_of(user) == 0
::Inkwell::CommunityUser.where(user_id_attr => user.id, => self.id).update_all :is_admin => false, :admin_level => nil
self.admin_count -= 1
self.save
end
|
#remove_post(options = {}) ⇒ Object
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
|
# File 'lib/acts_as_inkwell_community/base.rb', line 351
def remove_post(options = {})
options.symbolize_keys!
user = options[:user]
post = options[:post]
raise "user should be passed in params" unless user
raise "user should be a member of community" unless self.include_user?(user)
raise "post should be passed in params" unless post
check_post post
user_class = Object.const_get ::Inkwell::Engine::config.user_table.to_s.singularize.capitalize
user_id_attr = "#{::Inkwell::Engine::config.user_table.to_s.singularize}_id"
if self.include_admin?(user)
post_owner = user_class.find post.send(user_id_attr)
raise "admin tries to remove post of another admin. not enough permissions" if
(self.include_admin? post_owner) && (self.admin_level_of(user) > self.admin_level_of(post_owner))
else
raise "user tried to remove post of another user" unless post.send(user_id_attr) == user.id
end
raise "post isn't in community" unless post.communities_row.include? self.id
::Inkwell::BlogItem.delete_all :owner_id => self.id, :owner_type => OwnerTypes::COMMUNITY, :item_id => post.id, :item_type => ItemTypes::POST
communities_ids = ActiveSupport::JSON.decode post.communities_ids
communities_ids.delete self.id
post.communities_ids = ActiveSupport::JSON.encode communities_ids
post.save
items = ::Inkwell::TimelineItem.where(:item_id => post.id, :item_type => ItemTypes::POST).where("from_source like '%{\"community_id\":#{self.id}%'")
items.where(:has_many_sources => false).delete_all
items.where(:has_many_sources => true).each do |item|
from_source = ActiveSupport::JSON.decode item.from_source
from_source.delete Hash['community_id' => self.id]
item.from_source = ActiveSupport::JSON.encode from_source
item.has_many_sources = false if from_source.size < 2
item.save
end
end
|
#remove_user(options = {}) ⇒ Object
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
|
# File 'lib/acts_as_inkwell_community/base.rb', line 82
def remove_user(options = {})
options.symbolize_keys!
user = options[:user]
admin = options[:admin]
return unless self.include_user? user
raise "admin is not admin" if admin && !self.include_admin?(admin)
if self.include_admin? user
raise "community owner can not be removed from his community" if self.admin_level_of(user) == 0
raise "admin has no permissions to delete this user from community" if (self.admin_level_of(user) <= self.admin_level_of(admin)) && (user != admin)
end
relation = ::Inkwell::CommunityUser.where(user_id_attr => user.id, => self.id).first
self.user_count -= 1
self.writer_count -= 1 if relation.user_access == CommunityAccessLevels::WRITE
self.admin_count -= 1 if relation.is_admin
self.muted_count -= 1 if relation.muted
self.save
user. -= 1
user.save
if relation.muted
relation.active = false
relation.save
else
relation.destroy
end
timeline_items = ::Inkwell::TimelineItem.where(:owner_id => user.id, :owner_type => OwnerTypes::USER).where "from_source like '%{\"community_id\":#{self.id}%'"
timeline_items.delete_all :has_many_sources => false
timeline_items.each do |item|
from_source = ActiveSupport::JSON.decode item.from_source
from_source.delete_if { |rec| rec['community_id'] == self.id }
item.from_source = ActiveSupport::JSON.encode from_source
item.has_many_sources = false if from_source.size < 2
item.save
end
end
|
#set_read_access(arr) ⇒ Object
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
|
# File 'lib/acts_as_inkwell_community/base.rb', line 571
def set_read_access(arr)
raise "array with users ids should be passed" unless arr.class == Array
raise "empty array passed in params" if arr.empty?
uids = []
if arr[0].is_a? user_class
arr.each do |user|
uids << user.id
end
else
uids = arr
end
relations = ::Inkwell::CommunityUser.where user_id_attr => uids, => self.id, :user_access => CommunityAccessLevels::WRITE, :is_admin => false
raise "there is different count of passed users (#{uids.size}) and found users (#{relations.size}) in this community" unless relations.size == uids.size
self.writer_count -= relations.size
self.save
relations.update_all :user_access => CommunityAccessLevels::READ
end
|
#set_write_access(arr) ⇒ Object
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
|
# File 'lib/acts_as_inkwell_community/base.rb', line 551
def set_write_access(arr)
raise "array with users objects or ids should be passed" unless arr.class == Array
raise "empty array passed in params" if arr.empty?
uids = []
if arr[0].is_a? user_class
arr.each do |user|
uids << user.id
end
else
uids = arr
end
relations = ::Inkwell::CommunityUser.where user_id_attr => uids, => self.id, :user_access => CommunityAccessLevels::READ, :is_admin => false
raise "there is different count of passed users (#{uids.size}) and found users (#{relations.size}) in this community" unless relations.size == uids.size
self.writer_count += relations.size
self.save
relations.update_all :user_access => CommunityAccessLevels::WRITE
end
|
#unban_user(options = {}) ⇒ Object
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
|
# File 'lib/acts_as_inkwell_community/base.rb', line 220
def unban_user(options = {})
options.symbolize_keys!
user = options[:user]
admin = options[:admin]
raise "user should be passed in params" unless user
raise "admin should be passed in params" unless admin
check_user user
check_user admin
raise "admin is not admin" unless self.include_admin? admin
relation = ::Inkwell::CommunityUser.where(user_id_attr => user.id, => self.id).first
raise "this user is not banned" unless relation || relation.banned
relation.banned = false
relation.active = true unless relation.asked_invitation
relation.save
self.banned_count -= 1
self.save
end
|
#unmute_user(options = {}) ⇒ Object
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
|
# File 'lib/acts_as_inkwell_community/base.rb', line 155
def unmute_user(options = {})
options.symbolize_keys!
user = options[:user]
admin = options[:admin]
raise "user should be passed in params" unless user
raise "admin should be passed in params" unless admin
check_user user
check_user admin
relation = ::Inkwell::CommunityUser.where(user_id_attr => user.id, => self.id).first
raise "admin is not admin" unless self.include_admin? admin
raise "user should be a member of this community" unless relation
raise "this user is not muted" unless relation.muted
raise "admin has no permissions to unmute this user" if (relation.is_admin) && (admin_level_of(admin) >= relation.admin_level)
relation.muted = false
relation.save
self.muted_count -= 1
self.save
end
|
#users_row ⇒ Object
437
438
439
440
441
442
443
444
|
# File 'lib/acts_as_inkwell_community/base.rb', line 437
def users_row
relations = ::Inkwell::CommunityUser.where => self.id
result = []
relations.each do |rel|
result << rel.send(user_id_attr)
end
result
end
|
#writers_row ⇒ Object
446
447
448
449
450
451
452
453
|
# File 'lib/acts_as_inkwell_community/base.rb', line 446
def writers_row
relations = ::Inkwell::CommunityUser.where => self.id, :user_access => CommunityAccessLevels::WRITE
result = []
relations.each do |rel|
result << rel.send(user_id_attr)
end
result
end
|