opal 1.3.2 → 1.4.0.alpha1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (222) hide show
  1. checksums.yaml +4 -4
  2. data/.eslintrc.js +1 -0
  3. data/.github/workflows/build.yml +0 -3
  4. data/.rubocop.yml +5 -1
  5. data/UNRELEASED.md +66 -2
  6. data/benchmark-ips/bm_truthy.rb +30 -0
  7. data/bin/opal-mspec +1 -3
  8. data/bin/opal-repl +1 -2
  9. data/bin/remove-filters +1 -4
  10. data/docs/compiled_ruby.md +10 -6
  11. data/exe/opal-repl +1 -3
  12. data/lib/opal/ast/builder.rb +1 -1
  13. data/lib/opal/cli.rb +2 -2
  14. data/lib/opal/cli_runners/nodejs.rb +9 -2
  15. data/lib/opal/cli_runners/source-map-support-browser.js +80 -216
  16. data/lib/opal/cli_runners/source-map-support-node.js +80 -216
  17. data/lib/opal/cli_runners/source-map-support.js +5 -1
  18. data/lib/opal/cli_runners/system_runner.rb +10 -4
  19. data/lib/opal/compiler.rb +3 -5
  20. data/lib/opal/fragment.rb +5 -1
  21. data/lib/opal/nodes/args/extract_block_arg.rb +1 -8
  22. data/lib/opal/nodes/args/extract_kwoptarg.rb +1 -3
  23. data/lib/opal/nodes/args/extract_optarg.rb +1 -3
  24. data/lib/opal/nodes/args/extract_post_arg.rb +2 -5
  25. data/lib/opal/nodes/args/extract_post_optarg.rb +2 -7
  26. data/lib/opal/nodes/args/initialize_iterarg.rb +1 -3
  27. data/lib/opal/nodes/args/prepare_post_args.rb +5 -1
  28. data/lib/opal/nodes/base.rb +3 -2
  29. data/lib/opal/nodes/call.rb +20 -9
  30. data/lib/opal/nodes/call_special.rb +50 -0
  31. data/lib/opal/nodes/class.rb +24 -15
  32. data/lib/opal/nodes/constants.rb +23 -5
  33. data/lib/opal/nodes/def.rb +20 -23
  34. data/lib/opal/nodes/defined.rb +5 -5
  35. data/lib/opal/nodes/definitions.rb +2 -2
  36. data/lib/opal/nodes/defs.rb +2 -5
  37. data/lib/opal/nodes/helpers.rb +48 -18
  38. data/lib/opal/nodes/if.rb +109 -8
  39. data/lib/opal/nodes/iter.rb +23 -16
  40. data/lib/opal/nodes/literal.rb +18 -4
  41. data/lib/opal/nodes/logic.rb +2 -1
  42. data/lib/opal/nodes/masgn.rb +4 -9
  43. data/lib/opal/nodes/module.rb +29 -19
  44. data/lib/opal/nodes/node_with_args.rb +1 -7
  45. data/lib/opal/nodes/scope.rb +54 -15
  46. data/lib/opal/nodes/singleton_class.rb +5 -3
  47. data/lib/opal/nodes/super.rb +3 -3
  48. data/lib/opal/nodes/top.rb +34 -31
  49. data/lib/opal/nodes/variables.rb +2 -2
  50. data/lib/opal/nodes/x_string.rb +3 -0
  51. data/lib/opal/nodes.rb +0 -1
  52. data/lib/opal/parser/patch.rb +75 -0
  53. data/lib/opal/parser/with_ruby_lexer.rb +1 -1
  54. data/lib/opal/regexp_anchors.rb +7 -7
  55. data/lib/opal/requires.rb +19 -0
  56. data/lib/opal/rewriters/pattern_matching.rb +1 -1
  57. data/lib/opal/rewriters/returnable_logic.rb +102 -4
  58. data/lib/opal/util.rb +2 -2
  59. data/lib/opal/version.rb +1 -1
  60. data/lib/opal.rb +1 -17
  61. data/opal/corelib/array/pack.rb +11 -11
  62. data/opal/corelib/array.rb +193 -152
  63. data/opal/corelib/basic_object.rb +14 -14
  64. data/opal/corelib/binding.rb +7 -7
  65. data/opal/corelib/boolean.rb +12 -15
  66. data/opal/corelib/class.rb +23 -1
  67. data/opal/corelib/comparable.rb +8 -8
  68. data/opal/corelib/complex/base.rb +2 -2
  69. data/opal/corelib/complex.rb +79 -88
  70. data/opal/corelib/constants.rb +9 -9
  71. data/opal/corelib/dir.rb +4 -3
  72. data/opal/corelib/enumerable.rb +140 -127
  73. data/opal/corelib/enumerator/arithmetic_sequence.rb +177 -0
  74. data/opal/corelib/enumerator/chain.rb +42 -0
  75. data/opal/corelib/enumerator/generator.rb +35 -0
  76. data/opal/corelib/enumerator/lazy.rb +243 -0
  77. data/opal/corelib/enumerator/yielder.rb +36 -0
  78. data/opal/corelib/enumerator.rb +45 -300
  79. data/opal/corelib/error/errno.rb +47 -0
  80. data/opal/corelib/error.rb +62 -60
  81. data/opal/corelib/file.rb +26 -12
  82. data/opal/corelib/hash.rb +98 -107
  83. data/opal/corelib/helpers.rb +62 -13
  84. data/opal/corelib/io.rb +47 -34
  85. data/opal/corelib/kernel/format.rb +29 -29
  86. data/opal/corelib/kernel.rb +86 -83
  87. data/opal/corelib/main.rb +14 -12
  88. data/opal/corelib/marshal/read_buffer.rb +15 -15
  89. data/opal/corelib/marshal/write_buffer.rb +45 -44
  90. data/opal/corelib/marshal.rb +3 -3
  91. data/opal/corelib/math.rb +50 -50
  92. data/opal/corelib/method.rb +12 -8
  93. data/opal/corelib/module.rb +96 -79
  94. data/opal/corelib/nil.rb +9 -11
  95. data/opal/corelib/number.rb +113 -118
  96. data/opal/corelib/numeric.rb +37 -33
  97. data/opal/corelib/object_space.rb +11 -10
  98. data/opal/corelib/pack_unpack/format_string_parser.rb +3 -3
  99. data/opal/corelib/pattern_matching/base.rb +7 -7
  100. data/opal/corelib/pattern_matching.rb +1 -1
  101. data/opal/corelib/proc.rb +15 -16
  102. data/opal/corelib/process/base.rb +2 -2
  103. data/opal/corelib/process/status.rb +21 -0
  104. data/opal/corelib/process.rb +5 -5
  105. data/opal/corelib/random/formatter.rb +11 -11
  106. data/opal/corelib/random/math_random.js.rb +1 -1
  107. data/opal/corelib/random/mersenne_twister.rb +3 -3
  108. data/opal/corelib/random/seedrandom.js.rb +3 -3
  109. data/opal/corelib/random.rb +17 -17
  110. data/opal/corelib/range.rb +51 -35
  111. data/opal/corelib/rational/base.rb +4 -4
  112. data/opal/corelib/rational.rb +61 -62
  113. data/opal/corelib/regexp.rb +47 -38
  114. data/opal/corelib/runtime.js +245 -139
  115. data/opal/corelib/string/encoding.rb +21 -21
  116. data/opal/corelib/string/unpack.rb +19 -14
  117. data/opal/corelib/string.rb +135 -128
  118. data/opal/corelib/struct.rb +59 -46
  119. data/opal/corelib/time.rb +47 -57
  120. data/opal/corelib/trace_point.rb +2 -2
  121. data/opal/corelib/unsupported.rb +31 -120
  122. data/opal/corelib/variables.rb +3 -3
  123. data/opal/opal/base.rb +9 -8
  124. data/opal/opal/full.rb +8 -8
  125. data/opal/opal/mini.rb +17 -17
  126. data/opal/opal.rb +17 -18
  127. data/opal.gemspec +1 -1
  128. data/spec/filters/bugs/array.rb +4 -24
  129. data/spec/filters/bugs/bigdecimal.rb +0 -23
  130. data/spec/filters/bugs/binding.rb +0 -1
  131. data/spec/filters/bugs/boolean.rb +3 -0
  132. data/spec/filters/bugs/class.rb +2 -0
  133. data/spec/filters/bugs/date.rb +0 -5
  134. data/spec/filters/bugs/encoding.rb +8 -50
  135. data/spec/filters/bugs/enumerable.rb +4 -1
  136. data/spec/filters/bugs/enumerator.rb +3 -36
  137. data/spec/filters/bugs/exception.rb +0 -2
  138. data/spec/filters/bugs/file.rb +0 -2
  139. data/spec/filters/bugs/float.rb +0 -3
  140. data/spec/filters/bugs/hash.rb +5 -3
  141. data/spec/filters/bugs/integer.rb +2 -3
  142. data/spec/filters/bugs/kernel.rb +2 -31
  143. data/spec/filters/bugs/language.rb +29 -49
  144. data/spec/filters/bugs/main.rb +0 -2
  145. data/spec/filters/bugs/marshal.rb +2 -3
  146. data/spec/filters/bugs/matrix.rb +0 -36
  147. data/spec/filters/bugs/module.rb +7 -61
  148. data/spec/filters/bugs/numeric.rb +0 -7
  149. data/spec/filters/bugs/objectspace.rb +1 -1
  150. data/spec/filters/bugs/pack_unpack.rb +0 -4
  151. data/spec/filters/bugs/proc.rb +0 -9
  152. data/spec/filters/bugs/random.rb +0 -5
  153. data/spec/filters/bugs/range.rb +1 -6
  154. data/spec/filters/bugs/regexp.rb +0 -3
  155. data/spec/filters/bugs/set.rb +8 -1
  156. data/spec/filters/bugs/string.rb +9 -34
  157. data/spec/filters/bugs/stringscanner.rb +8 -7
  158. data/spec/filters/bugs/struct.rb +2 -3
  159. data/spec/filters/bugs/symbol.rb +0 -1
  160. data/spec/filters/bugs/time.rb +0 -8
  161. data/spec/filters/bugs/unboundmethod.rb +0 -8
  162. data/spec/filters/bugs/warnings.rb +1 -7
  163. data/spec/filters/unsupported/freeze.rb +24 -0
  164. data/spec/filters/unsupported/integer.rb +1 -0
  165. data/spec/filters/unsupported/kernel.rb +12 -0
  166. data/spec/filters/unsupported/privacy.rb +3 -0
  167. data/spec/filters/unsupported/string.rb +2 -0
  168. data/spec/lib/builder_spec.rb +2 -2
  169. data/spec/lib/cli_spec.rb +1 -1
  170. data/spec/lib/compiler_spec.rb +37 -37
  171. data/spec/lib/simple_server_spec.rb +2 -2
  172. data/spec/lib/source_map/file_spec.rb +1 -1
  173. data/spec/opal/compiler/irb_spec.rb +2 -2
  174. data/spec/opal/core/kernel/puts_spec.rb +90 -0
  175. data/spec/opal/core/language/super_spec.rb +24 -0
  176. data/spec/ruby_specs +4 -2
  177. data/spec/support/rewriters_helper.rb +1 -1
  178. data/stdlib/bigdecimal.rb +7 -11
  179. data/stdlib/buffer/view.rb +2 -2
  180. data/stdlib/buffer.rb +2 -2
  181. data/stdlib/date.rb +5 -6
  182. data/stdlib/erb.rb +1 -0
  183. data/stdlib/js.rb +2 -1
  184. data/stdlib/native.rb +7 -8
  185. data/stdlib/nodejs/argf.rb +4 -4
  186. data/stdlib/nodejs/base.rb +29 -0
  187. data/stdlib/nodejs/dir.rb +1 -1
  188. data/stdlib/nodejs/env.rb +6 -9
  189. data/stdlib/nodejs/file.rb +23 -17
  190. data/stdlib/nodejs/fileutils.rb +3 -3
  191. data/stdlib/nodejs/io.rb +2 -20
  192. data/stdlib/nodejs/irb.rb +0 -0
  193. data/stdlib/nodejs/kernel.rb +2 -37
  194. data/stdlib/nodejs.rb +1 -3
  195. data/stdlib/opal/miniracer.rb +2 -0
  196. data/stdlib/opal/platform.rb +6 -13
  197. data/stdlib/opal/replutils.rb +16 -5
  198. data/stdlib/opal-parser.rb +2 -2
  199. data/stdlib/optparse/ac.rb +54 -0
  200. data/stdlib/optparse/date.rb +14 -0
  201. data/stdlib/optparse/kwargs.rb +22 -0
  202. data/stdlib/optparse/shellwords.rb +7 -0
  203. data/stdlib/optparse/time.rb +15 -0
  204. data/stdlib/optparse/uri.rb +7 -0
  205. data/stdlib/optparse/version.rb +69 -0
  206. data/stdlib/optparse.rb +2279 -0
  207. data/stdlib/pathname.rb +5 -6
  208. data/stdlib/pp.rb +18 -2
  209. data/stdlib/promise/v2.rb +18 -22
  210. data/stdlib/promise.rb +15 -21
  211. data/stdlib/set.rb +32 -32
  212. data/stdlib/shellwords.rb +240 -0
  213. data/stdlib/stringio.rb +3 -6
  214. data/stdlib/strscan.rb +5 -8
  215. data/stdlib/template.rb +2 -2
  216. data/stdlib/thread.rb +7 -9
  217. data/tasks/performance.rake +5 -2
  218. data/tasks/testing/mspec_special_calls.rb +0 -12
  219. data/tasks/testing.rake +55 -37
  220. data/test/nodejs/test_file.rb +11 -0
  221. metadata +55 -10
  222. data/lib/opal/nodes/case.rb +0 -114
