mints 0.0.1 → 0.0.6

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.
@@ -0,0 +1,2 @@
1
+ class Api::V1::MintsPublicController < Mints::PublicAPIController
2
+ end
@@ -0,0 +1,2 @@
1
+ class Api::MintsUserController < Mints::UserAPIController
2
+ end
@@ -1,5 +1,10 @@
1
1
  require_relative "./pub.rb"
2
2
  require_relative "./contact.rb"
3
3
  require_relative "./user.rb"
4
+ require_relative "./mints/controllers/base_controller.rb"
5
+ require_relative "./mints/controllers/admin_base_controller.rb"
6
+ require_relative "./mints/controllers/public_api_controller.rb"
7
+ require_relative "./mints/controllers/contact_api_controller.rb"
8
+ require_relative "./mints/controllers/user_api_controller.rb"
4
9
  module Mints
5
10
  end
@@ -0,0 +1,56 @@
1
+ module Mints
2
+ class AdminBaseController < ActionController::Base
3
+ before_action :set_mints_user_client
4
+
5
+ # def mints_user_signed_in?
6
+ # # Check status in mints
7
+ # response = @mints_user.status
8
+ # status = response['success'] ? response['success'] : false
9
+ # unless status
10
+ # # if mints response is negative delete the session cookie
11
+ # cookies.delete(:mints_user_session_token)
12
+ # end
13
+ # return status
14
+ # end
15
+
16
+ ##
17
+ # === Mints user Login.
18
+ # Starts a user session in mints.cloud and set a session cookie
19
+ def mints_user_login(email, password)
20
+ # Login in mints
21
+ response = @mints_user.login(email, password)
22
+ # Get session token from response
23
+ session_token = response['api_token']
24
+ # Set a permanent cookie with the session token
25
+ cookies.permanent[:mints_user_session_token] = session_token
26
+ end
27
+
28
+ ##
29
+ # === Mints user Logout.
30
+ # Destroy session from mints.cloud and delete local session cookie
31
+ def mints_user_logout
32
+ # Logout from mints
33
+ # @mints_user.logout
34
+ # Delete local cookie
35
+ cookies.delete(:mints_user_session_token)
36
+ end
37
+
38
+ private
39
+
40
+ ##
41
+ # === Set Mints user client.
42
+ # Initialize the public client and set the user token
43
+ def set_mints_user_client
44
+ if File.exists?("#{Rails.root}/mints_config.yml")
45
+ config = YAML.load_file("#{Rails.root}/mints_config.yml")
46
+ @host = config["mints"]["host"]
47
+ @api_key = config["mints"]["api_key"]
48
+ @debug = config["sdk"]["debug"] ? config["sdk"]["debug"] : false
49
+ else
50
+ raise 'MintsBadCredentialsError'
51
+ end
52
+ # Initialize mints user client
53
+ @mints_user = Mints::User.new(@host, @api_key, nil, @debug)
54
+ end
55
+ end
56
+ end
@@ -0,0 +1,86 @@
1
+ module Mints
2
+ class BaseController < ActionController::Base
3
+ before_action :set_contact_token
4
+ before_action :set_mints_pub_client
5
+ before_action :register_visit
6
+ before_action :set_mints_contact_client
7
+
8
+ def mints_contact_signed_in?
9
+ # Check status in mints
10
+ response = @mints_contact.status
11
+ status = response['success'] ? response['success'] : false
12
+ unless status
13
+ # if mints response is negative delete the session cookie
14
+ cookies.delete(:mints_contact_session_token)
15
+ end
16
+ return status
17
+ end
18
+
19
+ ##
20
+ # === Mints Contact Login.
21
+ # Starts a contact session in mints.cloud and set a session cookie
22
+ def mints_contact_login(email, password)
23
+ # Login in mints
24
+ response = @mints_contact.login(email, password)
25
+ # Get session token from response
26
+ session_token = response['session_token']
27
+ # Set a permanent cookie with the session token
28
+ cookies.permanent[:mints_contact_session_token] = session_token
29
+ end
30
+
31
+ ##
32
+ # === Mints Contact Logout.
33
+ # Destroy session from mints.cloud and delete local session cookie
34
+ def mints_contact_logout
35
+ # Logout from mints
36
+ @mints_contact.logout
37
+ # Delete local cookie
38
+ cookies.delete(:mints_contact_session_token)
39
+ end
40
+
41
+ private
42
+
43
+ ##
44
+ # === Register visit.
45
+ # Call register visit method from the public client and set/renew the cookie mints_contact_id
46
+ def register_visit
47
+ response = @mints_pub.register_visit(request)
48
+ @contact_token = response['user_token']
49
+ @visit_id = response['visit_id']
50
+ cookies.permanent[:mints_contact_id] = @contact_token
51
+ end
52
+
53
+ ##
54
+ # === Set mints pub.
55
+ # Initialize the public client and set the contact token
56
+ def set_mints_pub_client
57
+ if File.exists?("#{Rails.root}/mints_config.yml")
58
+ config = YAML.load_file("#{Rails.root}/mints_config.yml")
59
+ @host = config["mints"]["host"]
60
+ @api_key = config["mints"]["api_key"]
61
+ @debug = config["sdk"]["debug"] ? config["sdk"]["debug"] : false
62
+ else
63
+ raise 'MintsBadCredentialsError'
64
+ end
65
+ # Initialize mints pub client, credentials taken from mints_config.yml file
66
+ @mints_pub = Mints::Pub.new(@host, @api_key, nil, @debug)
67
+ # Set contact token from cookie
68
+ @mints_pub.client.session_token = @contact_token
69
+ end
70
+
71
+ ##
72
+ # === Set contact token.
73
+ # Set contact token variable from the mints_contact_id cookie value
74
+ def set_contact_token
75
+ @contact_token = cookies[:mints_contact_id]
76
+ end
77
+
78
+ ##
79
+ # === Set mints contact client.
80
+ # Initialize the public client and set the contact token
81
+ def set_mints_contact_client
82
+ # Initialize mints clontact client
83
+ @mints_contact = Mints::Contact.new(@host, @api_key, nil, @debug)
84
+ end
85
+ end
86
+ end
@@ -0,0 +1,39 @@
1
+ require 'reverse_proxy/controller'
2
+ require 'reverse_proxy/client'
3
+ module Mints
4
+ class ContactAPIController < ActionController::API
5
+ include AbstractController::Helpers
6
+ include ActionController::Cookies
7
+ include ReverseProxy::Controller
8
+ before_action :set_config_variables
9
+
10
+ def index
11
+ headers = {
12
+ 'host' => "#{@host.gsub('http://', '').gsub('https://', '')}",
13
+ 'ApiKey' => "#{@api_key}",
14
+ 'Content-Type'=> 'application/json',
15
+ 'Accept'=> 'application/json'
16
+ }
17
+ if cookies[:mints_contact_session_token]
18
+ session_token = cookies[:mints_contact_session_token]
19
+ headers["Authorization"] = "Bearer #{session_token}"
20
+ end
21
+ reverse_proxy "#{@host}", headers: headers, verify_ssl: false do |config|
22
+ # We got a 404!
23
+ config.on_missing do |code, response|
24
+ raise ActionController::RoutingError.new('Not Found')
25
+ end
26
+ end
27
+ end
28
+
29
+ private
30
+
31
+ def set_config_variables
32
+ if File.exists?("#{Rails.root}/mints_config.yml")
33
+ config = YAML.load_file("#{Rails.root}/mints_config.yml")
34
+ @host = config["mints"]["host"]
35
+ @api_key = config["mints"]["api_key"]
36
+ end
37
+ end
38
+ end
39
+ end
@@ -0,0 +1,33 @@
1
+ require 'reverse_proxy/controller'
2
+ require 'reverse_proxy/client'
3
+ module Mints
4
+ class PublicAPIController < ActionController::API
5
+ include ReverseProxy::Controller
6
+ before_action :set_config_variables
7
+
8
+ def index
9
+ headers = {
10
+ 'host' => "#{@host.gsub('http://', '').gsub('https://', '')}",
11
+ 'ApiKey' => "#{@api_key}",
12
+ 'Content-Type'=> 'application/json',
13
+ 'Accept'=> 'application/json'
14
+ }
15
+ reverse_proxy "#{@host}", headers: headers, verify_ssl: false do |config|
16
+ # We got a 404!
17
+ config.on_missing do |code, response|
18
+ raise ActionController::RoutingError.new('Not Found')
19
+ end
20
+ end
21
+ end
22
+
23
+ private
24
+
25
+ def set_config_variables
26
+ if File.exists?("#{Rails.root}/mints_config.yml")
27
+ config = YAML.load_file("#{Rails.root}/mints_config.yml")
28
+ @host = config["mints"]["host"]
29
+ @api_key = config["mints"]["api_key"]
30
+ end
31
+ end
32
+ end
33
+ end
@@ -0,0 +1,39 @@
1
+ require 'reverse_proxy/controller'
2
+ require 'reverse_proxy/client'
3
+ module Mints
4
+ class UserAPIController < ActionController::API
5
+ include AbstractController::Helpers
6
+ include ActionController::Cookies
7
+ include ReverseProxy::Controller
8
+ before_action :set_config_variables
9
+
10
+ def index
11
+ headers = {
12
+ 'host' => "#{@host.gsub('http://', '').gsub('https://', '')}",
13
+ 'ApiKey' => "#{@api_key}",
14
+ 'Content-Type'=> 'application/json',
15
+ 'Accept'=> 'application/json'
16
+ }
17
+ if cookies[:mints_contact_session_token]
18
+ session_token = cookies[:mints_user_session_token]
19
+ headers["Authorization"] = "Bearer #{session_token}"
20
+ end
21
+ reverse_proxy "#{@host}", headers: headers, verify_ssl: false do |config|
22
+ # We got a 404!
23
+ config.on_missing do |code, response|
24
+ raise ActionController::RoutingError.new('Not Found')
25
+ end
26
+ end
27
+ end
28
+
29
+ private
30
+
31
+ def set_config_variables
32
+ if File.exists?("#{Rails.root}/mints_config.yml")
33
+ config = YAML.load_file("#{Rails.root}/mints_config.yml")
34
+ @host = config["mints"]["host"]
35
+ @api_key = config["mints"]["api_key"]
36
+ end
37
+ end
38
+ end
39
+ end
data/lib/pub.rb CHANGED
@@ -1,50 +1,320 @@
1
+ require 'yaml'
1
2
  require_relative './client.rb'
