t 0.4.0 → 0.5.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
data/t.gemspec CHANGED
@@ -6,9 +6,9 @@ Gem::Specification.new do |gem|
6
6
  gem.add_dependency 'activesupport', ['>= 2.3.11', '< 4']
7
7
  gem.add_dependency 'launchy', '~> 2.0'
8
8
  gem.add_dependency 'geokit', '~> 1.6'
9
+ gem.add_dependency 'highline', '~> 1.6'
10
+ gem.add_dependency 'json', '~> 1.6'
9
11
  gem.add_dependency 'oauth', '~> 0.4'
10
- gem.add_dependency 'oj', '~> 1.2'
11
- gem.add_dependency 'pager', '~> 1.0'
12
12
  gem.add_dependency 'retryable', '~> 1.2'
13
13
  gem.add_dependency 'thor', '~> 0.15.0.rc2'
14
14
  gem.add_dependency 'twitter', '~> 2.2'
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: t
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.4.0
4
+ version: 0.5.0
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2012-03-30 00:00:00.000000000 Z
12
+ date: 2012-04-22 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: actionpack
@@ -88,13 +88,13 @@ dependencies:
88
88
  - !ruby/object:Gem::Version
89
89
  version: '1.6'
90
90
  - !ruby/object:Gem::Dependency
91
- name: oauth
91
+ name: highline
92
92
  requirement: !ruby/object:Gem::Requirement
93
93
  none: false
94
94
  requirements:
95
95
  - - ~>
96
96
  - !ruby/object:Gem::Version
97
- version: '0.4'
97
+ version: '1.6'
98
98
  type: :runtime
99
99
  prerelease: false
100
100
  version_requirements: !ruby/object:Gem::Requirement
@@ -102,15 +102,15 @@ dependencies:
102
102
  requirements:
103
103
  - - ~>
104
104
  - !ruby/object:Gem::Version
105
- version: '0.4'
105
+ version: '1.6'
106
106
  - !ruby/object:Gem::Dependency
107
- name: oj
107
+ name: json
108
108
  requirement: !ruby/object:Gem::Requirement
109
109
  none: false
110
110
  requirements:
111
111
  - - ~>
112
112
  - !ruby/object:Gem::Version
113
- version: '1.2'
113
+ version: '1.6'
114
114
  type: :runtime
115
115
  prerelease: false
116
116
  version_requirements: !ruby/object:Gem::Requirement
@@ -118,15 +118,15 @@ dependencies:
118
118
  requirements:
119
119
  - - ~>
120
120
  - !ruby/object:Gem::Version
121
- version: '1.2'
121
+ version: '1.6'
122
122
  - !ruby/object:Gem::Dependency
123
- name: pager
123
+ name: oauth
124
124
  requirement: !ruby/object:Gem::Requirement
125
125
  none: false
126
126
  requirements:
127
127
  - - ~>
128
128
  - !ruby/object:Gem::Version
129
- version: '1.0'
129
+ version: '0.4'
130
130
  type: :runtime
131
131
  prerelease: false
132
132
  version_requirements: !ruby/object:Gem::Requirement
@@ -134,7 +134,7 @@ dependencies:
134
134
  requirements:
135
135
  - - ~>
136
136
  - !ruby/object:Gem::Version
137
- version: '1.0'
137
+ version: '0.4'
138
138
  - !ruby/object:Gem::Dependency
139
139
  name: retryable
140
140
  requirement: !ruby/object:Gem::Requirement
@@ -296,29 +296,18 @@ files:
296
296
  - bin/t
297
297
  - lib/t.rb
298
298
  - lib/t/cli.rb
299
- - lib/t/cli/delete.rb
300
- - lib/t/cli/follow.rb
301
- - lib/t/cli/list.rb
302
- - lib/t/cli/list/add.rb
303
- - lib/t/cli/list/remove.rb
304
- - lib/t/cli/search.rb
305
- - lib/t/cli/set.rb
306
- - lib/t/cli/unfollow.rb
307
299
  - lib/t/collectable.rb
308
300
  - lib/t/core_ext/enumerable.rb
309
301
  - lib/t/core_ext/string.rb