@@ -1,6 +1,6 @@
1
1
  require 'corelib/string'
2
2
 
3
- class Encoding
3
+ class ::Encoding
4
4
  def self.register(name, options = {}, &block)
5
5
  names = [name] + (options[:aliases] || [])
6
6
  ascii = options[:ascii] || false
@@ -94,18 +94,18 @@ class Encoding
94
94
  end
95
95
 
96
96
  def each_byte(*)
97
- raise NotImplementedError
97
+ ::Kernel.raise ::NotImplementedError
98
98
  end
99
99
 
100
100
  def bytesize(*)
101
- raise NotImplementedError
101
+ ::Kernel.raise ::NotImplementedError
102
102
  end
103
103
 
104
- class EncodingError < StandardError; end
105
- class CompatibilityError < EncodingError; end
104
+ class ::EncodingError < ::StandardError; end
105
+ class ::CompatibilityError < ::EncodingError; end
106
106
  end
107
107
 
108
- Encoding.register 'UTF-8', aliases: ['CP65001'], ascii: true do
108
+ ::Encoding.register 'UTF-8', aliases: ['CP65001'], ascii: true do
109
109
  def each_byte(string, &block)
110
110
  %x{
111
111
  // Taken from: https://github.com/feross/buffer/blob/f52dffd9df0445b93c0c9065c2f8f0f46b2c729a/index.js#L1954-L2032
@@ -201,7 +201,7 @@ Encoding.register 'UTF-8', aliases: ['CP65001'], ascii: true do
201
201
  end
202
202
  end
203
203
 
204
- Encoding.register 'UTF-16LE' do
204
+ ::Encoding.register 'UTF-16LE' do
205
205
  def each_byte(string, &block)
206
206
  %x{
207
207
  for (var i = 0, length = string.length; i < length; i++) {
@@ -218,7 +218,7 @@ Encoding.register 'UTF-16LE' do
218
218
  end
219
219
  end
220
220
 
221
- Encoding.register 'UTF-16BE', inherits: Encoding::UTF_16LE do
221
+ ::Encoding.register 'UTF-16BE', inherits: ::Encoding::UTF_16LE do
222
222
  def each_byte(string, &block)
223
223
  %x{
224
224
  for (var i = 0, length = string.length; i < length; i++) {
@@ -231,7 +231,7 @@ Encoding.register 'UTF-16BE', inherits: Encoding::UTF_16LE do
231
231
  end
232
232
  end
233
233
 
234
- Encoding.register 'UTF-32LE' do
234
+ ::Encoding.register 'UTF-32LE' do
235
235
  def each_byte(string, &block)
236
236
  %x{
237
237
  for (var i = 0, length = string.length; i < length; i++) {
@@ -250,7 +250,7 @@ Encoding.register 'UTF-32LE' do
250
250
  end
251
251
  end
252
252
 
253
- Encoding.register 'UTF-32BE', inherits: Encoding::UTF_32LE do
253
+ ::Encoding.register 'UTF-32BE', inherits: ::Encoding::UTF_32LE do
254
254
  def each_byte(string, &block)
255
255
  %x{
256
256
  for (var i = 0, length = string.length; i < length; i++) {
@@ -265,7 +265,7 @@ Encoding.register 'UTF-32BE', inherits: Encoding::UTF_32LE do
265
265
  end
266
266
  end
267
267
 
268
- Encoding.register 'ASCII-8BIT', aliases: ['BINARY'], ascii: true do
268
+ ::Encoding.register 'ASCII-8BIT', aliases: ['BINARY'], ascii: true do
269
269
  def each_char(string, &block)
270
270
  %x{
271
271
  for (var i = 0, length = string.length; i < length; i++) {
@@ -298,15 +298,15 @@ Encoding.register 'ASCII-8BIT', aliases: ['BINARY'], ascii: true do
298
298
  end
299
299
  end
300
300
 
301
- Encoding.register 'ISO-8859-1', aliases: ['ISO8859-1'], ascii: true, inherits: Encoding::ASCII_8BIT
302
- Encoding.register 'US-ASCII', aliases: ['ASCII'], ascii: true, inherits: Encoding::ASCII_8BIT
301
+ ::Encoding.register 'ISO-8859-1', aliases: ['ISO8859-1'], ascii: true, inherits: ::Encoding::ASCII_8BIT
302
+ ::Encoding.register 'US-ASCII', aliases: ['ASCII'], ascii: true, inherits: ::Encoding::ASCII_8BIT
303
303
 
304
- class String
304
+ class ::String
305
305
  attr_reader :encoding
306
306
  attr_reader :internal_encoding
307
- `Opal.defineProperty(String.prototype, 'bytes', nil)`
308
- `Opal.defineProperty(String.prototype, 'encoding', #{Encoding::UTF_8})`
309
- `Opal.defineProperty(String.prototype, 'internal_encoding', #{Encoding::UTF_8})`
307
+ `Opal.prop(String.prototype, 'bytes', nil)`
308
+ `Opal.prop(String.prototype, 'encoding', #{::Encoding::UTF_8})`
309
+ `Opal.prop(String.prototype, 'internal_encoding', #{::Encoding::UTF_8})`
310
310
 
311
311
  def b
312
312
  dup.force_encoding('binary')
@@ -377,8 +377,8 @@ class String
377
377
 
378
378
  if (encoding === str.encoding) { return str; }
379
379
 
380
- encoding = #{Opal.coerce_to!(encoding, String, :to_s)};
381
- encoding = #{Encoding.find(encoding)};
380
+ encoding = #{::Opal.coerce_to!(encoding, ::String, :to_s)};
381
+ encoding = #{::Encoding.find(encoding)};
382
382
 
383
383
  if (encoding === str.encoding) { return str; }
384
384
 
@@ -390,7 +390,7 @@ class String
390
390
 
391
391
  def getbyte(idx)
392
392
  string_bytes = bytes
393
- idx = Opal.coerce_to!(idx, Integer, :to_int)
393
+ idx = ::Opal.coerce_to!(idx, ::Integer, :to_int)
394
394
  return if string_bytes.length < idx
395
395
 
396
396
  string_bytes[idx]
@@ -415,4 +415,4 @@ class String
415
415
  end
416
416
  end
417
417
 
418
- Encoding.default_external = __ENCODING__
418
+ ::Encoding.default_external = __ENCODING__
@@ -1,7 +1,7 @@
1
1
  require 'base64'
2
2
  require 'corelib/pack_unpack/format_string_parser'
3
3
 
4
- class String
4
+ class ::String
5
5
  %x{
6
6
  // Format Parser
7
7
  var eachDirectiveAndCount = Opal.PackUnpack.eachDirectiveAndCount;
@@ -305,7 +305,7 @@ class String
305
305
  }
306
306
 
307
307
  if (c >> 6 == 0x02) {
308
- #{raise ArgumentError, 'malformed UTF-8 character'}
308
+ #{::Kernel.raise ::ArgumentError, 'malformed UTF-8 character'}
309
309
  }
310
310
 
311
311
  if (c >> 5 == 0x06) {
@@ -324,14 +324,14 @@ class String
324
324
  // 1111 110x (six bytes)
325
325
  extraLength = 5;
326
326
  } else {
327
- #{raise 'malformed UTF-8 character'}
327
+ #{::Kernel.raise 'malformed UTF-8 character'}
328
328
  }
329
329
 
330
330
  if (extraLength > bytesLength) {
331
331
  #{
332
332
  expected = `extraLength + 1`
333
333
  given = `bytesLength + 1`
334
- raise ArgumentError, "malformed UTF-8 character (expected #{expected} bytes, given #{given} bytes)"
334
+ ::Kernel.raise ::ArgumentError, "malformed UTF-8 character (expected #{expected} bytes, given #{given} bytes)"
335
335
  }
336
336
  }
337
337
 
@@ -343,7 +343,7 @@ class String
343
343
  c = readByte();
344
344
 
345
345
  if (c >> 6 != 0x02) {
346
- #{raise 'Invalid multibyte sequence'}
346
+ #{::Kernel.raise 'Invalid multibyte sequence'}
347
347
  }
348
348
 
349
349
  result = (result << 6) | (c & 0x3f);
@@ -675,8 +675,9 @@ class String
675
675
  alias('L', 'V');
676
676
  }
677
677
 
678
- def unpack(format)
679
- format = Opal.coerce_to!(format, String, :to_str).gsub(/\s/, '').delete("\000")
678
+ def unpack(format, offset: 0)
679
+ ::Kernel.raise ::ArgumentError, "offset can't be negative" if offset < 0
680
+ format = ::Opal.coerce_to!(format, ::String, :to_str).gsub(/\s/, '').delete("\000")
680
681
 
681
682
  %x{
682
683
  var output = [];
@@ -689,7 +690,7 @@ class String
689
690
  var cp, j = 0;
690
691
 
691
692
  output = new Array(self.length);
692
- for (var i = 0; i < self.length; i++) {
693
+ for (var i = offset; i < self.length; i++) {
693
694
  cp = output[j++] = self.codePointAt(i);
694
695
  if (cp > 0xffff) i++;
695
696
  }
@@ -698,6 +699,10 @@ class String
698
699
 
699
700
  var buffer = self.$bytes();
700
701
 
702
+ #{::Kernel.raise ::ArgumentError, 'offset outside of string' if offset > `buffer`.length}
703
+
704
+ buffer = buffer.slice(offset);
705
+
701
706
 
702
707
  // optimization
703
708
  var optimizedHandler = optimized[format];
@@ -718,7 +723,7 @@ class String
718
723
  chunkReader = readChunk[directive];
719
724
 
720
725
  if (chunkReader == null) {
721
- #{raise "Unsupported unpack directive #{`directive`.inspect} (no chunk reader defined)"}
726
+ #{::Kernel.raise "Unsupported unpack directive #{`directive`.inspect} (no chunk reader defined)"}
722
727
  }
723
728
 
724
729
  var chunkData = chunkReader(buffer, count);
@@ -728,7 +733,7 @@ class String
728
733
  var handler = handlers[directive];
729
734
 
730
735
  if (handler == null) {
731
- #{raise "Unsupported unpack directive #{`directive`.inspect} (no handler defined)"}
736
+ #{::Kernel.raise "Unsupported unpack directive #{`directive`.inspect} (no handler defined)"}
732
737
  }
733
738
 
734
739
  return handler(chunk);
@@ -741,7 +746,7 @@ class String
741
746
  var shouldAutocomplete = autocompletion[directive];
742
747
 
743
748
  if (shouldAutocomplete == null) {
744
- #{raise "Unsupported unpack directive #{`directive`.inspect} (no autocompletion rule defined)"}
749
+ #{::Kernel.raise "Unsupported unpack directive #{`directive`.inspect} (no autocompletion rule defined)"}
745
750
  }
746
751
 
747
752
  if (shouldAutocomplete) {
@@ -756,9 +761,9 @@ class String
756
761
  }
757
762
  end
758
763
 
759
- def unpack1(format)
760
- format = Opal.coerce_to!(format, String, :to_str).gsub(/\s/, '').delete("\000")
764
+ def unpack1(format, offset: 0)
765
+ format = ::Opal.coerce_to!(format, ::String, :to_str).gsub(/\s/, '').delete("\000")
761
766
 
762
- unpack(format[0])[0]
767
+ unpack(format[0], offset: offset)[0]
763
768
  end
764
769
  end