2
3
  module Mints
4
+ ##
5
+ # == Public context API
6
+ # Pub class contains functions that needs only an API key as authentication
7
+ # == Usage example
8
+ # Initialize
9
+ # pub = Mints::Pub.new(mints_url, api_key)
10
+ # or if host and api_key are provided by mints_config.yml
11
+ # pub = Mints::Pub.new
12
+ # Call any function
13
+ # pub.get_products
14
+ # == Single resource options
15
+ # * +include+ - [String] include a relationship
16
+ # * +attributes+ - [Boolean] attach attributes to response
17
+ # * +categories+ - [Boolean] attach categories to response
18
+ # * +tags+ - [Boolean] attach tags to response
19
+ # == Resource collections options
20
+ # * +search+ - [String] filter by a search word
21
+ # * +scopes+ - [String] filter by a scope
22
+ # * +filters+ - [String] filter by where clauses
23
+ # * +jfilters+ - [String] filter using complex condition objects
24
+ # * +catfilters+ - [String] filter by categories
25
+ # * +fields+ - [String] indicates the columns that will be selected
26
+ # * +sort+ - [String] indicates the columns that will be selected
27
+ # * +include+ - [String] include a relationship
28
+ # * +attributes+ - [Boolean] attach attributes to response
29
+ # * +categories+ - [Boolean] attach categories to response
30
+ # * +taxonomies+ - [Boolean] attach categories to response
31
+ # * +tags+ - [Boolean] attach tags to response
3
32
  class Pub