302
+ - lib/t/delete.rb
303
+ - lib/t/list.rb
310
304
  - lib/t/rcfile.rb
311
305
  - lib/t/requestable.rb
306
+ - lib/t/search.rb
307
+ - lib/t/set.rb
312
308
  - lib/t/version.rb
313
- - spec/cli/delete_spec.rb
314
- - spec/cli/follow_spec.rb
315
- - spec/cli/list/add_spec.rb
316
- - spec/cli/list/remove_spec.rb
317
- - spec/cli/list_spec.rb
318
- - spec/cli/search_spec.rb
319
- - spec/cli/set_spec.rb
320
- - spec/cli/unfollow_spec.rb
321
309
  - spec/cli_spec.rb
310
+ - spec/delete_spec.rb
322
311
  - spec/fixtures/.trc
323
312
  - spec/fixtures/501_ids.json
324
313
  - spec/fixtures/501_users_list.json
@@ -340,10 +329,14 @@ files:
340
329
  - spec/fixtures/sferik.json
341
330
  - spec/fixtures/status.json
342
331
  - spec/fixtures/statuses.json
332
+ - spec/fixtures/users.json
343
333
  - spec/fixtures/users_list.json
344
334
  - spec/fixtures/xml.gp
345
335
  - spec/helper.rb
336
+ - spec/list_spec.rb
346
337
  - spec/rcfile_spec.rb
338
+ - spec/search_spec.rb
339
+ - spec/set_spec.rb
347
340
  - t.gemspec
348
341
  homepage: http://github.com/sferik/t
349
342
  licenses: []
@@ -365,20 +358,13 @@ required_rubygems_version: !ruby/object:Gem::Requirement
365
358
  version: 1.3.6
366
359
  requirements: []
367
360
  rubyforge_project:
368
- rubygems_version: 1.8.21
361
+ rubygems_version: 1.8.23
369
362
  signing_key:
370
363
  specification_version: 3
371
364
  summary: CLI for Twitter
372
365
  test_files:
373
- - spec/cli/delete_spec.rb
374
- - spec/cli/follow_spec.rb
375
- - spec/cli/list/add_spec.rb
376
- - spec/cli/list/remove_spec.rb
377
- - spec/cli/list_spec.rb
378
- - spec/cli/search_spec.rb
379
- - spec/cli/set_spec.rb
380
- - spec/cli/unfollow_spec.rb
381
366
  - spec/cli_spec.rb
367
+ - spec/delete_spec.rb
382
368
  - spec/fixtures/.trc
383
369
  - spec/fixtures/501_ids.json
384
370
  - spec/fixtures/501_users_list.json
@@ -400,8 +386,12 @@ test_files:
400
386
  - spec/fixtures/sferik.json
401
387
  - spec/fixtures/status.json
402
388
  - spec/fixtures/statuses.json
389
+ - spec/fixtures/users.json
403
390
  - spec/fixtures/users_list.json
404
391
  - spec/fixtures/xml.gp
405
392
  - spec/helper.rb
393
+ - spec/list_spec.rb
406
394
  - spec/rcfile_spec.rb
395
+ - spec/search_spec.rb
396
+ - spec/set_spec.rb
407
397
  has_rdoc:
