opal-cj 0.7.0.beta1

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.
Files changed (470) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +10 -0
  3. data/.gitmodules +27 -0
  4. data/.rspec +3 -0
  5. data/.spectator +2 -0
  6. data/.spectator-mspec +3 -0
  7. data/.travis.yml +45 -0
  8. data/CHANGELOG.md +406 -0
  9. data/CONTRIBUTING.md +41 -0
  10. data/Gemfile +27 -0
  11. data/Guardfile +77 -0
  12. data/LICENSE +19 -0
  13. data/README.md +178 -0
  14. data/Rakefile +116 -0
  15. data/benchmarks/operators.rb +11 -0
  16. data/bin/opal +22 -0
  17. data/bin/opal-build +77 -0
  18. data/bin/opal-mspec +10 -0
  19. data/bin/opal-repl +72 -0
  20. data/config.ru +14 -0
  21. data/examples/rack/Gemfile +3 -0
  22. data/examples/rack/app/application.rb +13 -0
  23. data/examples/rack/app/user.rb +21 -0
  24. data/examples/rack/config.ru +7 -0
  25. data/examples/rack/index.html.erb +10 -0
  26. data/examples/sinatra/Gemfile +4 -0
  27. data/examples/sinatra/app/application.rb +7 -0
  28. data/examples/sinatra/config.ru +28 -0
  29. data/lib/mspec/opal/main.rb.erb +9 -0
  30. data/lib/mspec/opal/rake_task.rb +278 -0
  31. data/lib/mspec/opal/runner.rb +206 -0
  32. data/lib/mspec/opal/sprockets.js +57 -0
  33. data/lib/opal.rb +11 -0
  34. data/lib/opal/builder.rb +135 -0
  35. data/lib/opal/builder_processors.rb +165 -0
  36. data/lib/opal/cli.rb +145 -0
  37. data/lib/opal/cli_options.rb +149 -0
  38. data/lib/opal/cli_runners.rb +10 -0
  39. data/lib/opal/cli_runners/nodejs.rb +56 -0
  40. data/lib/opal/cli_runners/phantom.js +35 -0
  41. data/lib/opal/cli_runners/phantomjs.rb +28 -0
  42. data/lib/opal/cli_runners/server.rb +54 -0
  43. data/lib/opal/compiler.rb +307 -0
  44. data/lib/opal/erb.rb +64 -0
  45. data/lib/opal/fragment.rb +41 -0
  46. data/lib/opal/hike_path_finder.rb +18 -0
  47. data/lib/opal/nodes.rb +26 -0
  48. data/lib/opal/nodes/arglist.rb +56 -0
  49. data/lib/opal/nodes/array.rb +54 -0
  50. data/lib/opal/nodes/base.rb +151 -0
  51. data/lib/opal/nodes/call.rb +283 -0
  52. data/lib/opal/nodes/call_special.rb +178 -0
  53. data/lib/opal/nodes/case.rb +96 -0
  54. data/lib/opal/nodes/class.rb +42 -0
  55. data/lib/opal/nodes/constants.rb +78 -0
  56. data/lib/opal/nodes/def.rb +157 -0
  57. data/lib/opal/nodes/defined.rb +113 -0
  58. data/lib/opal/nodes/definitions.rb +168 -0
  59. data/lib/opal/nodes/for.rb +35 -0
  60. data/lib/opal/nodes/hash.rb +67 -0
  61. data/lib/opal/nodes/helpers.rb +114 -0
  62. data/lib/opal/nodes/if.rb +67 -0
  63. data/lib/opal/nodes/iter.rb +131 -0
  64. data/lib/opal/nodes/literal.rb +230 -0
  65. data/lib/opal/nodes/logic.rb +217 -0
  66. data/lib/opal/nodes/masgn.rb +62 -0
  67. data/lib/opal/nodes/module.rb +46 -0
  68. data/lib/opal/nodes/rescue.rb +135 -0
  69. data/lib/opal/nodes/runtime_helpers.rb +45 -0
  70. data/lib/opal/nodes/scope.rb +293 -0
  71. data/lib/opal/nodes/singleton_class.rb +25 -0
  72. data/lib/opal/nodes/super.rb +97 -0
  73. data/lib/opal/nodes/top.rb +101 -0
  74. data/lib/opal/nodes/variables.rb +158 -0
  75. data/lib/opal/nodes/while.rb +65 -0
  76. data/lib/opal/nodes/yield.rb +95 -0
  77. data/lib/opal/parser.rb +658 -0
  78. data/lib/opal/parser/grammar.rb +5452 -0
  79. data/lib/opal/parser/grammar.y +1684 -0
  80. data/lib/opal/parser/keywords.rb +66 -0
  81. data/lib/opal/parser/lexer.rb +1208 -0
  82. data/lib/opal/parser/parser_scope.rb +25 -0
  83. data/lib/opal/parser/sexp.rb +75 -0
  84. data/lib/opal/path_reader.rb +28 -0
  85. data/lib/opal/paths.rb +38 -0
  86. data/lib/opal/source_map.rb +70 -0
  87. data/lib/opal/sprockets.rb +4 -0
  88. data/lib/opal/sprockets/cache_key_fix.rb +17 -0
  89. data/lib/opal/sprockets/environment.rb +37 -0
  90. data/lib/opal/sprockets/erb.rb +37 -0
  91. data/lib/opal/sprockets/path_reader.rb +34 -0
  92. data/lib/opal/sprockets/processor.rb +124 -0
  93. data/lib/opal/sprockets/server.rb +180 -0
  94. data/lib/opal/util.rb +64 -0
  95. data/lib/opal/version.rb +3 -0
  96. data/opal.gemspec +36 -0
  97. data/opal/README.md +6 -0
  98. data/opal/corelib/array.rb +1556 -0
  99. data/opal/corelib/array/inheritance.rb +113 -0
  100. data/opal/corelib/basic_object.rb +73 -0
  101. data/opal/corelib/boolean.rb +41 -0
  102. data/opal/corelib/class.rb +55 -0
  103. data/opal/corelib/comparable.rb +56 -0
  104. data/opal/corelib/complex.rb +3 -0
  105. data/opal/corelib/dir.rb +20 -0
  106. data/opal/corelib/enumerable.rb +1132 -0
  107. data/opal/corelib/enumerator.rb +422 -0
  108. data/opal/corelib/error.rb +63 -0
  109. data/opal/corelib/file.rb +56 -0
  110. data/opal/corelib/hash.rb +728 -0
  111. data/opal/corelib/helpers.rb +102 -0
  112. data/opal/corelib/io.rb +59 -0
  113. data/opal/corelib/kernel.rb +569 -0
  114. data/opal/corelib/main.rb +7 -0
  115. data/opal/corelib/match_data.rb +114 -0
  116. data/opal/corelib/method.rb +58 -0
  117. data/opal/corelib/module.rb +462 -0
  118. data/opal/corelib/nil_class.rb +62 -0
  119. data/opal/corelib/numeric.rb +532 -0
  120. data/opal/corelib/proc.rb +52 -0
  121. data/opal/corelib/range.rb +116 -0
  122. data/opal/corelib/rational.rb +3 -0
  123. data/opal/corelib/regexp.rb +133 -0
  124. data/opal/corelib/runtime.js +1240 -0
  125. data/opal/corelib/string.rb +1212 -0
  126. data/opal/corelib/string/inheritance.rb +78 -0
  127. data/opal/corelib/struct.rb +141 -0
  128. data/opal/corelib/time.rb +584 -0
  129. data/opal/corelib/variables.rb +24 -0
  130. data/opal/opal.rb +32 -0
  131. data/package.json +9 -0
  132. data/spec/filters/bugs/array.rb +232 -0
  133. data/spec/filters/bugs/basic_object.rb +14 -0
  134. data/spec/filters/bugs/class.rb +21 -0
  135. data/spec/filters/bugs/enumerable.rb +69 -0
  136. data/spec/filters/bugs/enumerator.rb +3 -0
  137. data/spec/filters/bugs/hash.rb +128 -0
  138. data/spec/filters/bugs/kernel.rb +10 -0
  139. data/spec/filters/bugs/language.rb +415 -0
  140. data/spec/filters/bugs/math.rb +95 -0
  141. data/spec/filters/bugs/module.rb +14 -0
  142. data/spec/filters/bugs/nil.rb +7 -0
  143. data/spec/filters/bugs/numeric.rb +20 -0
  144. data/spec/filters/bugs/opal.rb +14 -0
  145. data/spec/filters/bugs/regexp.rb +11 -0
  146. data/spec/filters/bugs/set.rb +7 -0
  147. data/spec/filters/bugs/singleton.rb +6 -0
  148. data/spec/filters/bugs/string.rb +360 -0
  149. data/spec/filters/bugs/stringscanner.rb +22 -0
  150. data/spec/filters/bugs/struct.rb +45 -0
  151. data/spec/filters/bugs/time.rb +177 -0
  152. data/spec/filters/bugs/unknown.rb +11 -0
  153. data/spec/filters/unsupported/encoding.rb +95 -0
  154. data/spec/filters/unsupported/enumerator.rb +14 -0
  155. data/spec/filters/unsupported/float.rb +5 -0
  156. data/spec/filters/unsupported/frozen.rb +90 -0
  157. data/spec/filters/unsupported/hash_compare_by_identity.rb +16 -0
  158. data/spec/filters/unsupported/integer_size.rb +7 -0
  159. data/spec/filters/unsupported/method_added.rb +10 -0
  160. data/spec/filters/unsupported/mutable_strings.rb +361 -0
  161. data/spec/filters/unsupported/private_constants.rb +30 -0
  162. data/spec/filters/unsupported/private_methods.rb +44 -0
  163. data/spec/filters/unsupported/random.rb +4 -0
  164. data/spec/filters/unsupported/ruby_exe.rb +5 -0
  165. data/spec/filters/unsupported/tainted.rb +155 -0
  166. data/spec/filters/unsupported/time.rb +21 -0
  167. data/spec/filters/unsupported/trusted.rb +80 -0
  168. data/spec/lib/builder_processors_spec.rb +27 -0
  169. data/spec/lib/builder_spec.rb +66 -0
  170. data/spec/lib/cli_spec.rb +134 -0
  171. data/spec/lib/compiler_spec.rb +197 -0
  172. data/spec/lib/dependency_resolver_spec.rb +40 -0
  173. data/spec/lib/fixtures/no_requires.rb +1 -0
  174. data/spec/lib/fixtures/opal_file.rb +2 -0
  175. data/spec/lib/fixtures/require_tree_test.rb +3 -0
  176. data/spec/lib/fixtures/required_tree_test/required_file1.rb +1 -0
  177. data/spec/lib/fixtures/required_tree_test/required_file2.rb +1 -0
  178. data/spec/lib/fixtures/requires.rb +7 -0
  179. data/spec/lib/fixtures/sprockets_file.js.rb +3 -0
  180. data/spec/lib/fixtures/sprockets_require_tree_test.rb +3 -0
  181. data/spec/lib/hike_path_finder_spec.rb +23 -0
  182. data/spec/lib/lexer_spec.rb +110 -0
  183. data/spec/lib/parser/alias_spec.rb +26 -0
  184. data/spec/lib/parser/and_spec.rb +13 -0
  185. data/spec/lib/parser/attrasgn_spec.rb +28 -0
  186. data/spec/lib/parser/begin_spec.rb +42 -0
  187. data/spec/lib/parser/block_spec.rb +12 -0
  188. data/spec/lib/parser/break_spec.rb +17 -0
  189. data/spec/lib/parser/call_spec.rb +139 -0
  190. data/spec/lib/parser/class_spec.rb +35 -0
  191. data/spec/lib/parser/comments_spec.rb +11 -0
  192. data/spec/lib/parser/def_spec.rb +61 -0
  193. data/spec/lib/parser/if_spec.rb +26 -0
  194. data/spec/lib/parser/iter_spec.rb +59 -0
  195. data/spec/lib/parser/lambda_spec.rb +64 -0
  196. data/spec/lib/parser/literal_spec.rb +118 -0
  197. data/spec/lib/parser/masgn_spec.rb +37 -0
  198. data/spec/lib/parser/module_spec.rb +27 -0
  199. data/spec/lib/parser/not_spec.rb +27 -0
  200. data/spec/lib/parser/op_asgn1_spec.rb +23 -0
  201. data/spec/lib/parser/op_asgn2_spec.rb +23 -0
  202. data/spec/lib/parser/or_spec.rb +13 -0
  203. data/spec/lib/parser/return_spec.rb +17 -0
  204. data/spec/lib/parser/sclass_spec.rb +21 -0
  205. data/spec/lib/parser/string_spec.rb +276 -0
  206. data/spec/lib/parser/super_spec.rb +20 -0
  207. data/spec/lib/parser/unary_spec.rb +48 -0
  208. data/spec/lib/parser/undef_spec.rb +15 -0
  209. data/spec/lib/parser/unless_spec.rb +13 -0
  210. data/spec/lib/parser/variables_spec.rb +92 -0
  211. data/spec/lib/parser/while_spec.rb +15 -0
  212. data/spec/lib/parser/yield_spec.rb +20 -0
  213. data/spec/lib/path_reader_spec.rb +24 -0
  214. data/spec/lib/shared/path_finder_shared.rb +19 -0
  215. data/spec/lib/shared/path_reader_shared.rb +31 -0
  216. data/spec/lib/spec_helper.rb +9 -0
  217. data/spec/lib/sprockets/environment_spec.rb +30 -0
  218. data/spec/lib/sprockets/erb_spec.rb +25 -0
  219. data/spec/lib/sprockets/path_reader_spec.rb +25 -0
  220. data/spec/lib/sprockets/processor_spec.rb +35 -0
  221. data/spec/lib/sprockets/server_spec.rb +20 -0
  222. data/spec/opal/compiler/irb_spec.rb +44 -0
  223. data/spec/opal/core/array/select_spec.rb +14 -0
  224. data/spec/opal/core/array/set_range_to_array_spec.rb +7 -0
  225. data/spec/opal/core/date_spec.rb +122 -0
  226. data/spec/opal/core/enumerable/all_break_spec.rb +5 -0
  227. data/spec/opal/core/enumerable/any_break_spec.rb +5 -0
  228. data/spec/opal/core/enumerable/collect_break_spec.rb +13 -0
  229. data/spec/opal/core/enumerable/count_break_spec.rb +5 -0
  230. data/spec/opal/core/enumerable/detect_break_spec.rb +5 -0
  231. data/spec/opal/core/enumerable/drop_while_break_spec.rb +5 -0
  232. data/spec/opal/core/enumerable/each_slice_break.rb +6 -0
  233. data/spec/opal/core/enumerable/each_with_index_break_spec.rb +5 -0
  234. data/spec/opal/core/enumerable/each_with_object_break_spec.rb +5 -0
  235. data/spec/opal/core/enumerable/find_all_break_spec.rb +5 -0
  236. data/spec/opal/core/enumerable/find_index_break_spec.rb +5 -0
  237. data/spec/opal/core/enumerable/grep_break_spec.rb +5 -0
  238. data/spec/opal/core/enumerable/max_break_spec.rb +5 -0
  239. data/spec/opal/core/enumerable/max_by_break_spec.rb +5 -0
  240. data/spec/opal/core/enumerable/min_break_spec.rb +5 -0
  241. data/spec/opal/core/enumerable/min_by_break_spec.rb +5 -0
  242. data/spec/opal/core/enumerable/none_break_spec.rb +5 -0
  243. data/spec/opal/core/enumerable/one_break_spec.rb +5 -0
  244. data/spec/opal/core/enumerable/reduce_break_spec.rb +5 -0
  245. data/spec/opal/core/enumerable/take_while_break_spec.rb +5 -0
  246. data/spec/opal/core/fixtures/class.rb +124 -0
  247. data/spec/opal/core/fixtures/class_variables.rb +0 -0
  248. data/spec/opal/core/fixtures/constants.rb +33 -0
  249. data/spec/opal/core/fixtures/require_tree_files/file 1.rb +1 -0
  250. data/spec/opal/core/fixtures/require_tree_files/file 2.rb +1 -0
  251. data/spec/opal/core/fixtures/require_tree_files/file 3.rb +1 -0
  252. data/spec/opal/core/fixtures/require_tree_files/file 4.rb +1 -0
  253. data/spec/opal/core/fixtures/require_tree_files/file 5.rb +1 -0
  254. data/spec/opal/core/kernel/Array_spec.rb +10 -0
  255. data/spec/opal/core/kernel/block_given_spec.rb +30 -0
  256. data/spec/opal/core/kernel/class_spec.rb +6 -0
  257. data/spec/opal/core/kernel/define_singleton_method_spec.rb +21 -0
  258. data/spec/opal/core/kernel/equal_value_spec.rb +12 -0
  259. data/spec/opal/core/kernel/extend_spec.rb +21 -0
  260. data/spec/opal/core/kernel/format_spec.rb +122 -0
  261. data/spec/opal/core/kernel/freeze_spec.rb +15 -0
  262. data/spec/opal/core/kernel/instance_eval_spec.rb +28 -0
  263. data/spec/opal/core/kernel/instance_variable_defined_spec.rb +15 -0
  264. data/spec/opal/core/kernel/instance_variable_get_spec.rb +14 -0
  265. data/spec/opal/core/kernel/instance_variable_set_spec.rb +10 -0
  266. data/spec/opal/core/kernel/loop_spec.rb +23 -0
  267. data/spec/opal/core/kernel/match_spec.rb +5 -0
  268. data/spec/opal/core/kernel/method_spec.rb +31 -0
  269. data/spec/opal/core/kernel/methods_spec.rb +25 -0
  270. data/spec/opal/core/kernel/nil_spec.rb +7 -0
  271. data/spec/opal/core/kernel/p_spec.rb +15 -0
  272. data/spec/opal/core/kernel/printf_spec.rb +11 -0
  273. data/spec/opal/core/kernel/proc_spec.rb +13 -0
  274. data/spec/opal/core/kernel/rand_spec.rb +23 -0
  275. data/spec/opal/core/kernel/require_tree_spec.rb +7 -0
  276. data/spec/opal/core/kernel/respond_to_spec.rb +41 -0
  277. data/spec/opal/core/kernel/send_spec.rb +56 -0
  278. data/spec/opal/core/kernel/sprintf_spec.rb +5 -0
  279. data/spec/opal/core/language/block_spec.rb +538 -0
  280. data/spec/opal/core/language/fixtures/array.rb +11 -0
  281. data/spec/opal/core/language/fixtures/block.rb +57 -0
  282. data/spec/opal/core/language/fixtures/break.rb +240 -0
  283. data/spec/opal/core/language/fixtures/ensure.rb +72 -0
  284. data/spec/opal/core/language/fixtures/literal_lambda.rb +7 -0
  285. data/spec/opal/core/language/fixtures/metaclass.rb +33 -0
  286. data/spec/opal/core/language/fixtures/module.rb +24 -0
  287. data/spec/opal/core/language/fixtures/next.rb +128 -0
  288. data/spec/opal/core/language/fixtures/return.rb +118 -0
  289. data/spec/opal/core/language/fixtures/send.rb +110 -0
  290. data/spec/opal/core/language/fixtures/send_1.9.rb +22 -0
  291. data/spec/opal/core/language/fixtures/super.rb +308 -0
  292. data/spec/opal/core/language/fixtures/variables.rb +58 -0
  293. data/spec/opal/core/language/fixtures/yield.rb +28 -0
  294. data/spec/opal/core/language/predefined_spec.rb +85 -0
  295. data/spec/opal/core/language/proc_spec.rb +263 -0
  296. data/spec/opal/core/language/regexp_spec.rb +20 -0
  297. data/spec/opal/core/language/send_spec.rb +225 -0
  298. data/spec/opal/core/language/string_spec.rb +44 -0
  299. data/spec/opal/core/language/symbol_spec.rb +40 -0
  300. data/spec/opal/core/language/variables_spec.rb +1366 -0
  301. data/spec/opal/core/language/versions/array_1.9.rb +39 -0
  302. data/spec/opal/core/language/versions/block_1.9.rb +0 -0
  303. data/spec/opal/core/language/versions/break_1.9.rb +0 -0
  304. data/spec/opal/core/language/versions/case_1.9.rb +20 -0
  305. data/spec/opal/core/language/versions/hash_1.9.rb +18 -0
  306. data/spec/opal/core/language/versions/literal_lambda_1.9.rb +143 -0
  307. data/spec/opal/core/language/versions/not_1.9.rb +22 -0
  308. data/spec/opal/core/language/versions/send_1.9.rb +241 -0
  309. data/spec/opal/core/language/versions/symbol_1.9.rb +15 -0
  310. data/spec/opal/core/language/versions/variables_1.9.rb +8 -0
  311. data/spec/opal/core/module/alias_method_spec.rb +28 -0
  312. data/spec/opal/core/module/ancestors_spec.rb +11 -0
  313. data/spec/opal/core/module/append_features_spec.rb +14 -0
  314. data/spec/opal/core/module/attr_accessor_spec.rb +26 -0
  315. data/spec/opal/core/module/const_defined_spec.rb +85 -0
  316. data/spec/opal/core/module/const_get_spec.rb +85 -0
  317. data/spec/opal/core/module/const_missing_spec.rb +17 -0
  318. data/spec/opal/core/module/const_set_spec.rb +64 -0
  319. data/spec/opal/core/module/constants_spec.rb +49 -0
  320. data/spec/opal/core/module/fixtures/classes.rb +434 -0
  321. data/spec/opal/core/module/method_defined_spec.rb +48 -0
  322. data/spec/opal/core/module/module_function_spec.rb +25 -0
  323. data/spec/opal/core/module/name_spec.rb +52 -0
  324. data/spec/opal/core/module/public_method_defined_spec.rb +18 -0
  325. data/spec/opal/core/module/remove_const_spec.rb +22 -0
  326. data/spec/opal/core/module/undef_method_spec.rb +66 -0
  327. data/spec/opal/core/numeric/bit_and_spec.rb +7 -0
  328. data/spec/opal/core/numeric/bit_or_spec.rb +8 -0
  329. data/spec/opal/core/numeric/bit_xor_spec.rb +6 -0
  330. data/spec/opal/core/numeric/ceil_spec.rb +8 -0
  331. data/spec/opal/core/numeric/chr_spec.rb +8 -0
  332. data/spec/opal/core/numeric/comparison_spec.rb +24 -0
  333. data/spec/opal/core/numeric/complement_spec.rb +8 -0
  334. data/spec/opal/core/numeric/divide_spec.rb +10 -0
  335. data/spec/opal/core/numeric/eql_spec.rb +9 -0
  336. data/spec/opal/core/numeric/exponent_spec.rb +33 -0
  337. data/spec/opal/core/numeric/floor_spec.rb +8 -0
  338. data/spec/opal/core/numeric/gt_spec.rb +11 -0
  339. data/spec/opal/core/numeric/gte_spec.rb +12 -0
  340. data/spec/opal/core/numeric/integer_spec.rb +9 -0
  341. data/spec/opal/core/numeric/left_shift_spec.rb +21 -0
  342. data/spec/opal/core/numeric/lt_spec.rb +11 -0
  343. data/spec/opal/core/numeric/lte_spec.rb +12 -0
  344. data/spec/opal/core/numeric/minus_spec.rb +8 -0
  345. data/spec/opal/core/numeric/modulo_spec.rb +19 -0
  346. data/spec/opal/core/numeric/multiply_spec.rb +9 -0
  347. data/spec/opal/core/numeric/next_spec.rb +9 -0
  348. data/spec/opal/core/numeric/ord_spec.rb +9 -0
  349. data/spec/opal/core/numeric/plus_spec.rb +8 -0
  350. data/spec/opal/core/numeric/pred_spec.rb +7 -0
  351. data/spec/opal/core/numeric/right_shift_spec.rb +25 -0
  352. data/spec/opal/core/numeric/step_spec.rb +11 -0
  353. data/spec/opal/core/numeric/succ_spec.rb +9 -0
  354. data/spec/opal/core/numeric/times_spec.rb +36 -0
  355. data/spec/opal/core/numeric/to_f_spec.rb +7 -0
  356. data/spec/opal/core/numeric/to_i_spec.rb +7 -0
  357. data/spec/opal/core/numeric/to_json_spec.rb +8 -0
  358. data/spec/opal/core/numeric/to_s_spec.rb +26 -0
  359. data/spec/opal/core/numeric/uminus_spec.rb +9 -0
  360. data/spec/opal/core/numeric/upto_spec.rb +19 -0
  361. data/spec/opal/core/numeric/zero_spec.rb +7 -0
  362. data/spec/opal/core/proc/call_spec.rb +21 -0
  363. data/spec/opal/core/proc/element_reference_spec.rb +21 -0
  364. data/spec/opal/core/proc/proc_tricks_spec.rb +7 -0
  365. data/spec/opal/core/runtime/begin_spec.rb +39 -0
  366. data/spec/opal/core/runtime/block_send_spec.rb +28 -0
  367. data/spec/opal/core/runtime/block_spec.rb +23 -0
  368. data/spec/opal/core/runtime/bridged_classes_spec.rb +64 -0
  369. data/spec/opal/core/runtime/constants_spec.rb +13 -0
  370. data/spec/opal/core/runtime/eval_spec.rb +5 -0
  371. data/spec/opal/core/runtime/main_methods_spec.rb +27 -0
  372. data/spec/opal/core/runtime/method_missing_spec.rb +62 -0
  373. data/spec/opal/core/runtime/method_spec.rb +31 -0
  374. data/spec/opal/core/runtime/operator_call_spec.rb +13 -0
  375. data/spec/opal/core/runtime/paren_spec.rb +14 -0
  376. data/spec/opal/core/runtime/rescue_spec.rb +38 -0
  377. data/spec/opal/core/runtime/return_spec.rb +38 -0
  378. data/spec/opal/core/runtime/send_spec.rb +34 -0
  379. data/spec/opal/core/runtime/singleton_class_spec.rb +13 -0
  380. data/spec/opal/core/runtime/super_spec.rb +212 -0
  381. data/spec/opal/core/runtime/truthy_spec.rb +23 -0
  382. data/spec/opal/core/runtime/variables_spec.rb +20 -0
  383. data/spec/opal/core/source_map_spec.rb +15 -0
  384. data/spec/opal/core/string_spec.rb +11 -0
  385. data/spec/opal/stdlib/erb/erb_spec.rb +30 -0
  386. data/spec/opal/stdlib/erb/inline_block.opalerb +3 -0
  387. data/spec/opal/stdlib/erb/quoted.opalerb +1 -0
  388. data/spec/opal/stdlib/erb/simple.opalerb +1 -0
  389. data/spec/opal/stdlib/json/ext_spec.rb +48 -0
  390. data/spec/opal/stdlib/json/parse_spec.rb +33 -0
  391. data/spec/opal/stdlib/native/alias_native_spec.rb +27 -0
  392. data/spec/opal/stdlib/native/each_spec.rb +13 -0
  393. data/spec/opal/stdlib/native/element_reference_spec.rb +16 -0
  394. data/spec/opal/stdlib/native/exposure_spec.rb +33 -0
  395. data/spec/opal/stdlib/native/ext_spec.rb +19 -0
  396. data/spec/opal/stdlib/native/initialize_spec.rb +17 -0
  397. data/spec/opal/stdlib/native/method_missing_spec.rb +51 -0
  398. data/spec/opal/stdlib/native/native_reader_spec.rb +22 -0
  399. data/spec/opal/stdlib/native/native_writer_spec.rb +30 -0
  400. data/spec/opal/stdlib/native/new_spec.rb +8 -0
  401. data/spec/opal/stdlib/promise/error_spec.rb +15 -0
  402. data/spec/opal/stdlib/promise/rescue_spec.rb +35 -0
  403. data/spec/opal/stdlib/promise/then_spec.rb +54 -0
  404. data/spec/opal/stdlib/promise/trace_spec.rb +35 -0
  405. data/spec/opal/stdlib/promise/value_spec.rb +15 -0
  406. data/spec/opal/stdlib/promise/when_spec.rb +34 -0
  407. data/spec/opal/stdlib/template/paths_spec.rb +10 -0
  408. data/spec/opal/stdlib/thread/mutex_spec.rb +40 -0
  409. data/spec/opal/stdlib/thread/thread_queue_spec.rb +32 -0
  410. data/spec/opal/stdlib/thread/thread_spec.rb +60 -0
  411. data/spec/rubyspecs +329 -0
  412. data/spec/spec_helper.rb +42 -0
  413. data/spec/support/mspec_rspec_adapter.rb +33 -0
  414. data/spec/support/parser_helpers.rb +37 -0
  415. data/stdlib/README.md +3 -0
  416. data/stdlib/base64.rb +152 -0
  417. data/stdlib/benchmark.rb +10 -0
  418. data/stdlib/buffer.rb +40 -0
  419. data/stdlib/buffer/array.rb +66 -0
  420. data/stdlib/buffer/view.rb +70 -0
  421. data/stdlib/date.rb +170 -0
  422. data/stdlib/delegate.rb +29 -0
  423. data/stdlib/dir.rb +1 -0
  424. data/stdlib/encoding.rb +166 -0
  425. data/stdlib/enumerator.rb +1 -0
  426. data/stdlib/erb.rb +16 -0
  427. data/stdlib/file.rb +1 -0
  428. data/stdlib/forwardable.rb +71 -0
  429. data/stdlib/json.rb +182 -0
  430. data/stdlib/math.rb +370 -0
  431. data/stdlib/native.rb +530 -0
  432. data/stdlib/nodejs.rb +5 -0
  433. data/stdlib/nodejs/dir.rb +13 -0
  434. data/stdlib/nodejs/file.rb +98 -0
  435. data/stdlib/nodejs/fileutils.rb +26 -0
  436. data/stdlib/nodejs/io.rb +2 -0
  437. data/stdlib/nodejs/irb.rb +45 -0
  438. data/stdlib/nodejs/process.rb +16 -0
  439. data/stdlib/nodejs/require.rb +32 -0
  440. data/stdlib/nodejs/rubygems.rb +68 -0
  441. data/stdlib/nodejs/runtime.rb +25 -0
  442. data/stdlib/nodejs/yaml.rb +11 -0
  443. data/stdlib/observer.rb +202 -0
  444. data/stdlib/opal-parser.rb +53 -0
  445. data/stdlib/opal-source-maps.rb +2 -0
  446. data/stdlib/ostruct.rb +69 -0
  447. data/stdlib/pathname.rb +31 -0
  448. data/stdlib/phantomjs.rb +8 -0
  449. data/stdlib/pp.rb +12 -0
  450. data/stdlib/process.rb +10 -0
  451. data/stdlib/promise.rb +300 -0
  452. data/stdlib/racc/parser.rb +215 -0
  453. data/stdlib/rbconfig.rb +20 -0
  454. data/stdlib/securerandom.rb +12 -0
  455. data/stdlib/set.rb +116 -0
  456. data/stdlib/singleton.rb +40 -0
  457. data/stdlib/source_map.rb +5 -0
  458. data/stdlib/source_map/map.rb +220 -0
  459. data/stdlib/source_map/mapping.rb +26 -0
  460. data/stdlib/source_map/offset.rb +88 -0
  461. data/stdlib/source_map/version.rb +3 -0
  462. data/stdlib/source_map/vlq.rb +98 -0
  463. data/stdlib/sourcemap.rb +1 -0
  464. data/stdlib/stringio.rb +181 -0
  465. data/stdlib/strscan.rb +155 -0
  466. data/stdlib/template.rb +46 -0
  467. data/stdlib/thread.rb +160 -0
  468. data/stdlib/time.rb +9 -0
  469. data/tasks/github.rake +19 -0
  470. metadata +690 -0