4
33
  attr_reader :client
5
- def initialize(host, api_key)
6
- @client = Mints::Client.new(host, api_key)
34
+
35
+ ##
36
+ # === Initialize.
37
+ # Class constructor
38
+ #
39
+ # ==== Parameters
40
+ # * +host+ - [String] It's the visitor IP
41
+ # * +api_key+ - [String] Mints instance api key
42
+ # * +contact_token+ - [String] Cookie 'mints_contact_id' value (mints_contact_token)
43
+ # ==== Return
44
+ # Returns a Client object
45
+ def initialize(host, api_key, contact_token = nil, debug = false)
46
+ @client = Mints::Client.new(host, api_key, contact_token, debug)
7
47
  end
8
48
 
9
- def register_visit(ip, user_agent, url)
49
+ ##
50
+ # === Register Visit.
51
+ # Register a ghost/contact visit in Mints.Cloud
52
+ #
53
+ # ==== Parameters
54
+ # * +request+ - [ActionDispatch::Request] request
55
+ # * +ip+ - [String] It's the visitor IP
56
+ # * +user_agent+ - The visitor's browser user agent
57
+ # * +url+ - [String] URL visited
58
+ def register_visit(request, ip = nil, user_agent = nil, url = nil)
10
59
  data = {
11
- ip_address: ip,
12
- user_agent: user_agent,
13
- url: url
60
+ ip_address: ip || request.remote_ip,
61
+ user_agent: user_agent || request.user_agent,
62
+ url: url || request.fullpath
14
63
  }