data/lib/t/cli/delete.rb DELETED
@@ -1,85 +0,0 @@
1
- require 't/core_ext/string'
2
- require 't/rcfile'
3
- require 't/requestable'
4
- require 'thor'
5
-
6
- module T
7
- class CLI
8
- class Delete < Thor
9
- include T::Requestable
10
-
11
- check_unknown_options!
12
-
13
- def initialize(*)
14
- super
15
- @rcfile = RCFile.instance
16
- end
17
-
18
- desc "block SCREEN_NAME", "Unblock a user."
19
- def block(screen_name)
20
- screen_name = screen_name.strip_at
21
- user = client.unblock(screen_name, :include_entities => false)
22
- say "@#{@rcfile.default_profile[0]} unblocked @#{user.screen_name}."
23
- say
24
- say "Run `#{File.basename($0)} block #{user.screen_name}` to block."
25
- end
26
-
27
- desc "dm", "Delete the last Direct Message sent."
28
- def dm
29
- direct_message = client.direct_messages_sent(:count => 1, :include_entities => false).first
30
- if direct_message
31
- unless parent_options['force']
32
- return unless yes? "Are you sure you want to permanently delete the direct message to @#{direct_message.recipient.screen_name}: \"#{direct_message.text}\"?"
33
- end
34
- direct_message = client.direct_message_destroy(direct_message.id, :include_entities => false)
35
- say "@#{direct_message.sender.screen_name} deleted the direct message sent to @#{direct_message.recipient.screen_name}: \"#{direct_message.text}\""
36
- else
37
- raise Thor::Error, "Direct Message not found"
38
- end
39
- end
40
- map %w(m) => :dm
41
-
42
- desc "favorite", "Deletes the last favorite."
43
- def favorite
44
- status = client.favorites(:count => 1, :include_entities => false).first
45
- if status
46
- unless parent_options['force']
47
- return unless yes? "Are you sure you want to delete the favorite of @#{status.user.screen_name}'s latest status: \"#{status.text}\"?"
48
- end
49
- client.unfavorite(status.id, :include_entities => false)
50
- say "@#{@rcfile.default_profile[0]} unfavorited @#{status.user.screen_name}'s latest status: \"#{status.text}\""
51
- say
52
- say "Run `#{File.basename($0)} favorite #{status.user.screen_name}` to favorite."
53
- else
54
- raise Thor::Error, "Tweet not found"
55
- end
56
- end
57
- map %w(fave) => :favorite
58
-
59
- desc "list LIST_NAME", "Delete a list."
60
- def list(list_name)
61
- unless parent_options['force']
62
- return unless yes? "Are you sure you want to permanently delete the list \"#{list_name}\"?"
63
- end
64
- status = client.list_destroy(list_name)
65
- say "@#{@rcfile.default_profile[0]} deleted the list \"#{list_name}\"."
66
- end
67
-
68
- desc "status", "Delete a Tweet."
69
- def status
70
- user = client.user(:include_entities => false)
71
- if user.status
72
- unless parent_options['force']
73
- return unless yes? "Are you sure you want to permanently delete @#{@rcfile.default_profile[0]}'s latest status: \"#{user.status.text}\"?"
74
- end
75
- status = client.status_destroy(user.status.id, :include_entities => false, :trim_user => true)
76
- say "@#{@rcfile.default_profile[0]} deleted the status: \"#{status.text}\""
77
- else
78
- raise Thor::Error, "Tweet not found"
79
- end
80
- end
81
- map %w(post tweet update) => :status
82
-
83
- end
84
- end
85
- end
data/lib/t/cli/follow.rb DELETED
@@ -1,78 +0,0 @@
1
- require 'retryable'
2
- require 't/core_ext/enumerable'
3
- require 't/core_ext/string'
4
- require 't/collectable'
5
- require 't/rcfile'
6
- require 't/requestable'
7
- require 'thor'
8
-
9
- module T
10
- class CLI
11
- class Follow < Thor
12
- include T::Collectable
13
- include T::Requestable
14
-
15
- check_unknown_options!
16
-
17
- def initialize(*)
18
- super
19
- @rcfile = RCFile.instance
20
- end
21
-
22
- desc "followers", "Follow all followers."
23
- def followers
24
- follower_ids = collect_with_cursor do |cursor|
25
- client.follower_ids(:cursor => cursor)
26
- end
27
- friend_ids = collect_with_cursor do |cursor|
28
- client.friend_ids(:cursor => cursor)
29
- end
30
- follow_ids = (follower_ids - friend_ids)
31
- number = follow_ids.length
32
- return say "@#{@rcfile.default_profile[0]} is already following all followers." if number.zero?
33
- return unless yes? "Are you sure you want to follow #{number} #{number == 1 ? 'user' : 'users'}?"
34
- screen_names = follow_ids.threaded_map do |follow_id|
35
- retryable(:tries => 3, :on => Twitter::Error::ServerError, :sleep => 0) do
36
- client.follow(follow_id, :include_entities => false)
37
- end
38
- end
39
- say "@#{@rcfile.default_profile[0]} is now following #{number} more #{number == 1 ? 'user' : 'users'}."
40
- say
41
- say "Run `#{File.basename($0)} unfollow all followers` to stop."
42
- end
43
-
44
- desc "listed LIST_NAME", "Follow all members of a list."
45
- def listed(list_name)
46
- list_member_collection = collect_with_cursor do |cursor|
47
- client.list_members(list_name, :cursor => cursor, :skip_status => true, :include_entities => false)
48
- end
49
- number = list_member_collection.length
50
- return say "@#{@rcfile.default_profile[0]} is already following all list members." if number.zero?
51
- return unless yes? "Are you sure you want to follow #{number} #{number == 1 ? 'user' : 'users'}?"
52
- list_member_collection.threaded_map do |list_member|
53
- retryable(:tries => 3, :on => Twitter::Error::ServerError, :sleep => 0) do
54
- client.follow(list_member.id, :include_entities => false)
55
- end
56
- end
57
- say "@#{@rcfile.default_profile[0]} is now following #{number} more #{number == 1 ? 'user' : 'users'}."
58
- say
59
- say "Run `#{File.basename($0)} unfollow all listed #{list_name}` to stop."
60
- end
61
-
62
- desc "users SCREEN_NAME [SCREEN_NAME...]", "Allows you to start following users."
63
- def users(screen_name, *screen_names)
64
- screen_names.unshift(screen_name)
65
- screen_names.threaded_map do |screen_name|
66
- retryable(:tries => 3, :on => Twitter::Error::ServerError, :sleep => 0) do
67
- client.follow(screen_name, :include_entities => false)
68
- end
69
- end
70
- number = screen_names.length
71
- say "@#{@rcfile.default_profile[0]} is now following #{number} more #{number == 1 ? 'user' : 'users'}."
72
- say
73
- say "Run `#{File.basename($0)} unfollow users #{screen_names.join(' ')}` to stop."
74
- end
75
-
76
- end
77
- end
78
- end
data/lib/t/cli/list.rb DELETED
@@ -1,58 +0,0 @@
1
- require 'action_view'
2
- require 'pager'
3
- require 't/rcfile'
4
- require 't/requestable'
5
- require 'thor'
6
-
7
- module T
8
- class CLI
9
- class List < Thor
10
- include ActionView::Helpers::DateHelper
11
- include Pager
12
- include T::Requestable
13
-
14
- DEFAULT_NUM_RESULTS = 20
15
- MAX_SCREEN_NAME_SIZE = 20
16
-
17
- check_unknown_options!
18
-
19
- def initialize(*)
20
- super
21
- @rcfile = RCFile.instance
22
- end
23
-
24
- desc "create LIST_NAME [DESCRIPTION]", "Create a new list."
25
- method_option :private, :aliases => "-p", :type => :boolean
26
- def create(list_name, description="")
27
- defaults = description.blank? ? {} : {:description => description}
28
- defaults.merge!(:mode => 'private') if options['private']
29
- client.list_create(list_name, defaults)
30
- say "@#{@rcfile.default_profile[0]} created the list \"#{list_name}\"."
31
- end
32
-
33
- desc "timeline LIST_NAME", "Show tweet timeline for members of the specified list."
34
- method_option :number, :aliases => "-n", :type => :numeric, :default => DEFAULT_NUM_RESULTS
35
- method_option :reverse, :aliases => "-r", :type => :boolean, :default => false
36
- def timeline(list_name)
37
- defaults = {:include_entities => false}
38
- defaults.merge!(:per_page => options['number']) if options['number']
39
- timeline = client.list_timeline(list_name, defaults)
40
- timeline.reverse! if options['reverse']
41
- page unless T.env.test?
42
- timeline.each do |status|
43
- say "#{status.user.screen_name.rjust(MAX_SCREEN_NAME_SIZE)}: #{status.text} (#{time_ago_in_words(status.created_at)} ago)"
44
- end
45
- end
46
- map %w(tl) => :timeline
47
-
48
- desc "add SUBCOMMAND ...ARGS", "Add users to a list."
49
- require 't/cli/list/add'
50
- subcommand 'add', CLI::List::Add
51
-
52
- desc "remove SUBCOMMAND ...ARGS", "Remove users from a list."
53
- require 't/cli/list/remove'
54
- subcommand 'remove', CLI::List::Remove
55
-
56
- end
57
- end
58
- end
@@ -1,144 +0,0 @@
1
- require 'active_support/core_ext/array/grouping'
2
- require 'retryable'
3
- require 't/core_ext/enumerable'
4
- require 't/core_ext/string'
5
- require 't/collectable'
6
- require 't/rcfile'
7
- require 't/requestable'
8
- require 'thor'
9
-
10
- module T
11
- class CLI
12
- class List
13
- class Add < Thor
14
- include T::Collectable
15
- include T::Requestable
16
-
17
- MAX_USERS_PER_LIST = 500
18
- MAX_USERS_PER_REQUEST = 100
19
-
20
- check_unknown_options!
21
-
22
- def initialize(*)
23
- super
24
- @rcfile = RCFile.instance
25
- end
26
-
27
- desc "friends LIST_NAME", "Add all friends to a list."
28
- def friends(list_name)
29
- list_member_ids = collect_with_cursor do |cursor|
30
- client.list_members(list_name, :cursor => cursor, :skip_status => true, :include_entities => false)
31
- end
32
- existing_list_members = list_member_ids.length
33
- if existing_list_members >= MAX_USERS_PER_LIST
34
- return say "The list \"#{list_name}\" are already contains the maximum of #{MAX_USERS_PER_LIST} members."
35
- end
36
- friend_ids = collect_with_cursor do |cursor|
37
- client.friend_ids(:cursor => cursor)
38
- end
39
- list_member_ids_to_add = (friend_ids - list_member_ids)
40
- number = list_member_ids_to_add.length
41
- if number.zero?
42
- return say "All of @#{@rcfile.default_profile[0]}'s friends are already members of the list \"#{list_name}\"."
43
- elsif existing_list_members + number > MAX_USERS_PER_LIST
44
- return unless yes? "Lists can't have more than #{MAX_USERS_PER_LIST} members. Do you want to add up to #{MAX_USERS_PER_LIST} friends to the list \"#{list_name}\"?"
45
- else
46
- return unless yes? "Are you sure you want to add #{number} #{number == 1 ? 'friend' : 'friends'} to the list \"#{list_name}\"?"
47
- end
48
- max_members_to_add = MAX_USERS_PER_LIST - existing_list_members
49
- list_member_ids_to_add[0...max_members_to_add].in_groups_of(MAX_USERS_PER_REQUEST, false).threaded_each do |user_id_group|
50
- retryable(:tries => 3, :on => Twitter::Error::ServerError, :sleep => 0) do
51
- client.list_add_members(list_name, user_id_group)
52
- end
53
- end
54
- number_added = [number, max_members_to_add].min
55
- say "@#{@rcfile.default_profile[0]} added #{number_added} #{number_added == 1 ? 'friend' : 'friends'} to the list \"#{list_name}\"."
56
- say
57
- say "Run `#{File.basename($0)} list remove all friends #{list_name}` to undo."
58
- end
59
-
60
- desc "followers LIST_NAME", "Add all followers to a list."
61
- def followers(list_name)
62
- list_member_ids = collect_with_cursor do |cursor|
63
- client.list_members(list_name, :cursor => cursor, :skip_status => true, :include_entities => false)
64
- end
65
- existing_list_members = list_member_ids.length
66
- if existing_list_members >= MAX_USERS_PER_LIST
67
- return say "The list \"#{list_name}\" are already contains the maximum of #{MAX_USERS_PER_LIST} members."
68
- end
69
- follower_ids = collect_with_cursor do |cursor|
70
- followers = client.follower_ids(:cursor => cursor)
71
- end
72
- list_member_ids_to_add = (follower_ids - list_member_ids)
73
- number = list_member_ids_to_add.length
74
- if number.zero?
75
- return say "All of @#{@rcfile.default_profile[0]}'s followers are already members of the list \"#{list_name}\"."
76
- elsif existing_list_members + number > MAX_USERS_PER_LIST
77
- return unless yes? "Lists can't have more than #{MAX_USERS_PER_LIST} members. Do you want to add up to #{MAX_USERS_PER_LIST} followers to the list \"#{list_name}\"?"
78
- else
79
- return unless yes? "Are you sure you want to add #{number} #{number == 1 ? 'follower' : 'followers'} to the list \"#{list_name}\"?"
80
- end
81
- max_members_to_add = MAX_USERS_PER_LIST - existing_list_members
82
- list_member_ids_to_add[0...max_members_to_add].in_groups_of(MAX_USERS_PER_REQUEST, false).threaded_each do |user_id_group|
83
- retryable(:tries => 3, :on => Twitter::Error::ServerError, :sleep => 0) do
84
- client.list_add_members(list_name, user_id_group)
85
- end
86
- end
87
- number_added = [number, max_members_to_add].min
88
- say "@#{@rcfile.default_profile[0]} added #{number_added} #{number_added == 1 ? 'follower' : 'followers'} to the list \"#{list_name}\"."
89
- say
90
- say "Run `#{File.basename($0)} list remove all followers #{list_name}` to undo."
91
- end
92
-
93
- desc "listed FROM_LIST_NAME TO_LIST_NAME", "Add all list memebers to a list."
94
- def listed(from_list_name, to_list_name)
95
- to_list_members = collect_with_cursor do |cursor|
96
- client.list_members(to_list_name, :cursor => cursor, :skip_status => true, :include_entities => false)
97
- end
98
- existing_list_members = to_list_members.length
99
- if existing_list_members >= MAX_USERS_PER_LIST
100
- return say "The list \"#{to_list_name}\" are already contains the maximum of #{MAX_USERS_PER_LIST} members."
101
- end
102
- from_list_members = collect_with_cursor do |cursor|
103
- client.list_members(from_list_name, :cursor => cursor, :skip_status => true, :include_entities => false)
104
- end
105
- list_member_ids_to_add = (from_list_members.collect(&:id) - to_list_members.collect(&:id))
106
- number = list_member_ids_to_add.length
107
- if number.zero?
108
- return say "All of the members of the list \"#{from_list_name}\" are already members of the list \"#{to_list_name}\"."
109
- elsif existing_list_members + number > MAX_USERS_PER_LIST
110
- return unless yes? "Lists can't have more than #{MAX_USERS_PER_LIST} members. Do you want to add up to #{MAX_USERS_PER_LIST} members to the list \"#{to_list_name}\"?"
111
- else
112
- return unless yes? "Are you sure you want to add #{number} #{number == 1 ? 'member' : 'members'} to the list \"#{to_list_name}\"?"
113
- end
114
- max_members_to_add = MAX_USERS_PER_LIST - existing_list_members
115
- list_member_ids_to_add[0...max_members_to_add].in_groups_of(MAX_USERS_PER_REQUEST, false).threaded_each do |user_id_group|
116
- retryable(:tries => 3, :on => Twitter::Error::ServerError, :sleep => 0) do
117
- client.list_add_members(to_list_name, user_id_group)
118
- end
119
- end
120
- number_added = [number, max_members_to_add].min
121
- say "@#{@rcfile.default_profile[0]} added #{number_added} #{number_added == 1 ? 'member' : 'members'} to the list \"#{to_list_name}\"."
122
- say
123
- say "Run `#{File.basename($0)} list remove all listed #{from_list_name} #{to_list_name}` to undo."
124
- end
125
-
126
- desc "users LIST_NAME SCREEN_NAME [SCREEN_NAME...]", "Add users to a list."
127
- def users(list_name, screen_name, *screen_names)
128
- screen_names.unshift(screen_name)
129
- screen_names.map!(&:strip_at)
130
- screen_names.in_groups_of(MAX_USERS_PER_REQUEST, false).threaded_each do |user_id_group|
131
- retryable(:tries => 3, :on => Twitter::Error::ServerError, :sleep => 0) do
132
- client.list_add_members(list_name, user_id_group)
133
- end
134
- end
135
- number = screen_names.length
136
- say "@#{@rcfile.default_profile[0]} added #{number} #{number == 1 ? 'user' : 'users'} to the list \"#{list_name}\"."
137
- say
138
- say "Run `#{File.basename($0)} list remove users #{list_name} #{screen_names.join(' ')}` to undo."
139
- end
140
-
141
- end
142
- end
143
- end
144
- end