@@ -0,0 +1,5 @@
1
+ require 'nodejs/runtime'
2
+ require 'nodejs/file'
3
+ require 'nodejs/dir'
4
+ require 'nodejs/io'
5
+ require 'nodejs/process'
@@ -0,0 +1,13 @@
1
+ class Dir
2
+ @__glob__ = NodeJS.require :glob
3
+ `var __glob__ = #{@__glob__}`
4
+
5
+ def self.[] glob
6
+ `__glob__.sync(#{glob})`
7
+ end
8
+
9
+ def pwd
10
+ `process.cwd()`
11
+ end
12
+ alias getwd pwd
13
+ end
@@ -0,0 +1,98 @@
1
+ class File < IO
2
+ include ::IO::Writable
3
+ include ::IO::Readable
4
+
5
+ @__fs__ = NodeJS.require :fs
6
+ @__path__ = NodeJS.require :path
7
+ `var __fs__ = #{@__fs__}`
8
+ `var __path__ = #{@__path__}`
9
+
10
+ def self.read path
11
+ `__fs__.readFileSync(#{path}).toString()`
12
+ end
13
+
14
+ def self.exist? path
15
+ `__fs__.existsSync(#{path})`
16
+ end
17
+
18
+ def self.realpath(pathname, dir_string = nil, cache = nil, &block)
19
+ pathname = join(dir_string, pathname) if dir_string
20
+ if block_given?
21
+ `
22
+ __fs__.realpath(#{pathname}, #{cache}, function(error, realpath){
23
+ if (error) #{raise error.message}
24
+ else #{block.call(`realpath`)}
25
+ })
26
+ `
27
+ else
28
+ `__fs__.realpathSync(#{pathname}, #{cache})`
29
+ end
30
+ end
31
+
32
+ def self.basename(path, ext = undefined)
33
+ `__path__.basename(#{path}, #{ext})`
34
+ end
35
+
36
+ def self.dirname(path)
37
+ `__path__.dirname(#{path})`
38
+ end
39
+
40
+ def self.join(*paths)
41
+ `__path__.join.apply(__path__, #{paths})`
42
+ end
43
+
44
+ def self.directory? path
45
+ return nil unless exist? path
46
+ `!!__fs__.lstatSync(path).isDirectory()`
47
+ end
48
+
49
+ def self.file? path
50
+ return nil unless exist? path
51
+ `!!__fs__.lstatSync(path).isFile()`
52
+ end
53
+
54
+ def self.size path
55
+ return nil unless exist? path
56
+ `__fs__.lstatSync(path).size`
57
+ end
58
+
59
+ def self.open path, flags
60
+ file = new(path, flags)
61
+ if block_given?
62
+ begin
63
+ yield(file)
64
+ ensure
65
+ file.close
66
+ end
67
+ else
68
+ file
69
+ end
70
+ end
71
+
72
+
73
+
74
+
75
+ # Instance Methods
76
+
77
+ def initialize(path, flags)
78
+ flags = flags.gsub(/b/, '')
79
+ @path = path
80
+ @flags = flags
81
+ @fd = `__fs__.openSync(path, flags)`
82
+ end
83
+
84
+ attr_reader :path
85
+
86
+ def write string
87
+ `__fs__.writeSync(#{@fd}, #{string}, null, #{string}.length)`
88
+ end
89
+
90
+ def flush
91
+ `__fs__.fsyncSync(#@fd)`
92
+ end
93
+
94
+ def close
95
+ `__fs__.closeSync(#{@fd})`
96
+ end
97
+ end
98
+
@@ -0,0 +1,26 @@
1
+ module FileUtils
2
+ extend self
3
+ `var __fs__ = #{File}.__fs__`
4
+
5
+ def mkdir_p path
6
+ return true if File.directory? path
7
+ `__fs__.mkdirSync(#{path})`
8
+ end
9
+
10
+ def cp source, target
11
+ target = File.join(target, File.basename(source)) if File.directory? target
12
+ `__fs__.writeFileSync(target, __fs__.readFileSync(source));`
13
+ end
14
+
15
+ def rm path
16
+ `__fs__.unlinkSync(path)`
17
+ end
18
+
19
+ def mv source, target
20
+ target = File.join(target, File.basename(source)) if File.directory? target
21
+ `__fs__.renameSync(source, target)`
22
+ end
23
+
24
+ alias mkpath mkdir_p
25
+ alias makedirs mkdir_p
26
+ end
@@ -0,0 +1,2 @@
1
+ $stdout.write_proc = -> (string) {`process.stdout.write(#{string})`}
2
+ $stderr.write_proc = -> (string) {`process.stderr.write(string)`}
@@ -0,0 +1,45 @@
1
+ require 'native'
2
+
3
+ NodeRepl = Native(`OpalNode.node_require('repl')`)
4
+
5
+ def NodeRepl.start opations = {}
6
+ Native::Object.new(`#@native.start(#{opations.to_n})`)
7
+ end
8
+
9
+ line = 1
10
+ prompt_interrupted = false
11
+
12
+ prompt = ->(_self) {
13
+ tip = prompt_interrupted ? '*' : '>'
14
+ "irb(#{_self.to_s}):#{line.to_s.rjust(3, '0')}#{tip} "
15
+ }
16
+
17
+ $repl = NodeRepl.start prompt: prompt.call(self),
18
+ useGlobal: true, ignoreUndefined: true,
19
+ eval: -> (cmd, context, filename, callback) {
20
+ line += 1
21
+
22
+ cmd = cmd[1...-1].chomp
23
+
24
+ if cmd.empty?
25
+ prompt_interrupted = true
26
+ $repl.prompt = prompt.call(self)
27
+
28
+ callback.call('')
29
+ next
30
+ end
31
+
32
+ prompt_interrupted = false
33
+ $repl.prompt = prompt.call(self)
34
+
35
+ begin
36
+ result = `OpalNode.run(cmd, filename)`
37
+ result = nil if `#{result} == nil`
38
+ callback.call('=> '+result.inspect)
39
+ rescue => e
40
+ callback.call(e.backtrace.join("\n"))
41
+ end
42
+ }
43
+
44
+ # Add a newline before exiting
45
+ $repl.on :exit, -> { puts }
@@ -0,0 +1,16 @@
1
+ module Kernel
2
+ def exit
3
+ `process.exit()`
4
+ end
5
+ end
6
+
7
+ ARGV = `process.argv.slice(2)`
8
+
9
+ ENV = Object.new
10
+ def ENV.[]= name, value
11
+ `process.env[#{name.to_s}] = #{value.to_s}`
12
+ end
13
+
14
+ def ENV.[] name
15
+ `process.env[#{name}] || nil`
16
+ end
@@ -0,0 +1,32 @@
1
+ require 'opal-parser'
2
+
3
+ module Kernel
4
+ def __prepare_require__(path)
5
+ name = `$opal.normalize_loadable_path(#{path})`
6
+ full_path = name.end_with?('.rb') ? name : name+'.rb'
7
+
8
+ if `!$opal.modules[#{name}]`
9
+ ruby = File.read(full_path)
10
+ compiler = Opal::Compiler.new(ruby, requirable: true, file: name)
11
+ js = compiler.compile
12
+ compiler.requires.each do |sub_path|
13
+ __prepare_require__(sub_path)
14
+ end
15
+ `eval(#{js})`
16
+ end
17
+
18
+ name
19
+ rescue => e
20
+ raise [path, name, full_path].inspect+e.message
21
+ end
22
+
23
+ def require path
24
+ name = __prepare_require__(path)
25
+ `$opal.require(#{name})`
26
+ end
27
+
28
+ def load path
29
+ name = __prepare_require__(path)
30
+ `$opal.load(#{name})`
31
+ end
32
+ end
@@ -0,0 +1,68 @@
1
+ require 'json'
2
+
3
+ module Gem
4
+ class Install
5
+ def initialize(name, version)
6
+ @name = name
7
+ @version = version
8
+ end
9
+
10
+ def version
11
+ @version ||= latest_version(name)
12
+ end
13
+
14
+ def latest_version(name)
15
+ command = curl("https://rubygems.org/api/v1/versions/#{name}.json")
16
+ versions = JSON.parse system(command)
17
+ versions.first['number']
18
+ end
19
+
20
+ def full_name
21
+ "#{name}-#{version}"
22
+ end
23
+
24
+ def gem_home
25
+ ENV['HOME']+'/.opal-node/opal-gems/#{RUBY_ENGINE_VERSION}'
26
+ end
27
+
28
+ def gems_dir
29
+ File.join(gem_home, :gems)
30
+ end
31
+
32
+ def specs_dir
33
+ File.join(gem_home, :specs)
34
+ end
35
+
36
+ def perform
37
+ gem_dir = File.join(gems_dir, full_name)
38
+ spec_dir = File.join(specs_dir, full_name+'.yml')
39
+ system "mkdir -p #{gem_dir} #{spec_dir}"
40
+
41
+ Dir.chdir gem_dir do
42
+ system curl("https://rubygems.org/downloads/#{name}-#{version}.gem") + '| tar -xv'
43
+ system "gunzip metadata.gz --stdout > #{specs_dir}/#{full_name}.yml"
44
+ system "gunzip data.tar.gz"
45
+ system "tar -xvf data.tar"
46
+ end
47
+ end
48
+
49
+ def curl url
50
+ "curl -L #{url}"
51
+ end
52
+ end
53
+ end
54
+
55
+ command = ARGV.shift
56
+ case command
57
+ when 'install'
58
+ name = ARGV.shift
59
+ if ARGV.include? '-v'
60
+ version = ARGV[ ARGV.index('-v')+1 ]
61
+ else
62
+ version = nil
63
+ end
64
+ install = Gem::Install.new(name, version)
65
+ install.perform
66
+ else
67
+ raise NotImplementedError, "sorry, the #{command.inspect} is not implemented."
68
+ end
@@ -0,0 +1,25 @@
1
+ %x{
2
+ // Generated by CoffeeScript 1.6.3
3
+ (function() {
4
+ var OpalNode, extensions, fs, parser, parserFile, source, sourceFile, vm, __path__;
5
+ fs = require('fs');
6
+ __path__ = require('path');
7
+ vm = require('vm');
8
+ // vm.runInThisContext(parser, parserFile);
9
+ OpalNode = (function() {
10
+ function OpalNode() {}
11
+ OpalNode.node_require = require;
12
+ return OpalNode;
13
+ })();
14
+
15
+ global.OpalNode = OpalNode;
16
+
17
+ }).call(this);
18
+ }
19
+
20
+ module NodeJS
21
+ def self.require name
22
+ `OpalNode.node_require(#{name})`
23
+ end
24
+ end
25
+
@@ -0,0 +1,11 @@
1
+ require 'native'
2
+
3
+ module YAML
4
+ `var __yaml__ = OpalNode.node_require('js-yaml')`
5
+
6
+ def self.load_path path
7
+ loaded = `__yaml__.yaml.safeLoad(#{File.__fs__}.readFileSync(#{path}, 'utf8'))`
8
+ loaded = Hash.new(loaded) if native?(loaded)
9
+ loaded
10
+ end
11
+ end
@@ -0,0 +1,202 @@
1
+ #
2
+ # Implementation of the _Observer_ object-oriented design pattern. The
3
+ # following documentation is copied, with modifications, from "Programming
4
+ # Ruby", by Hunt and Thomas; http://www.ruby-doc.org/docs/ProgrammingRuby/html/lib_patterns.html.
5
+ #
6
+ # See Observable for more info.
7
+
8
+ # The Observer pattern (also known as publish/subscribe) provides a simple
9
+ # mechanism for one object to inform a set of interested third-party objects
10
+ # when its state changes.
11
+ #
12
+ # == Mechanism
13
+ #
14
+ # The notifying class mixes in the +Observable+
15
+ # module, which provides the methods for managing the associated observer
16
+ # objects.
17
+ #
18
+ # The observers must implement a method called +update+ to receive
19
+ # notifications.
20
+ #
21
+ # The observable object must:
22
+ # * assert that it has +#changed+
23
+ # * call +#notify_observers+
24
+ #
25
+ # === Example
26
+ #
27
+ # The following example demonstrates this nicely. A +Ticker+, when run,
28
+ # continually receives the stock +Price+ for its <tt>@symbol</tt>. A +Warner+
29
+ # is a general observer of the price, and two warners are demonstrated, a
30
+ # +WarnLow+ and a +WarnHigh+, which print a warning if the price is below or
31
+ # above their set limits, respectively.
32
+ #
33
+ # The +update+ callback allows the warners to run without being explicitly
34
+ # called. The system is set up with the +Ticker+ and several observers, and the
35
+ # observers do their duty without the top-level code having to interfere.
36
+ #
37
+ # Note that the contract between publisher and subscriber (observable and
38
+ # observer) is not declared or enforced. The +Ticker+ publishes a time and a
39
+ # price, and the warners receive that. But if you don't ensure that your
40
+ # contracts are correct, nothing else can warn you.
41
+ #
42
+ # require "observer"
43
+ #
44
+ # class Ticker ### Periodically fetch a stock price.
45
+ # include Observable
46
+ #
47
+ # def initialize(symbol)
48
+ # @symbol = symbol
49
+ # end
50
+ #
51
+ # def run
52
+ # lastPrice = nil
53
+ # loop do
54
+ # price = Price.fetch(@symbol)
55
+ # print "Current price: #{price}\n"
56
+ # if price != lastPrice
57
+ # changed # notify observers
58
+ # lastPrice = price
59
+ # notify_observers(Time.now, price)
60
+ # end
61
+ # sleep 1
62
+ # end
63
+ # end
64
+ # end
65
+ #
66
+ # class Price ### A mock class to fetch a stock price (60 - 140).
67
+ # def Price.fetch(symbol)
68
+ # 60 + rand(80)
69
+ # end
70
+ # end
71
+ #
72
+ # class Warner ### An abstract observer of Ticker objects.
73
+ # def initialize(ticker, limit)
74
+ # @limit = limit
75
+ # ticker.add_observer(self)
76
+ # end
77
+ # end
78
+ #
79
+ # class WarnLow < Warner
80
+ # def update(time, price) # callback for observer
81
+ # if price < @limit
82
+ # print "--- #{time.to_s}: Price below #@limit: #{price}\n"
83
+ # end
84
+ # end
85
+ # end
86
+ #
87
+ # class WarnHigh < Warner
88
+ # def update(time, price) # callback for observer
89
+ # if price > @limit
90
+ # print "+++ #{time.to_s}: Price above #@limit: #{price}\n"
91
+ # end
92
+ # end
93
+ # end
94
+ #
95
+ # ticker = Ticker.new("MSFT")
96
+ # WarnLow.new(ticker, 80)
97
+ # WarnHigh.new(ticker, 120)
98
+ # ticker.run
99
+ #
100
+ # Produces:
101
+ #
102
+ # Current price: 83
103
+ # Current price: 75
104
+ # --- Sun Jun 09 00:10:25 CDT 2002: Price below 80: 75
105
+ # Current price: 90
106
+ # Current price: 134
107
+ # +++ Sun Jun 09 00:10:25 CDT 2002: Price above 120: 134
108
+ # Current price: 134
109
+ # Current price: 112
110
+ # Current price: 79
111
+ # --- Sun Jun 09 00:10:25 CDT 2002: Price below 80: 79
112
+ module Observable
113
+
114
+ #
115
+ # Add +observer+ as an observer on this object. so that it will receive
116
+ # notifications.
117
+ #
118
+ # +observer+:: the object that will be notified of changes.
119
+ # +func+:: Symbol naming the method that will be called when this Observable
120
+ # has changes.
121
+ #
122
+ # This method must return true for +observer.respond_to?+ and will
123
+ # receive <tt>*arg</tt> when #notify_observers is called, where
124
+ # <tt>*arg</tt> is the value passed to #notify_observers by this
125
+ # Observable
126
+ def add_observer(observer, func=:update)
127
+ @observer_peers = {} unless defined? @observer_peers
128
+ unless observer.respond_to? func
129
+ raise NoMethodError, "observer does not respond to `#{func.to_s}'"
130
+ end
131
+ @observer_peers[observer] = func
132
+ end
133
+
134
+ #
135
+ # Remove +observer+ as an observer on this object so that it will no longer
136
+ # receive notifications.
137
+ #
138
+ # +observer+:: An observer of this Observable
139
+ def delete_observer(observer)
140
+ @observer_peers.delete observer if defined? @observer_peers
141
+ end
142
+
143
+ #
144
+ # Remove all observers associated with this object.
145
+ #
146
+ def delete_observers
147
+ @observer_peers.clear if defined? @observer_peers
148
+ end
149
+
150
+ #
151
+ # Return the number of observers associated with this object.
152
+ #
153
+ def count_observers
154
+ if defined? @observer_peers
155
+ @observer_peers.size
156
+ else
157
+ 0
158
+ end
159
+ end
160
+
161
+ #
162
+ # Set the changed state of this object. Notifications will be sent only if
163
+ # the changed +state+ is +true+.
164
+ #
165
+ # +state+:: Boolean indicating the changed state of this Observable.
166
+ #
167
+ def changed(state=true)
168
+ @observer_state = state
169
+ end
170
+
171
+ #
172
+ # Returns true if this object's state has been changed since the last
173
+ # #notify_observers call.
174
+ #
175
+ def changed?
176
+ if defined? @observer_state and @observer_state
177
+ true
178
+ else
179
+ false
180
+ end
181
+ end
182
+
183
+ #
184
+ # Notify observers of a change in state *if* this object's changed state is
185
+ # +true+.
186
+ #
187
+ # This will invoke the method named in #add_observer, passing <tt>*arg</tt>.
188
+ # The changed state is then set to +false+.
189
+ #
190
+ # <tt>*arg</tt>:: Any arguments to pass to the observers.
191
+ def notify_observers(*arg)
192
+ if defined? @observer_state and @observer_state
193
+ if defined? @observer_peers
194
+ @observer_peers.each do |k, v|
195
+ k.send v, *arg
196
+ end
197
+ end
198
+ @observer_state = false
199
+ end
200
+ end
201
+
202
+ end