15
- return @client.raw("post", "/register-visit-timer", data)
64
+ response = @client.raw("post", "/register-visit", nil, data)
65
+ return response
66
+ end
67
+
68
+ ##
69
+ # === Register Visit timer.
70
+ # Register a page visit time
71
+ #
72
+ # ==== Parameters
73
+ # * +visit+ - [String] It's the visitor IP
74
+ # * +time+ - [Integer] The visitor's browser user agent
75
+ def register_visit_timer(visit, time)
76
+ return @client.raw("get", "/register-visit-timer?visit=#{visit}&time=#{time}")
77
+ end
78
+
79
+ ##
80
+ # === Get Content Page.
81
+ # Get a single content page
82
+ #
83
+ # ==== Parameters
84
+ # * +slug+ - [String] It's the slug
85
+ # * +options+ - [Hash] List of {Single Resource Options}[#class-Mints::Pub-label-Single+resource+options] shown above can be used as parameter
86
+ def get_content_page(slug, options = nil)
87
+ return @client.raw("get", "/content/content-pages/#{slug}", options)
88
+ end
89
+
90
+ ##
91
+ # === Get Content Templates.
92
+ # Get a collection of content templates
93
+ #
94
+ # ==== Parameters
95
+ # * +options+ - [Hash] List of {Resource collection Options}[#class-Mints::Pub-label-Resource+collections+options+] shown above can be used as parameter
96
+ def get_content_templates(options = nil)
97
+ return @client.raw("get", "/content/content-templates", options)
98
+ end
99
+
100
+ ##
101
+ # === Get Content Template.
102
+ # Get a single content template.
103
+ #
104
+ # ==== Parameters
105
+ # * +slug+ - [String] It's the string identifier generated by Mints
106
+ # * +options+ - [Hash] List of {Single Resource Options}[#class-Mints::Pub-label-Single+resource+options] shown above can be used as parameter
107
+ def get_content_template(slug, options = nil)
108
+ return @client.raw("get", "/content/content-templates/#{slug}", options)
109
+ end
110
+
111
+ ##
112
+ # === Get Content Instances.
113
+ # Get a collection of content instances
114
+ #
115
+ # ==== Parameters
116
+ # * +options+ - [Hash] List of {Resource collection Options}[#class-Mints::Pub-label-Resource+collections+options+] shown above can be used as parameter
117
+ def get_content_instances(options)
118
+ return @client.raw("get", "/content/content-instances", options)
119
+ end
120
+
121
+ ##
122
+ # === Get Content Instance.
123
+ # Get a single content instance.
124
+ #
125
+ # ==== Parameters
126
+ # * +slug+ - [String] It's the string identifier generated by Mints
127
+ # * +options+ - [Hash] List of {Single Resource Options}[#class-Mints::Pub-label-Single+resource+options] shown above can be used as parameter
128
+ def get_content_instance(slug, options = nil)
129
+ return @client.raw("get", "/content/content-instances/#{slug}", options)
130
+ end
131
+
132
+ ##
133
+ # === Get Stories.
134
+ # Get a collection of stories
135
+ #
136
+ # ==== Parameters
137
+ # * +options+ - [Hash] List of {Resource collection Options}[#class-Mints::Pub-label-Resource+collections+options+] shown above can be used as parameter
138
+ def get_stories(options = nil)
139
+ return @client.raw("get", "/content/stories", options)
140
+ end
141
+
142
+ ##
143
+ # === Get Story.
144
+ # Get a single story.
145
+ #
146
+ # ==== Parameters
147
+ # * +slug+ - [String] It's the string identifier generated by Mints
148
+ # * +options+ - [Hash] List of {Single Resource Options}[#class-Mints::Pub-label-Single+resource+options] shown above can be used as parameter
149
+ def get_story(slug, options = nil)
150
+ return @client.raw("get", "/content/stories/#{slug}", options)
16
151
  end
