test_track_rails_client 0.9.7 → 0.9.8

Sign up to get free protection for your applications and to get access to all the features.
Files changed (113) hide show
  1. checksums.yaml +8 -8
  2. data/README.md +11 -8
  3. data/lib/test_track_rails_client/version.rb +1 -1
  4. data/vendor/gems/fakeable_her/fakeable_her.gemspec +22 -0
  5. data/vendor/gems/fakeable_her/lib/fakeable_her/model.rb +148 -0
  6. data/vendor/gems/fakeable_her/lib/fakeable_her/version.rb +3 -0
  7. data/vendor/gems/fakeable_her/lib/fakeable_her.rb +5 -0
  8. data/vendor/gems/her/CONTRIBUTING.md +26 -0
  9. data/vendor/gems/her/Gemfile +10 -0
  10. data/vendor/gems/her/LICENSE +7 -0
  11. data/vendor/gems/her/README.md +1023 -0
  12. data/vendor/gems/her/Rakefile +11 -0
  13. data/vendor/gems/her/UPGRADE.md +101 -0
  14. data/vendor/gems/her/gemfiles/Gemfile.activemodel-3.2.x +7 -0
  15. data/vendor/gems/her/gemfiles/Gemfile.activemodel-4.0 +7 -0
  16. data/vendor/gems/her/gemfiles/Gemfile.activemodel-4.1 +7 -0
  17. data/vendor/gems/her/gemfiles/Gemfile.activemodel-4.2 +7 -0
  18. data/vendor/gems/her/her.gemspec +31 -0
  19. data/vendor/gems/her/lib/her/api.rb +119 -0
  20. data/vendor/gems/her/lib/her/collection.rb +12 -0
  21. data/vendor/gems/her/lib/her/error_collection.rb +15 -0
  22. data/vendor/gems/her/lib/her/errors.rb +40 -0
  23. data/vendor/gems/her/lib/her/json_api/model.rb +46 -0
  24. data/vendor/gems/her/lib/her/middleware/accept_json.rb +17 -0
  25. data/vendor/gems/her/lib/her/middleware/first_level_parse_json.rb +36 -0
  26. data/vendor/gems/her/lib/her/middleware/json_api_parser.rb +36 -0
  27. data/vendor/gems/her/lib/her/middleware/parse_json.rb +21 -0
  28. data/vendor/gems/her/lib/her/middleware/second_level_parse_json.rb +36 -0
  29. data/vendor/gems/her/lib/her/middleware.rb +12 -0
  30. data/vendor/gems/her/lib/her/model/active_model_overrides.rb +13 -0
  31. data/vendor/gems/her/lib/her/model/associations/association.rb +106 -0
  32. data/vendor/gems/her/lib/her/model/associations/association_proxy.rb +46 -0
  33. data/vendor/gems/her/lib/her/model/associations/belongs_to_association.rb +96 -0
  34. data/vendor/gems/her/lib/her/model/associations/has_many_association.rb +100 -0
  35. data/vendor/gems/her/lib/her/model/associations/has_one_association.rb +79 -0
  36. data/vendor/gems/her/lib/her/model/associations.rb +141 -0
  37. data/vendor/gems/her/lib/her/model/attributes.rb +304 -0
  38. data/vendor/gems/her/lib/her/model/base.rb +33 -0
  39. data/vendor/gems/her/lib/her/model/deprecated_methods.rb +61 -0
  40. data/vendor/gems/her/lib/her/model/http.rb +117 -0
  41. data/vendor/gems/her/lib/her/model/introspection.rb +65 -0
  42. data/vendor/gems/her/lib/her/model/nested_attributes.rb +45 -0
  43. data/vendor/gems/her/lib/her/model/orm.rb +219 -0
  44. data/vendor/gems/her/lib/her/model/parse.rb +215 -0
  45. data/vendor/gems/her/lib/her/model/paths.rb +126 -0
  46. data/vendor/gems/her/lib/her/model/relation.rb +251 -0
  47. data/vendor/gems/her/lib/her/model.rb +81 -0
  48. data/vendor/gems/her/lib/her/version.rb +3 -0
  49. data/vendor/gems/her/lib/her.rb +20 -0
  50. data/vendor/gems/her/spec/api_spec.rb +114 -0
  51. data/vendor/gems/her/spec/collection_spec.rb +26 -0
  52. data/vendor/gems/her/spec/error_collection_spec.rb +33 -0
  53. data/vendor/gems/her/spec/json_api/model_spec.rb +168 -0
  54. data/vendor/gems/her/spec/middleware/accept_json_spec.rb +10 -0
  55. data/vendor/gems/her/spec/middleware/first_level_parse_json_spec.rb +62 -0
  56. data/vendor/gems/her/spec/middleware/json_api_parser_spec.rb +32 -0
  57. data/vendor/gems/her/spec/middleware/second_level_parse_json_spec.rb +35 -0
  58. data/vendor/gems/her/spec/model/associations/association_proxy_spec.rb +31 -0
  59. data/vendor/gems/her/spec/model/associations_spec.rb +504 -0
  60. data/vendor/gems/her/spec/model/attributes_spec.rb +404 -0
  61. data/vendor/gems/her/spec/model/callbacks_spec.rb +145 -0
  62. data/vendor/gems/her/spec/model/dirty_spec.rb +110 -0
  63. data/vendor/gems/her/spec/model/http_spec.rb +165 -0
  64. data/vendor/gems/her/spec/model/introspection_spec.rb +76 -0
  65. data/vendor/gems/her/spec/model/nested_attributes_spec.rb +134 -0
  66. data/vendor/gems/her/spec/model/orm_spec.rb +791 -0
  67. data/vendor/gems/her/spec/model/parse_spec.rb +372 -0
  68. data/vendor/gems/her/spec/model/paths_spec.rb +347 -0
  69. data/vendor/gems/her/spec/model/relation_spec.rb +226 -0
  70. data/vendor/gems/her/spec/model/validations_spec.rb +42 -0
  71. data/vendor/gems/her/spec/model_spec.rb +31 -0
  72. data/vendor/gems/her/spec/spec_helper.rb +27 -0
  73. data/vendor/gems/her/spec/support/extensions/array.rb +5 -0
  74. data/vendor/gems/her/spec/support/extensions/hash.rb +5 -0
  75. data/vendor/gems/her/spec/support/macros/her_macros.rb +17 -0
  76. data/vendor/gems/her/spec/support/macros/model_macros.rb +36 -0
  77. data/vendor/gems/her/spec/support/macros/request_macros.rb +27 -0
  78. data/vendor/gems/publicsuffix-ruby/CHANGELOG.md +236 -0
  79. data/vendor/gems/publicsuffix-ruby/Gemfile +3 -0
  80. data/vendor/gems/publicsuffix-ruby/LICENSE.txt +22 -0
  81. data/vendor/gems/publicsuffix-ruby/README.md +151 -0
  82. data/vendor/gems/publicsuffix-ruby/Rakefile +109 -0
  83. data/vendor/gems/publicsuffix-ruby/lib/definitions.txt +11467 -0
  84. data/vendor/gems/publicsuffix-ruby/lib/public_suffix/domain.rb +387 -0
  85. data/vendor/gems/publicsuffix-ruby/lib/public_suffix/errors.rb +53 -0
  86. data/vendor/gems/publicsuffix-ruby/lib/public_suffix/list.rb +302 -0
  87. data/vendor/gems/publicsuffix-ruby/lib/public_suffix/rule.rb +373 -0
  88. data/vendor/gems/publicsuffix-ruby/lib/public_suffix/version.rb +23 -0
  89. data/vendor/gems/publicsuffix-ruby/lib/public_suffix.rb +131 -0
  90. data/vendor/gems/publicsuffix-ruby/public_suffix.gemspec +39 -0
  91. data/vendor/gems/publicsuffix-ruby/test/acceptance_test.rb +42 -0
  92. data/vendor/gems/publicsuffix-ruby/test/test_helper.rb +6 -0
  93. data/vendor/gems/publicsuffix-ruby/test/unit/domain_test.rb +170 -0
  94. data/vendor/gems/publicsuffix-ruby/test/unit/errors_test.rb +23 -0
  95. data/vendor/gems/publicsuffix-ruby/test/unit/list_test.rb +179 -0
  96. data/vendor/gems/publicsuffix-ruby/test/unit/public_suffix_test.rb +115 -0
  97. data/vendor/gems/publicsuffix-ruby/test/unit/rule_test.rb +307 -0
  98. data/vendor/gems/ruby_spec_helpers/lib/ruby_spec_helpers/capybara_configuration.rb +98 -0
  99. data/vendor/gems/ruby_spec_helpers/lib/ruby_spec_helpers/matchers.rb +151 -0
  100. data/vendor/gems/ruby_spec_helpers/lib/ruby_spec_helpers/rspec_configuration.rb +34 -0
  101. data/vendor/gems/ruby_spec_helpers/lib/ruby_spec_helpers/rubocop/cop/betterment/html_safe.rb +15 -0
  102. data/vendor/gems/ruby_spec_helpers/lib/ruby_spec_helpers/rubocop/cop/betterment/raw.rb +15 -0
  103. data/vendor/gems/ruby_spec_helpers/lib/ruby_spec_helpers/rubocop/cop/betterment/safe_concat.rb +15 -0
  104. data/vendor/gems/ruby_spec_helpers/lib/ruby_spec_helpers/rubocop.rb +3 -0
  105. data/vendor/gems/ruby_spec_helpers/lib/ruby_spec_helpers/shared_examples/betterment_application_examples.rb +47 -0
  106. data/vendor/gems/ruby_spec_helpers/lib/ruby_spec_helpers/shared_examples.rb +1 -0
  107. data/vendor/gems/ruby_spec_helpers/lib/ruby_spec_helpers/site_prism_configuration.rb +42 -0
  108. data/vendor/gems/ruby_spec_helpers/lib/ruby_spec_helpers/site_prism_dropdown.rb +17 -0
  109. data/vendor/gems/ruby_spec_helpers/lib/ruby_spec_helpers/version.rb +3 -0
  110. data/vendor/gems/ruby_spec_helpers/lib/ruby_spec_helpers/webmock_configuration.rb +8 -0
  111. data/vendor/gems/ruby_spec_helpers/lib/ruby_spec_helpers.rb +2 -0
  112. data/vendor/gems/ruby_spec_helpers/ruby_spec_helpers.gemspec +25 -0
  113. metadata +110 -1
