createsend 0.1.1 → 0.2.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/Gemfile.lock +1 -1
- data/README.md +6 -6
- data/Rakefile +1 -1
- data/createsend.gemspec +1 -1
- data/lib/campaign.rb +131 -129
- data/lib/client.rb +134 -132
- data/lib/createsend.rb +94 -80
- data/lib/list.rb +179 -180
- data/lib/segment.rb +67 -65
- data/lib/subscriber.rb +56 -54
- data/lib/template.rb +35 -33
- data/test/campaign_test.rb +2 -2
- data/test/client_test.rb +2 -2
- data/test/createsend_test.rb +8 -8
- data/test/fixtures/list_webhooks.json +1 -4
- data/test/list_test.rb +4 -4
- data/test/segment_test.rb +2 -2
- data/test/subscriber_test.rb +6 -6
- data/test/template_test.rb +2 -2
- metadata +5 -5
data/Gemfile.lock
CHANGED
data/README.md
CHANGED
@@ -15,7 +15,7 @@ Retrieve a list of all your clients.
|
|
15
15
|
|
16
16
|
CreateSend.api_key 'your_api_key'
|
17
17
|
|
18
|
-
cs = CreateSend.new
|
18
|
+
cs = CreateSend::CreateSend.new
|
19
19
|
clients = cs.clients
|
20
20
|
|
21
21
|
clients.each do |c|
|
@@ -35,10 +35,10 @@ If the createsend API returns an error, an exception will be thrown. For example
|
|
35
35
|
CreateSend.api_key 'your_api_key'
|
36
36
|
|
37
37
|
begin
|
38
|
-
cl = Client.new "4a397ccaaa55eb4e6aa1221e1e2d7122"
|
39
|
-
id = Campaign.create cl.client_id, "", "", "", "", "", "", "", [], []
|
38
|
+
cl = CreateSend::Client.new "4a397ccaaa55eb4e6aa1221e1e2d7122"
|
39
|
+
id = CreateSend::Campaign.create cl.client_id, "", "", "", "", "", "", "", [], []
|
40
40
|
puts "New campaign ID: #{id}"
|
41
|
-
rescue BadRequest => br
|
41
|
+
rescue CreateSend::BadRequest => br
|
42
42
|
puts "Bad request error: #{br}"
|
43
43
|
puts "Error Code: #{br.data.Code}"
|
44
44
|
puts "Error Message: #{br.data.Message}"
|
@@ -55,11 +55,11 @@ Results in:
|
|
55
55
|
### Expected input and output
|
56
56
|
The best way of finding out the expected input and output of a particular method in a particular class is to use the unit tests as a reference.
|
57
57
|
|
58
|
-
For example, if you wanted to find out how to call the Subscriber.add method, you would look at the file test/subscriber_test.rb
|
58
|
+
For example, if you wanted to find out how to call the CreateSend::Subscriber.add method, you would look at the file test/subscriber_test.rb
|
59
59
|
|
60
60
|
should "add a subscriber with custom fields" do
|
61
61
|
stub_post(@api_key, "subscribers/#{@list_id}.json", "add_subscriber.json")
|
62
62
|
custom_fields = [ { :Key => 'website', :Value => 'http://example.com/' } ]
|
63
|
-
email_address = Subscriber.add @list_id, "subscriber@example.com", "Subscriber", custom_fields, true
|
63
|
+
email_address = CreateSend::Subscriber.add @list_id, "subscriber@example.com", "Subscriber", custom_fields, true
|
64
64
|
email_address.should == "subscriber@example.com"
|
65
65
|
end
|
data/Rakefile
CHANGED
data/createsend.gemspec
CHANGED
@@ -21,7 +21,7 @@ Gem::Specification.new do |s|
|
|
21
21
|
s.require_paths = ["lib"]
|
22
22
|
s.summary = %q{A library which implements the complete functionality of v3 of the createsend API.}
|
23
23
|
s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
|
24
|
-
s.version = CreateSend::
|
24
|
+
s.version = CreateSend::VERSION
|
25
25
|
s.platform = Gem::Platform::RUBY
|
26
26
|
s.required_rubygems_version = Gem::Requirement.new('>= 1.3.6') if s.respond_to? :required_rubygems_version=
|
27
27
|
end
|
data/lib/campaign.rb
CHANGED
@@ -1,134 +1,136 @@
|
|
1
1
|
require 'createsend'
|
2
2
|
require 'json'
|
3
3
|
|
4
|
-
|
5
|
-
|
6
|
-
|
4
|
+
module CreateSend
|
5
|
+
# Represents a campaign and provides associated funtionality.
|
6
|
+
class Campaign
|
7
|
+
attr_reader :campaign_id
|
8
|
+
|
9
|
+
def initialize(campaign_id)
|
10
|
+
@campaign_id = campaign_id
|
11
|
+
end
|
12
|
+
|
13
|
+
# Creates a new campaign for a client.
|
14
|
+
def self.create(client_id, subject, name, from_name, from_email, reply_to, html_url,
|
15
|
+
text_url, list_ids, segment_ids)
|
16
|
+
options = { :body => {
|
17
|
+
:Subject => subject,
|
18
|
+
:Name => name,
|
19
|
+
:FromName => from_name,
|
20
|
+
:FromEmail => from_email,
|
21
|
+
:ReplyTo => reply_to,
|
22
|
+
:HtmlUrl => html_url,
|
23
|
+
:TextUrl => text_url,
|
24
|
+
:ListIDs => list_ids,
|
25
|
+
:SegmentIDs => segment_ids }.to_json }
|
26
|
+
response = CreateSend.post "/campaigns/#{client_id}.json", options
|
27
|
+
response.parsed_response
|
28
|
+
end
|
29
|
+
|
30
|
+
# Sends a preview of this campaign.
|
31
|
+
def send_preview(recipients, personalize="fallback")
|
32
|
+
options = { :body => {
|
33
|
+
:PreviewRecipients => recipients.kind_of?(String) ? [ recipients ] : recipients,
|
34
|
+
:Personalize => personalize }.to_json }
|
35
|
+
response = post "sendpreview", options
|
36
|
+
end
|
37
|
+
|
38
|
+
# Sends this campaign.
|
39
|
+
def send(confirmation_email, send_date="immediately")
|
40
|
+
options = { :body => {
|
41
|
+
:ConfirmationEmail => confirmation_email,
|
42
|
+
:SendDate => send_date }.to_json }
|
43
|
+
response = post "send", options
|
44
|
+
end
|
45
|
+
|
46
|
+
# Deletes this campaign.
|
47
|
+
def delete
|
48
|
+
response = CreateSend.delete "/campaigns/#{campaign_id}.json", {}
|
49
|
+
end
|
50
|
+
|
51
|
+
# Gets a summary of this campaign
|
52
|
+
def summary
|
53
|
+
response = get "summary", {}
|
54
|
+
Hashie::Mash.new(response)
|
55
|
+
end
|
56
|
+
|
57
|
+
# Retrieves the lists and segments to which this campaaign will be (or was) sent.
|
58
|
+
def lists_and_segments
|
59
|
+
response = get "listsandsegments", {}
|
60
|
+
Hashie::Mash.new(response)
|
61
|
+
end
|
62
|
+
|
63
|
+
# Retrieves the recipients of this campaign.
|
64
|
+
def recipients(page=1, page_size=1000, order_field="email", order_direction="asc")
|
65
|
+
options = { :query => {
|
66
|
+
:page => page,
|
67
|
+
:pagesize => page_size,
|
68
|
+
:orderfield => order_field,
|
69
|
+
:orderdirection => order_direction } }
|
70
|
+
response = get 'recipients', options
|
71
|
+
Hashie::Mash.new(response)
|
72
|
+
end
|
73
|
+
|
74
|
+
# Retrieves the opens for this campaign.
|
75
|
+
def opens(date, page=1, page_size=1000, order_field="date", order_direction="asc")
|
76
|
+
options = { :query => {
|
77
|
+
:date => date,
|
78
|
+
:page => page,
|
79
|
+
:pagesize => page_size,
|
80
|
+
:orderfield => order_field,
|
81
|
+
:orderdirection => order_direction } }
|
82
|
+
response = get "opens", options
|
83
|
+
Hashie::Mash.new(response)
|
84
|
+
end
|
85
|
+
|
86
|
+
# Retrieves the subscriber clicks for this campaign.
|
87
|
+
def clicks(date, page=1, page_size=1000, order_field="date", order_direction="asc")
|
88
|
+
options = { :query => {
|
89
|
+
:date => date,
|
90
|
+
:page => page,
|
91
|
+
:pagesize => page_size,
|
92
|
+
:orderfield => order_field,
|
93
|
+
:orderdirection => order_direction } }
|
94
|
+
response = get "clicks", options
|
95
|
+
Hashie::Mash.new(response)
|
96
|
+
end
|
97
|
+
|
98
|
+
# Retrieves the unsubscribes for this campaign.
|
99
|
+
def unsubscribes(date, page=1, page_size=1000, order_field="date", order_direction="asc")
|
100
|
+
options = { :query => {
|
101
|
+
:date => date,
|
102
|
+
:page => page,
|
103
|
+
:pagesize => page_size,
|
104
|
+
:orderfield => order_field,
|
105
|
+
:orderdirection => order_direction } }
|
106
|
+
response = get "unsubscribes", options
|
107
|
+
Hashie::Mash.new(response)
|
108
|
+
end
|
109
|
+
|
110
|
+
# Retrieves the bounces for this campaign.
|
111
|
+
def bounces(page=1, page_size=1000, order_field="date", order_direction="asc")
|
112
|
+
options = { :query => {
|
113
|
+
:page => page,
|
114
|
+
:pagesize => page_size,
|
115
|
+
:orderfield => order_field,
|
116
|
+
:orderdirection => order_direction } }
|
117
|
+
response = get "bounces", options
|
118
|
+
Hashie::Mash.new(response)
|
119
|
+
end
|
120
|
+
|
121
|
+
private
|
122
|
+
|
123
|
+
def get(action, options = {})
|
124
|
+
CreateSend.get uri_for(action), options
|
125
|
+
end
|
126
|
+
|
127
|
+
def post(action, options = {})
|
128
|
+
CreateSend.post uri_for(action), options
|
129
|
+
end
|
130
|
+
|
131
|
+
def uri_for(action)
|
132
|
+
"/campaigns/#{campaign_id}/#{action}.json"
|
133
|
+
end
|
7
134
|
|
8
|
-
def initialize(campaign_id)
|
9
|
-
@campaign_id = campaign_id
|
10
135
|
end
|
11
|
-
|
12
|
-
# Creates a new campaign for a client.
|
13
|
-
def self.create(client_id, subject, name, from_name, from_email, reply_to, html_url,
|
14
|
-
text_url, list_ids, segment_ids)
|
15
|
-
options = { :body => {
|
16
|
-
:Subject => subject,
|
17
|
-
:Name => name,
|
18
|
-
:FromName => from_name,
|
19
|
-
:FromEmail => from_email,
|
20
|
-
:ReplyTo => reply_to,
|
21
|
-
:HtmlUrl => html_url,
|
22
|
-
:TextUrl => text_url,
|
23
|
-
:ListIDs => list_ids,
|
24
|
-
:SegmentIDs => segment_ids }.to_json }
|
25
|
-
response = CreateSend.post "/campaigns/#{client_id}.json", options
|
26
|
-
response.parsed_response
|
27
|
-
end
|
28
|
-
|
29
|
-
# Sends a preview of this campaign.
|
30
|
-
def send_preview(recipients, personalize="fallback")
|
31
|
-
options = { :body => {
|
32
|
-
:PreviewRecipients => recipients.kind_of?(String) ? [ recipients ] : recipients,
|
33
|
-
:Personalize => personalize }.to_json }
|
34
|
-
response = post "sendpreview", options
|
35
|
-
end
|
36
|
-
|
37
|
-
# Sends this campaign.
|
38
|
-
def send(confirmation_email, send_date="immediately")
|
39
|
-
options = { :body => {
|
40
|
-
:ConfirmationEmail => confirmation_email,
|
41
|
-
:SendDate => send_date }.to_json }
|
42
|
-
response = post "send", options
|
43
|
-
end
|
44
|
-
|
45
|
-
# Deletes this campaign.
|
46
|
-
def delete
|
47
|
-
response = CreateSend.delete "/campaigns/#{campaign_id}.json", {}
|
48
|
-
end
|
49
|
-
|
50
|
-
# Gets a summary of this campaign
|
51
|
-
def summary
|
52
|
-
response = get "summary", {}
|
53
|
-
Hashie::Mash.new(response)
|
54
|
-
end
|
55
|
-
|
56
|
-
# Retrieves the lists and segments to which this campaaign will be (or was) sent.
|
57
|
-
def lists_and_segments
|
58
|
-
response = get "listsandsegments", {}
|
59
|
-
Hashie::Mash.new(response)
|
60
|
-
end
|
61
|
-
|
62
|
-
# Retrieves the recipients of this campaign.
|
63
|
-
def recipients(page=1, page_size=1000, order_field="email", order_direction="asc")
|
64
|
-
options = { :query => {
|
65
|
-
:page => page,
|
66
|
-
:pagesize => page_size,
|
67
|
-
:orderfield => order_field,
|
68
|
-
:orderdirection => order_direction } }
|
69
|
-
response = get 'recipients', options
|
70
|
-
Hashie::Mash.new(response)
|
71
|
-
end
|
72
|
-
|
73
|
-
# Retrieves the opens for this campaign.
|
74
|
-
def opens(date, page=1, page_size=1000, order_field="date", order_direction="asc")
|
75
|
-
options = { :query => {
|
76
|
-
:date => date,
|
77
|
-
:page => page,
|
78
|
-
:pagesize => page_size,
|
79
|
-
:orderfield => order_field,
|
80
|
-
:orderdirection => order_direction } }
|
81
|
-
response = get "opens", options
|
82
|
-
Hashie::Mash.new(response)
|
83
|
-
end
|
84
|
-
|
85
|
-
# Retrieves the subscriber clicks for this campaign.
|
86
|
-
def clicks(date, page=1, page_size=1000, order_field="date", order_direction="asc")
|
87
|
-
options = { :query => {
|
88
|
-
:date => date,
|
89
|
-
:page => page,
|
90
|
-
:pagesize => page_size,
|
91
|
-
:orderfield => order_field,
|
92
|
-
:orderdirection => order_direction } }
|
93
|
-
response = get "clicks", options
|
94
|
-
Hashie::Mash.new(response)
|
95
|
-
end
|
96
|
-
|
97
|
-
# Retrieves the unsubscribes for this campaign.
|
98
|
-
def unsubscribes(date, page=1, page_size=1000, order_field="date", order_direction="asc")
|
99
|
-
options = { :query => {
|
100
|
-
:date => date,
|
101
|
-
:page => page,
|
102
|
-
:pagesize => page_size,
|
103
|
-
:orderfield => order_field,
|
104
|
-
:orderdirection => order_direction } }
|
105
|
-
response = get "unsubscribes", options
|
106
|
-
Hashie::Mash.new(response)
|
107
|
-
end
|
108
|
-
|
109
|
-
# Retrieves the bounces for this campaign.
|
110
|
-
def bounces(page=1, page_size=1000, order_field="date", order_direction="asc")
|
111
|
-
options = { :query => {
|
112
|
-
:page => page,
|
113
|
-
:pagesize => page_size,
|
114
|
-
:orderfield => order_field,
|
115
|
-
:orderdirection => order_direction } }
|
116
|
-
response = get "bounces", options
|
117
|
-
Hashie::Mash.new(response)
|
118
|
-
end
|
119
|
-
|
120
|
-
private
|
121
|
-
|
122
|
-
def get(action, options = {})
|
123
|
-
CreateSend.get uri_for(action), options
|
124
|
-
end
|
125
|
-
|
126
|
-
def post(action, options = {})
|
127
|
-
CreateSend.post uri_for(action), options
|
128
|
-
end
|
129
|
-
|
130
|
-
def uri_for(action)
|
131
|
-
"/campaigns/#{campaign_id}/#{action}.json"
|
132
|
-
end
|
133
|
-
|
134
|
-
end
|
136
|
+
end
|
data/lib/client.rb
CHANGED
@@ -1,135 +1,137 @@
|
|
1
1
|
require 'createsend'
|
2
2
|
require 'json'
|
3
3
|
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
:
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
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
|
-
|
81
|
-
|
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
|
-
|
120
|
-
|
121
|
-
|
122
|
-
|
123
|
-
|
124
|
-
|
125
|
-
|
126
|
-
|
127
|
-
|
128
|
-
|
129
|
-
|
130
|
-
|
131
|
-
|
132
|
-
|
133
|
-
|
134
|
-
|
135
|
-
end
|
4
|
+
module CreateSend
|
5
|
+
# Represents a client and associated functionality.
|
6
|
+
class Client
|
7
|
+
attr_reader :client_id
|
8
|
+
|
9
|
+
def initialize(client_id)
|
10
|
+
@client_id = client_id
|
11
|
+
end
|
12
|
+
|
13
|
+
# Creates a client.
|
14
|
+
def self.create(company, contact_name, email, timezone, country)
|
15
|
+
options = { :body => {
|
16
|
+
:CompanyName => company,
|
17
|
+
:ContactName => contact_name,
|
18
|
+
:EmailAddress => email,
|
19
|
+
:TimeZone => timezone,
|
20
|
+
:Country => country }.to_json }
|
21
|
+
CreateSend.post "/clients.json", options
|
22
|
+
end
|
23
|
+
|
24
|
+
# Gets the details of this client.
|
25
|
+
def details
|
26
|
+
response = CreateSend.get "/clients/#{client_id}.json", {}
|
27
|
+
Hashie::Mash.new(response)
|
28
|
+
end
|
29
|
+
|
30
|
+
# Gets the sent campaigns belonging to this client.
|
31
|
+
def campaigns
|
32
|
+
response = get 'campaigns'
|
33
|
+
response.map{|item| Hashie::Mash.new(item)}
|
34
|
+
end
|
35
|
+
|
36
|
+
# Gets the draft campaigns belonging to this client.
|
37
|
+
def drafts
|
38
|
+
response = get 'drafts'
|
39
|
+
response.map{|item| Hashie::Mash.new(item)}
|
40
|
+
end
|
41
|
+
|
42
|
+
# Gets the subscriber lists belonging to this client.
|
43
|
+
def lists
|
44
|
+
response = get 'lists'
|
45
|
+
response.map{|item| Hashie::Mash.new(item)}
|
46
|
+
end
|
47
|
+
|
48
|
+
# Gets the segments belonging to this client.
|
49
|
+
def segments
|
50
|
+
response = get 'segments'
|
51
|
+
response.map{|item| Hashie::Mash.new(item)}
|
52
|
+
end
|
53
|
+
|
54
|
+
# Gets this client's suppression list.
|
55
|
+
def suppressionlist(page=1, page_size=1000, order_field="email", order_direction="asc")
|
56
|
+
options = { :query => {
|
57
|
+
:page => page,
|
58
|
+
:pagesize => page_size,
|
59
|
+
:orderfield => order_field,
|
60
|
+
:orderdirection => order_direction } }
|
61
|
+
response = get 'suppressionlist', options
|
62
|
+
Hashie::Mash.new(response)
|
63
|
+
end
|
64
|
+
|
65
|
+
# Gets the templates belonging to this client.
|
66
|
+
def templates
|
67
|
+
response = get 'templates'
|
68
|
+
response.map{|item| Hashie::Mash.new(item)}
|
69
|
+
end
|
70
|
+
|
71
|
+
# Sets the basic details for this client.
|
72
|
+
def set_basics(company, contact_name, email, timezone, country)
|
73
|
+
options = { :body => {
|
74
|
+
:CompanyName => company,
|
75
|
+
:ContactName => contact_name,
|
76
|
+
:EmailAddress => email,
|
77
|
+
:TimeZone => timezone,
|
78
|
+
:Country => country }.to_json }
|
79
|
+
put 'setbasics', options
|
80
|
+
end
|
81
|
+
|
82
|
+
# Sets the access settings for this client.
|
83
|
+
def set_access(username, password, access_level)
|
84
|
+
options = { :body => {
|
85
|
+
:Username => username,
|
86
|
+
:Password => password,
|
87
|
+
:AccessLevel => access_level }.to_json }
|
88
|
+
put 'setaccess', options
|
89
|
+
end
|
90
|
+
|
91
|
+
# Sets the PAYG billing settings for this client.
|
92
|
+
def set_payg_billing(currency, can_purchase_credits, client_pays, markup_percentage,
|
93
|
+
markup_on_delivery=0, markup_per_recipient=0, markup_on_design_spam_test=0)
|
94
|
+
options = { :body => {
|
95
|
+
:Currency => currency,
|
96
|
+
:CanPurchaseCredits => can_purchase_credits,
|
97
|
+
:ClientPays => client_pays,
|
98
|
+
:MarkupPercentage => markup_percentage,
|
99
|
+
:MarkupOnDelivery => markup_on_delivery,
|
100
|
+
:MarkupPerRecipient => markup_per_recipient,
|
101
|
+
:MarkupOnDesignSpamTest => markup_on_design_spam_test }.to_json }
|
102
|
+
put 'setpaygbilling', options
|
103
|
+
end
|
104
|
+
|
105
|
+
# Sets the monthly billing settings for this client.
|
106
|
+
def set_monthly_billing(currency, client_pays, markup_percentage)
|
107
|
+
options = { :body => {
|
108
|
+
:Currency => currency,
|
109
|
+
:ClientPays => client_pays,
|
110
|
+
:MarkupPercentage => markup_percentage }.to_json }
|
111
|
+
put 'setmonthlybilling', options
|
112
|
+
end
|
113
|
+
|
114
|
+
# Deletes this client.
|
115
|
+
def delete
|
116
|
+
CreateSend.delete "/clients/#{client_id}.json", {}
|
117
|
+
end
|
118
|
+
|
119
|
+
private
|
120
|
+
|
121
|
+
def get(action, options = {})
|
122
|
+
CreateSend.get uri_for(action), options
|
123
|
+
end
|
124
|
+
|
125
|
+
def post(action, options = {})
|
126
|
+
CreateSend.post uri_for(action), options
|
127
|
+
end
|
128
|
+
|
129
|
+
def put(action, options = {})
|
130
|
+
CreateSend.put uri_for(action), options
|
131
|
+
end
|
132
|
+
|
133
|
+
def uri_for(action)
|
134
|
+
"/clients/#{client_id}/#{action}.json"
|
135
|
+
end
|
136
|
+
end
|
137
|
+
end
|