17
152
 
18
- def register_visit_timer
19
- return @client.raw("get", "/register-visit-timer")
153
+ ##
154
+ # === Get Forms.
155
+ # Get a collection of forms
156
+ #
157
+ # ==== Parameters
158
+ # * +options+ - [Hash] List of {Resource collection Options}[#class-Mints::Pub-label-Resource+collections+options+] shown above can be used as parameter
159
+ def get_forms(options = nil)
160
+ return @client.raw("get", "/content/forms", options)
20
161
  end
21
162
 
22
- def get_content_page
23
- return @client.raw("get", "/content-pages/#{slug}")
163
+ ##
164
+ # === Get Form.
165
+ # Get a single form.
166
+ #
167
+ # ==== Parameters
168
+ # * +slug+ - [String] It's the string identifier generated by Mints
169
+ # * +options+ - [Hash] List of {Single Resource Options}[#class-Mints::Pub-label-Single+resource+options] shown above can be used as parameter
170
+ def get_form(slug, options = nil)
171
+ return @client.raw("get", "/content/forms/#{slug}", options)
172
+ end
173
+
174
+ ##
175
+ # === Submit Form.
176
+ # Submit a form.
177
+ #
178
+ # ==== Parameters
179
+ # * +data+ - [Hash] Data to be submited
180
+ def submit_form(data)
181
+ return @client.raw("post", "/forms/store", nil, data)
182
+ end
183
+
184
+ ##
185
+ # === Get Products.
186
+ # Get a collection of products.
187
+ #
188
+ # ==== Parameters
189
+ # * +options+ - [Hash] List of {Resource collection Options}[#class-Mints::Pub-label-Resource+collections+options+] shown above can be used as parameter
190
+ def get_products(options = nil)
191
+ return @client.raw("get", "/ecommerce/products", options)
192
+ end
193
+
194
+ ##
195
+ # === Get Product.
196
+ # Get a single product.
197
+ #
198
+ # ==== Parameters
199
+ # * +slug+ - [String] It's the string identifier generated by Mints
200
+ # * +options+ - [Hash] List of {Single Resource Options}[#class-Mints::Pub-label-Single+resource+options] shown above can be used as parameter
201
+ def get_product(slug, options = nil)
202
+ return @client.raw("get", "/ecommerce/products/#{slug}", options)
203
+ end
204
+
205
+ ##
206
+ # === Get Product Brands.
207
+ # Get a collection of product brands.
208
+ #
209
+ # ==== Parameters
210
+ # * +options+ - [Hash] List of {Resource collection Options}[#class-Mints::Pub-label-Resource+collections+options+] shown above can be used as parameter
211
+ def get_product_brands(options = nil)
212
+ return @client.raw("get", "/ecommerce/product-brands", options)
213
+ end
214
+
215
+ ##
216
+ # === Get Product Brand.
217
+ # Get a product brand.
218
+ #
219
+ # ==== Parameters
220
+ # * +slug+ - [String] It's the string identifier generated by Mints
221
+ # * +options+ - [Hash] List of {Single Resource Options}[#class-Mints::Pub-label-Single+resource+options] shown above can be used as parameter
222
+ def get_product_brand(slug, options = nil)
223
+ return @client.raw("get", "/ecommerce/product-brands/#{slug}", options)
224
+ end
225
+
226
+ ##
227
+ # === Get SKUs.
228
+ # Get a collection of SKUs.
229
+ #
230
+ # ==== Parameters
231
+ # * +options+ - [Hash] List of {Resource collection Options}[#class-Mints::Pub-label-Resource+collections+options+] shown above can be used as parameter
232
+ def get_skus(options = nil)
233
+ return @client.raw("get", "/ecommerce/skus", options)
234
+ end
235
+
236
+ ##
237
+ # === Get SKU.
238
+ # Get a single SKU.
239
+ #
240
+ # ==== Parameters
241
+ # * +slug+ - [String] It's the string identifier generated by Mints
242
+ # * +options+ - [Hash] List of {Single Resource Options}[#class-Mints::Pub-label-Single+resource+options] shown above can be used as parameter
243
+ def get_sku(slug, options = nil)
244
+ return @client.raw("get", "/ecommerce/skus/#{slug}", options)
245
+ end
246
+
247
+ ##
248
+ # === Get categories.
249
+ # Get a collection of categories.
250
+ #
251
+ # ==== Parameters
252
+ # * +options+ - [Hash] List of {Resource collection Options}[#class-Mints::Pub-label-Resource+collections+options+] shown above can be used as parameter
253
+ def get_categories(options = nil)
254
+ return @client.raw("get", "/config/categories", options)
24
255
  end