@@ -0,0 +1,387 @@
1
+ #--
2
+ # Public Suffix
3
+ #
4
+ # Domain name parser based on the Public Suffix List.
5
+ #
6
+ # Copyright (c) 2009-2014 Simone Carletti <weppos@weppos.net>
7
+ #++
8
+
9
+
10
+ module PublicSuffix
11
+
12
+ class Domain
13
+
14
+ # Splits a string into its possible labels
15
+ # as a domain in reverse order from the input string.
16
+ #
17
+ # The input is not validated, but it is assumed to be a valid domain.
18
+ #
19
+ # @param [String, #to_s] domain
20
+ # The domain name to split.
21
+ #
22
+ # @return [Array<String>]
23
+ #
24
+ # @example
25
+ #
26
+ # domain_to_labels('google.com')
27
+ # # => ['com', 'google']
28
+ #
29
+ # domain_to_labels('google.co.uk')
30
+ # # => ['uk', 'co', 'google']
31
+ #
32
+ def self.domain_to_labels(domain)
33
+ domain.to_s.split(".").reverse
34
+ end
35
+
36
+ # Creates and returns a new {PublicSuffix::Domain} instance.
37
+ #
38
+ # @overload initialize(tld)
39
+ # Initializes with a +tld+.
40
+ # @param [String] tld The TLD (extension)
41
+ # @overload initialize(tld, sld)
42
+ # Initializes with a +tld+ and +sld+.
43
+ # @param [String] tld The TLD (extension)
44
+ # @param [String] sld The TRD (domain)
45
+ # @overload initialize(tld, sld, trd)
46
+ # Initializes with a +tld+, +sld+ and +trd+.
47
+ # @param [String] tld The TLD (extension)
48
+ # @param [String] sld The SLD (domain)
49
+ # @param [String] tld The TRD (subdomain)
50
+ #
51
+ # @yield [self] Yields on self.
52
+ # @yieldparam [PublicSuffix::Domain] self The newly creates instance
53
+ #
54
+ # @example Initialize with a TLD
55
+ # PublicSuffix::Domain.new("com")
56
+ # # => #<PublicSuffix::Domain @tld="com">
57
+ #
58
+ # @example Initialize with a TLD and SLD
59
+ # PublicSuffix::Domain.new("com", "example")
60
+ # # => #<PublicSuffix::Domain @tld="com", @trd=nil>
61
+ #
62
+ # @example Initialize with a TLD, SLD and TRD
63
+ # PublicSuffix::Domain.new("com", "example", "wwww")
64
+ # # => #<PublicSuffix::Domain @tld="com", @trd=nil, @sld="example">
65
+ #
66
+ def initialize(*args, &block)
67
+ @tld, @sld, @trd = args
68
+ yield(self) if block_given?
69
+ end
70
+
71
+ # Returns a string representation of this object.
72
+ #
73
+ # @return [String]
74
+ def to_s
75
+ name
76
+ end
77
+
78
+ # Returns an array containing the domain parts.
79
+ #
80
+ # @return [Array<String, nil>]
81
+ #
82
+ # @example
83
+ #
84
+ # PublicSuffix::Domain.new("google.com").to_a
85
+ # # => [nil, "google", "com"]
86
+ #
87
+ # PublicSuffix::Domain.new("www.google.com").to_a
88
+ # # => [nil, "google", "com"]
89
+ #
90
+ def to_a
91
+ [trd, sld, tld]
92
+ end
93
+
94
+
95
+ # Returns the Top Level Domain part, aka the extension.
96
+ #
97
+ # @return [String, nil]
98
+ def tld
99
+ @tld
100
+ end
101
+
102
+ # Returns the Second Level Domain part, aka the domain part.
103
+ #
104
+ # @return [String, nil]
105
+ def sld
106
+ @sld
107
+ end
108
+
109
+ # Returns the Third Level Domain part, aka the subdomain part.
110
+ #
111
+ # @return [String, nil]
112
+ def trd
113
+ @trd
114
+ end
115
+
116
+
117
+ # Returns the full domain name.
118
+ #
119
+ # @return [String]
120
+ #
121
+ # @example Gets the domain name of a domain
122
+ # PublicSuffix::Domain.new("com", "google").name
123
+ # # => "google.com"
124
+ #
125
+ # @example Gets the domain name of a subdomain
126
+ # PublicSuffix::Domain.new("com", "google", "www").name
127
+ # # => "www.google.com"
128
+ #
129
+ def name
130
+ [trd, sld, tld].reject { |part| part.nil? }.join(".")
131
+ end
132
+
133
+ # Returns a domain-like representation of this object
134
+ # if the object is a {#domain?}, <tt>nil</tt> otherwise.
135
+ #
136
+ # PublicSuffix::Domain.new("com").domain
137
+ # # => nil
138
+ #
139
+ # PublicSuffix::Domain.new("com", "google").domain
140
+ # # => "google.com"
141
+ #
142
+ # PublicSuffix::Domain.new("com", "google", "www").domain
143
+ # # => "www.google.com"
144
+ #
145
+ # This method doesn't validate the input. It handles the domain
146
+ # as a valid domain name and simply applies the necessary transformations.
147
+ #
148
+ # # This is an invalid domain
149
+ # PublicSuffix::Domain.new("qqq", "google").domain
150
+ # # => "google.qqq"
151
+ #
152
+ # This method returns a FQD, not just the domain part.
153
+ # To get the domain part, use <tt>#sld</tt> (aka second level domain).
154
+ #
155
+ # PublicSuffix::Domain.new("com", "google", "www").domain
156
+ # # => "google.com"
157
+ #
158
+ # PublicSuffix::Domain.new("com", "google", "www").sld
159
+ # # => "google"
160
+ #
161
+ # @return [String]
162
+ #
163
+ # @see #domain?
164
+ # @see #subdomain
165
+ #
166
+ def domain
167
+ return unless domain?
168
+ [sld, tld].join(".")
169
+ end
170
+
171
+ # Returns a domain-like representation of this object
172
+ # if the object is a {#subdomain?}, <tt>nil</tt> otherwise.
173
+ #
174
+ # PublicSuffix::Domain.new("com").subdomain
175
+ # # => nil
176
+ #
177
+ # PublicSuffix::Domain.new("com", "google").subdomain
178
+ # # => nil
179
+ #
180
+ # PublicSuffix::Domain.new("com", "google", "www").subdomain
181
+ # # => "www.google.com"
182
+ #
183
+ # This method doesn't validate the input. It handles the domain
184
+ # as a valid domain name and simply applies the necessary transformations.
185
+ #
186
+ # # This is an invalid domain
187
+ # PublicSuffix::Domain.new("qqq", "google", "www").subdomain
188
+ # # => "www.google.qqq"
189
+ #
190
+ # This method returns a FQD, not just the domain part.
191
+ # To get the subdomain part, use <tt>#trd</tt> (aka third level domain).
192
+ #
193
+ # PublicSuffix::Domain.new("com", "google", "www").subdomain
194
+ # # => "www.google.com"
195
+ #
196
+ # PublicSuffix::Domain.new("com", "google", "www").trd
197
+ # # => "www"
198
+ #
199
+ # @return [String]
200
+ #
201
+ # @see #subdomain?
202
+ # @see #domain
203
+ #
204
+ def subdomain
205
+ return unless subdomain?
206
+ [trd, sld, tld].join(".")
207
+ end
208
+
209
+ # Returns the rule matching this domain
210
+ # in the default {PublicSuffix::List}.
211
+ #
212
+ # @return [PublicSuffix::Rule::Base, nil]
213
+ # The rule instance a rule matches current domain,
214
+ # nil if no rule is found.
215
+ def rule
216
+ List.default.find(name)
217
+ end
218
+
219
+
220
+ # Checks whether <tt>self</tt> looks like a domain.
221
+ #
222
+ # This method doesn't actually validate the domain.
223
+ # It only checks whether the instance contains
224
+ # a value for the {#tld} and {#sld} attributes.
225
+ # If you also want to validate the domain,
226
+ # use {#valid_domain?} instead.
227
+ #
228
+ # @return [Boolean]
229
+ #
230
+ # @example
231
+ #
232
+ # PublicSuffix::Domain.new("com").domain?
233
+ # # => false
234
+ #
235
+ # PublicSuffix::Domain.new("com", "google").domain?
236
+ # # => true
237
+ #
238
+ # PublicSuffix::Domain.new("com", "google", "www").domain?
239
+ # # => true
240
+ #
241
+ # # This is an invalid domain, but returns true
242
+ # # because this method doesn't validate the content.
243
+ # PublicSuffix::Domain.new("qqq", "google").domain?
244
+ # # => true
245
+ #
246
+ # @see #subdomain?
247
+ #
248
+ def domain?
249
+ !(tld.nil? || sld.nil?)
250
+ end
251
+
252
+ # Checks whether <tt>self</tt> looks like a subdomain.
253
+ #
254
+ # This method doesn't actually validate the subdomain.
255
+ # It only checks whether the instance contains
256
+ # a value for the {#tld}, {#sld} and {#trd} attributes.
257
+ # If you also want to validate the domain,
258
+ # use {#valid_subdomain?} instead.
259
+ #
260
+ # @return [Boolean]
261
+ #
262
+ # @example
263
+ #
264
+ # PublicSuffix::Domain.new("com").subdomain?
265
+ # # => false
266
+ #
267
+ # PublicSuffix::Domain.new("com", "google").subdomain?
268
+ # # => false
269
+ #
270
+ # PublicSuffix::Domain.new("com", "google", "www").subdomain?
271
+ # # => true
272
+ #
273
+ # # This is an invalid domain, but returns true
274
+ # # because this method doesn't validate the content.
275
+ # PublicSuffix::Domain.new("qqq", "google", "www").subdomain?
276
+ # # => true
277
+ #
278
+ # @see #domain?
279
+ #
280
+ def subdomain?
281
+ !(tld.nil? || sld.nil? || trd.nil?)
282
+ end
283
+
284
+ # Checks whether <tt>self</tt> is exclusively a domain,
285
+ # and not a subdomain.
286
+ #
287
+ # @return [Boolean]
288
+ def is_a_domain?
289
+ domain? && !subdomain?
290
+ end
291
+
292
+ # Checks whether <tt>self</tt> is exclusively a subdomain.
293
+ #
294
+ # @return [Boolean]
295
+ def is_a_subdomain?
296
+ subdomain?
297
+ end
298
+
299
+ # Checks whether <tt>self</tt> is assigned and allowed
300
+ # according to default {List}.
301
+ #
302
+ # This method triggers a new rule lookup in the default {List},
303
+ # which is a quite intensive task.
304
+ #
305
+ # @return [Boolean]
306
+ #
307
+ # @example Check a valid domain
308
+ # Domain.new("com", "example").valid?
309
+ # # => true
310
+ #
311
+ # @example Check a valid subdomain
312
+ # Domain.new("com", "example", "www").valid?
313
+ # # => true
314
+ #
315
+ # @example Check a not-assigned domain
316
+ # Domain.new("qqq", "example").valid?
317
+ # # => false
318
+ #
319
+ # @example Check a not-allowed domain
320
+ # Domain.new("do", "example").valid?
321
+ # # => false
322
+ # Domain.new("do", "example", "www").valid?
323
+ # # => true
324
+ #
325
+ def valid?
326
+ r = rule
327
+ !r.nil? && r.allow?(name)
328
+ end
329
+
330
+
331
+ # Checks whether <tt>self</tt> looks like a domain and validates
332
+ # according to default {List}.
333
+ #
334
+ # @return [Boolean]
335
+ #
336
+ # @example
337
+ #
338
+ # PublicSuffix::Domain.new("com").domain?
339
+ # # => false
340
+ #
341
+ # PublicSuffix::Domain.new("com", "google").domain?
342
+ # # => true
343
+ #
344
+ # PublicSuffix::Domain.new("com", "google", "www").domain?
345
+ # # => true
346
+ #
347
+ # # This is an invalid domain
348
+ # PublicSuffix::Domain.new("qqq", "google").false?
349
+ # # => true
350
+ #
351
+ # @see #domain?
352
+ # @see #valid?
353
+ #
354
+ def valid_domain?
355
+ domain? && valid?
356
+ end
357
+
358
+ # Checks whether <tt>self</tt> looks like a subdomain and validates
359
+ # according to default {List}.
360
+ #
361
+ # @return [Boolean]
362
+ #
363
+ # @example
364
+ #
365
+ # PublicSuffix::Domain.new("com").subdomain?
366
+ # # => false
367
+ #
368
+ # PublicSuffix::Domain.new("com", "google").subdomain?
369
+ # # => false
370
+ #
371
+ # PublicSuffix::Domain.new("com", "google", "www").subdomain?
372
+ # # => true
373
+ #
374
+ # # This is an invalid domain
375
+ # PublicSuffix::Domain.new("qqq", "google", "www").subdomain?
376
+ # # => false
377
+ #
378
+ # @see #subdomain?
379
+ # @see #valid?
380
+ #
381
+ def valid_subdomain?
382
+ subdomain? && valid?
383
+ end
384
+
385
+ end
386
+
387
+ end
@@ -0,0 +1,53 @@
1
+ #--
2
+ # Public Suffix
3
+ #
4
+ # Domain name parser based on the Public Suffix List.
5
+ #
6
+ # Copyright (c) 2009-2014 Simone Carletti <weppos@weppos.net>
7
+ #++
8
+
9
+
10
+ module PublicSuffix
11
+
12
+ class Error < StandardError
13
+ end
14
+
15
+ # Raised when trying to parse an invalid domain.
16
+ # A domain is considered invalid when no rule is found
17
+ # in the definition list.
18
+ #
19
+ # @example
20
+ #
21
+ # PublicSuffix.parse("nic.test")
22
+ # # => PublicSuffix::DomainInvalid
23
+ #
24
+ # PublicSuffix.parse("http://www.nic.it")
25
+ # # => PublicSuffix::DomainInvalid
26
+ #
27
+ class DomainInvalid < Error
28
+ end
29
+
30
+ # Raised when trying to parse a domain
31
+ # which is formally defined by a rule,
32
+ # but the rules set a requirement which is not satisfied
33
+ # by the input you are trying to parse.
34
+ #
35
+ # @example
36
+ #
37
+ # PublicSuffix.parse("nic.do")
38
+ # # => PublicSuffix::DomainNotAllowed
39
+ #
40
+ # PublicSuffix.parse("www.nic.do")
41
+ # # => PublicSuffix::Domain
42
+ #
43
+ class DomainNotAllowed < DomainInvalid
44
+ end
45
+
46
+
47
+ # Backward Compatibility
48
+ #
49
+ # @deprecated Use {PublicSuffix::DomainInvalid}.
50
+ #
51
+ InvalidDomain = DomainInvalid
52
+
53
+ end