25
256
 
26
- def get_content_template
27
- return @client.raw("get", "/content/content-templates/#{slug}")
257
+ ##
258
+ # === Get Category.
259
+ # Get a single category
260
+ #
261
+ # ==== Parameters
262
+ # * +slug+ - [String] It's the string identifier generated by Mints
263
+ # * +options+ - [Hash] List of {Single Resource Options}[#class-Mints::Pub-label-Single+resource+options] shown above can be used as parameter
264
+ def get_category(slug, options = nil)
265
+ return @client.raw("get", "/config/categories/#{slug}", options)
28
266
  end
29
267
 
30
- def content_instance
31
- return @client.raw("get", "/content/content-instances/#{slug}")
268
+ ##
269
+ # === Get Tags.
270
+ # Get a collection of tags.
271
+ #
272
+ # ==== Parameters
273
+ # * +options+ - [Hash] List of {Resource collection Options}[#class-Mints::Pub-label-Resource+collections+options+] shown above can be used as parameter
274
+ def get_tags(options = nil)
275
+ return @client.raw("get", "/config/tags", options)
32
276
  end
33
277
 
34
- def get_stories
35
- return @client.raw("get", "/content/stories")
278
+ ##
279
+ # === Get Tag.
280
+ # Get a single tag
281
+ #
282
+ # ==== Parameters
283
+ # * +slug+ - [String] It's the string identifier generated by Mints
284
+ # * +options+ - [Hash] List of {Single Resource Options}[#class-Mints::Pub-label-Single+resource+options] shown above can be used as parameter
285
+ def get_tag(slug, options = nil)
286
+ return @client.raw("get", "/config/tags/#{slug}", options)
36
287
  end
37
288
 
38
- def get_story(slug)
39
- return @client.raw("get", "/content/stories/#{slug}")
289
+ ##
290
+ # === Get Attributes.
291
+ # Get a collection of attributes.
292
+ #
293
+ # ==== Parameters
294
+ # * +options+ - [Hash] List of {Resource collection Options}[#class-Mints::Pub-label-Resource+collections+options+] shown above can be used as parameter
295
+ def get_attributes(options = nil)
296
+ return @client.raw("get", "/config/attributes", options)
40
297
  end
41
298
 
42
- def get_form
43
- return @client.raw("get", "/content/forms/{slug}")
299
+ ##
300
+ # === Get Taxonomies.
301
+ # Get a collection of taxonomies.
302
+ #
303
+ # ==== Parameters
304
+ # * +options+ - [Hash] List of {Resource collection Options}[#class-Mints::Pub-label-Resource+collections+options+] shown above can be used as parameter
305
+ def get_taxonomies(options = nil)
306
+ return @client.raw("get", "/config/taxonomies", options)
44
307
  end
45
308
 
46
- def submit_form
47
- return @client.raw("post", "/forms/store", data)
309
+ ##
310
+ # === Get Taxonomy.
311
+ # Get a single taxonomy
312
+ #
313
+ # ==== Parameters
314
+ # * +slug+ - [String] It's the string identifier generated by Mints
315
+ # * +options+ - [Hash] List of {Single Resource Options}[#class-Mints::Pub-label-Single+resource+options] shown above can be used as parameter
316
+ def get_taxonomy(slug, options = nil)
317
+ return @client.raw("get", "/config/taxonomies/#{slug}", options)
48
318
  end
49
319
  end
50
320
  end