ruby2js 3.1.2 → 3.3.3
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.
- checksums.yaml +4 -4
- data/README.md +52 -11
- data/lib/ruby2js.rb +14 -2
- data/lib/ruby2js/converter.rb +11 -3
- data/lib/ruby2js/converter/args.rb +1 -1
- data/lib/ruby2js/converter/block.rb +2 -2
- data/lib/ruby2js/converter/class.rb +4 -3
- data/lib/ruby2js/converter/class2.rb +38 -9
- data/lib/ruby2js/converter/cvar.rb +1 -1
- data/lib/ruby2js/converter/cvasgn.rb +1 -1
- data/lib/ruby2js/converter/def.rb +2 -2
- data/lib/ruby2js/converter/for.rb +7 -0
- data/lib/ruby2js/converter/hash.rb +14 -3
- data/lib/ruby2js/converter/if.rb +13 -2
- data/lib/ruby2js/converter/import.rb +38 -0
- data/lib/ruby2js/converter/logical.rb +46 -1
- data/lib/ruby2js/converter/opasgn.rb +5 -2
- data/lib/ruby2js/converter/regexp.rb +27 -2
- data/lib/ruby2js/converter/return.rb +1 -1
- data/lib/ruby2js/converter/send.rb +53 -27
- data/lib/ruby2js/converter/super.rb +15 -9
- data/lib/ruby2js/converter/xnode.rb +89 -0
- data/lib/ruby2js/es2021.rb +5 -0
- data/lib/ruby2js/es2021/strict.rb +3 -0
- data/lib/ruby2js/filter/cjs.rb +2 -2
- data/lib/ruby2js/filter/esm.rb +72 -0
- data/lib/ruby2js/filter/functions.rb +191 -41
- data/lib/ruby2js/filter/matchAll.rb +49 -0
- data/lib/ruby2js/filter/node.rb +18 -10
- data/lib/ruby2js/filter/nokogiri.rb +13 -13
- data/lib/ruby2js/filter/react.rb +190 -30
- data/lib/ruby2js/filter/require.rb +1 -4
- data/lib/ruby2js/filter/rubyjs.rb +4 -4
- data/lib/ruby2js/filter/vue.rb +15 -15
- data/lib/ruby2js/filter/wunderbar.rb +63 -0
- data/lib/ruby2js/serializer.rb +25 -11
- data/lib/ruby2js/version.rb +2 -2
- data/ruby2js.gemspec +3 -12
- metadata +25 -5
@@ -17,7 +17,7 @@ module Ruby2JS
|
|
17
17
|
end
|
18
18
|
|
19
19
|
def on_send(node)
|
20
|
-
if
|
20
|
+
if \
|
21
21
|
not @require_expr and # only statements
|
22
22
|
node.children.length == 3 and
|
23
23
|
node.children[0] == nil and
|
@@ -39,9 +39,6 @@ module Ruby2JS
|
|
39
39
|
filename = File.join(dirname, basename)
|
40
40
|
|
41
41
|
segments = basename.split(/[\/\\]/)
|
42
|
-
if segments.all? {|path| path =~ @@valid_path and path != '..'}
|
43
|
-
filename.untaint
|
44
|
-
end
|
45
42
|
|
46
43
|
if not File.file? filename and File.file? filename+".rb"
|
47
44
|
filename += '.rb'
|
@@ -20,7 +20,7 @@ module Ruby2JS
|
|
20
20
|
target = target.children.first
|
21
21
|
end
|
22
22
|
|
23
|
-
if
|
23
|
+
if \
|
24
24
|
[:capitalize, :center, :chomp, :ljust, :lstrip, :rindex, :rjust,
|
25
25
|
:rstrip, :scan, :swapcase, :tr].include? method
|
26
26
|
then
|
@@ -28,7 +28,7 @@ module Ruby2JS
|
|
28
28
|
s(:send, s(:lvar, :_s), method,
|
29
29
|
*process_all([node.children[0], *node.children[2..-1]]))
|
30
30
|
|
31
|
-
elsif
|
31
|
+
elsif \
|
32
32
|
[:at, :compact, :compact!, :delete_at, :delete_at, :flatten, :insert,
|
33
33
|
:reverse, :reverse!, :rotate, :rotate, :rotate!, :shift, :shuffle,
|
34
34
|
:shuffle!, :slice, :slice!, :transpose, :union, :uniq, :uniq!]
|
@@ -62,14 +62,14 @@ module Ruby2JS
|
|
62
62
|
method = call.children[1]
|
63
63
|
return super if excluded?(method)
|
64
64
|
|
65
|
-
if
|
65
|
+
if \
|
66
66
|
[:collect_concat, :count, :cycle, :delete_if, :drop_while,
|
67
67
|
:each_index, :each_slice, :each_with_index, :each_with_object,
|
68
68
|
:find, :find_all, :flat_map, :inject, :grep, :group_by, :keep_if,
|
69
69
|
:map, :max_by, :min_by, :one?, :partition, :reject, :reverse_each,
|
70
70
|
:select!, :sort_by, :take_while].include? method
|
71
71
|
then
|
72
|
-
if
|
72
|
+
if \
|
73
73
|
[:collect_concat, :count, :delete_if, :drop_while, :find,
|
74
74
|
:find_all, :flat_map, :grep, :group_by, :keep_if, :map, :max_by,
|
75
75
|
:min_by, :one?, :partition, :reject, :select!, :sort_by,
|
data/lib/ruby2js/filter/vue.rb
CHANGED
@@ -43,7 +43,7 @@ module Ruby2JS
|
|
43
43
|
@vue_h ||= options[:vue_h]
|
44
44
|
filters = options[:filters] || Filter::DEFAULTS
|
45
45
|
|
46
|
-
if
|
46
|
+
if \
|
47
47
|
defined? Ruby2JS::Filter::Functions and
|
48
48
|
filters.include? Ruby2JS::Filter::Functions
|
49
49
|
then
|
@@ -140,7 +140,7 @@ module Ruby2JS
|
|
140
140
|
end
|
141
141
|
end
|
142
142
|
|
143
|
-
elsif
|
143
|
+
elsif \
|
144
144
|
statement.type == :send and statement.children[0] == cname and
|
145
145
|
statement.children[1].to_s.end_with? '='
|
146
146
|
then
|
@@ -161,13 +161,13 @@ module Ruby2JS
|
|
161
161
|
hash << s(:pair, s(:sym, statement.children[1]),
|
162
162
|
statement.children[2])
|
163
163
|
|
164
|
-
elsif
|
164
|
+
elsif \
|
165
165
|
statement.children[1] == :options and
|
166
166
|
statement.children[2].type == :hash
|
167
167
|
then
|
168
168
|
options += statement.children[2].children
|
169
169
|
|
170
|
-
elsif
|
170
|
+
elsif \
|
171
171
|
statement.children[1] == :el and
|
172
172
|
statement.children[2].type == :str
|
173
173
|
then
|
@@ -190,7 +190,7 @@ module Ruby2JS
|
|
190
190
|
|
191
191
|
block = s(:begin, block) unless block and block.type == :begin
|
192
192
|
|
193
|
-
if
|
193
|
+
if \
|
194
194
|
(block.children.length != 1 and
|
195
195
|
not vue_wunderbar_free(block.children[0..-2])) or
|
196
196
|
|
@@ -403,7 +403,7 @@ module Ruby2JS
|
|
403
403
|
end
|
404
404
|
end
|
405
405
|
|
406
|
-
elsif
|
406
|
+
elsif \
|
407
407
|
class_methods.any? do |other_method|
|
408
408
|
other_method.children[1].to_s == "#{method.children[1]}="
|
409
409
|
end
|
@@ -545,7 +545,7 @@ module Ruby2JS
|
|
545
545
|
*values.join(' ').split(' ').
|
546
546
|
map {|str| s(:pair, s(:str, str), s(:true))})
|
547
547
|
else
|
548
|
-
if
|
548
|
+
if \
|
549
549
|
expr.type == :if and expr.children[1] and
|
550
550
|
expr.children[1].type == :str
|
551
551
|
then
|
@@ -847,7 +847,7 @@ module Ruby2JS
|
|
847
847
|
s(:splat, s(:array, *process_all(node.children[2..-1])))
|
848
848
|
end
|
849
849
|
|
850
|
-
elsif
|
850
|
+
elsif \
|
851
851
|
node.children[1] == :createElement and
|
852
852
|
node.children[0] == s(:const, nil, :Vue)
|
853
853
|
then
|
@@ -867,7 +867,7 @@ module Ruby2JS
|
|
867
867
|
element
|
868
868
|
end
|
869
869
|
|
870
|
-
elsif
|
870
|
+
elsif \
|
871
871
|
@vue_self and VUE_METHODS.include? node.children[1] and
|
872
872
|
node.children[0] == s(:const, nil, :Vue)
|
873
873
|
then
|
@@ -929,7 +929,7 @@ module Ruby2JS
|
|
929
929
|
prev = nil
|
930
930
|
(node.children.length-1).downto(0) do |i|
|
931
931
|
child = node.children[i]
|
932
|
-
if
|
932
|
+
if \
|
933
933
|
child.type == :send and child.children[0] == s(:gvar, :$_) and
|
934
934
|
child.children[1] == :push
|
935
935
|
then
|
@@ -968,7 +968,7 @@ module Ruby2JS
|
|
968
968
|
child = node.children.first
|
969
969
|
|
970
970
|
# map Vue.render(el, &block) to Vue.new(el: el, render: block)
|
971
|
-
if
|
971
|
+
if \
|
972
972
|
child.children[1] == :render and
|
973
973
|
child.children[0] == s(:const, nil, :Vue)
|
974
974
|
then
|
@@ -979,7 +979,7 @@ module Ruby2JS
|
|
979
979
|
block = node.children[2]
|
980
980
|
block = s(:begin, block) unless block and block.type == :begin
|
981
981
|
|
982
|
-
if
|
982
|
+
if \
|
983
983
|
block.children.length != 1 or not block.children.last or
|
984
984
|
not [:send, :block].include? block.children.first.type
|
985
985
|
then
|
@@ -999,7 +999,7 @@ module Ruby2JS
|
|
999
999
|
|
1000
1000
|
return super unless @vue_h
|
1001
1001
|
|
1002
|
-
if
|
1002
|
+
if \
|
1003
1003
|
child.children[1] == :createElement and
|
1004
1004
|
child.children[0] == s(:const, nil, :Vue)
|
1005
1005
|
then
|
@@ -1059,7 +1059,7 @@ module Ruby2JS
|
|
1059
1059
|
*node.children[1..-1]))
|
1060
1060
|
end
|
1061
1061
|
|
1062
|
-
elsif
|
1062
|
+
elsif \
|
1063
1063
|
node.children.first.children.last == :forEach and
|
1064
1064
|
vue_element?(node.children.last)
|
1065
1065
|
then
|
@@ -1144,7 +1144,7 @@ module Ruby2JS
|
|
1144
1144
|
node.children[0].children[0].to_s[1..-1]),
|
1145
1145
|
node.children[1], process(node.children[2])]
|
1146
1146
|
|
1147
|
-
elsif
|
1147
|
+
elsif \
|
1148
1148
|
node.children.first.type == :lvasgn and
|
1149
1149
|
@vue_props.include? node.children[0].children[0]
|
1150
1150
|
then
|
@@ -0,0 +1,63 @@
|
|
1
|
+
require 'ruby2js'
|
2
|
+
|
3
|
+
module Ruby2JS
|
4
|
+
module Filter
|
5
|
+
module Wunderbar
|
6
|
+
include SEXP
|
7
|
+
|
8
|
+
def on_send(node)
|
9
|
+
target, method, *attrs = node.children
|
10
|
+
|
11
|
+
if target == s(:const, nil, :Wunderbar)
|
12
|
+
if [:debug, :info, :warn, :error, :fatal].include? method
|
13
|
+
method = :error if method == :fatal
|
14
|
+
return node.updated(nil, [s(:const, nil, :console), method, *attrs])
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
stack = []
|
19
|
+
while target!=nil and target.type==:send and target.children.length==2
|
20
|
+
name = method.to_s
|
21
|
+
if name.end_with? '!'
|
22
|
+
stack << s(:hash, s(:pair, s(:sym, :id), s(:str, name[0..-2])))
|
23
|
+
else
|
24
|
+
stack << s(:hash, s(:pair, s(:sym, :class), s(:str, name)))
|
25
|
+
end
|
26
|
+
target, method = target.children
|
27
|
+
end
|
28
|
+
|
29
|
+
if target == nil and method.to_s.start_with? "_"
|
30
|
+
S(:xnode, *method.to_s[1..-1], *stack, *process_all(attrs))
|
31
|
+
else
|
32
|
+
super
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
def on_block(node)
|
37
|
+
send, args, *block = node.children
|
38
|
+
target, method, *_ = send.children
|
39
|
+
while target!=nil and target.type==:send and target.children.length==2
|
40
|
+
target, method = target.children
|
41
|
+
end
|
42
|
+
|
43
|
+
if target == nil and method.to_s.start_with? "_"
|
44
|
+
if args.children.empty?
|
45
|
+
# append block as a standalone proc
|
46
|
+
process send.updated(nil, [*send.children, *process_all(block)])
|
47
|
+
else
|
48
|
+
# iterate over Enumerable arguments if there are args present
|
49
|
+
send = send.children
|
50
|
+
return super if send.length < 3
|
51
|
+
process s(:block, s(:send, *send[0..1], *send[3..-1]),
|
52
|
+
s(:args), s(:block, s(:send, send[2], :map),
|
53
|
+
*node.children[1..-1]))
|
54
|
+
end
|
55
|
+
else
|
56
|
+
super
|
57
|
+
end
|
58
|
+
end
|
59
|
+
end
|
60
|
+
|
61
|
+
DEFAULTS.push Wunderbar
|
62
|
+
end
|
63
|
+
end
|
data/lib/ruby2js/serializer.rb
CHANGED
@@ -32,8 +32,10 @@ module Ruby2JS
|
|
32
32
|
''
|
33
33
|
elsif ['case ', 'default:'].include? self[0]
|
34
34
|
' ' * ([0,indent-2].max) + join
|
35
|
-
|
35
|
+
elsif indent > 0
|
36
36
|
' ' * indent + join
|
37
|
+
else
|
38
|
+
join
|
37
39
|
end
|
38
40
|
end
|
39
41
|
end
|
@@ -58,7 +60,6 @@ module Ruby2JS
|
|
58
60
|
|
59
61
|
def timestamp(file)
|
60
62
|
if file
|
61
|
-
file = file.dup.untaint
|
62
63
|
@timestamps[file] = File.mtime(file) if File.exist?(file)
|
63
64
|
end
|
64
65
|
end
|
@@ -87,9 +88,21 @@ module Ruby2JS
|
|
87
88
|
first = line.find {|token| !token.empty?}
|
88
89
|
if first
|
89
90
|
last = line[line.rindex {|token| !token.empty?}]
|
90
|
-
|
91
|
-
|
92
|
-
|
91
|
+
if (first.start_with? '<' and line.include? '>') or
|
92
|
+
(last.end_with? '>' and line.include? '<')
|
93
|
+
then
|
94
|
+
node = line.join[/.*?(<.*)/, 1]
|
95
|
+
indent -= @indent if node.start_with? '</'
|
96
|
+
|
97
|
+
line.indent = indent
|
98
|
+
|
99
|
+
node = line.join[/.*(<.*)/, 1]
|
100
|
+
indent += @indent unless node.include? '</' or node.include? '/>'
|
101
|
+
else
|
102
|
+
indent -= @indent if ')}]'.include? first[0] and indent >= @indent
|
103
|
+
line.indent = indent
|
104
|
+
indent += @indent if '({['.include? last[-1]
|
105
|
+
end
|
93
106
|
else
|
94
107
|
line.indent = indent
|
95
108
|
end
|
@@ -102,24 +115,24 @@ module Ruby2JS
|
|
102
115
|
reindent @lines
|
103
116
|
|
104
117
|
(@lines.length-3).downto(0) do |i|
|
105
|
-
if
|
118
|
+
if \
|
106
119
|
@lines[i].length == 0
|
107
120
|
then
|
108
121
|
@lines.delete i
|
109
|
-
elsif
|
122
|
+
elsif \
|
110
123
|
@lines[i+1].comment? and not @lines[i].comment? and
|
111
124
|
@lines[i].indent == @lines[i+1].indent
|
112
125
|
then
|
113
126
|
# before a comment
|
114
127
|
@lines.insert i+1, Line.new
|
115
|
-
elsif
|
128
|
+
elsif \
|
116
129
|
@lines[i].indent == @lines[i+1].indent and
|
117
130
|
@lines[i+1].indent < @lines[i+2].indent and
|
118
131
|
not @lines[i].comment?
|
119
132
|
then
|
120
133
|
# start of indented block
|
121
134
|
@lines.insert i+1, Line.new
|
122
|
-
elsif
|
135
|
+
elsif \
|
123
136
|
@lines[i].indent > @lines[i+1].indent and
|
124
137
|
@lines[i+1].indent == @lines[i+2].indent and
|
125
138
|
not @lines[i+2].empty?
|
@@ -136,7 +149,8 @@ module Ruby2JS
|
|
136
149
|
@line << Token.new(string, @ast)
|
137
150
|
else
|
138
151
|
parts = string.split("\n")
|
139
|
-
|
152
|
+
first = parts.shift
|
153
|
+
@line << Token.new(first, @ast) if first
|
140
154
|
@lines += parts.map {|part| Line.new(Token.new(part, @ast))}
|
141
155
|
@lines << Line.new if string.end_with?("\n")
|
142
156
|
@line = @lines.last
|
@@ -208,7 +222,7 @@ module Ruby2JS
|
|
208
222
|
mark = output_location
|
209
223
|
yield
|
210
224
|
|
211
|
-
if
|
225
|
+
if \
|
212
226
|
@lines.length > mark.first+1 or
|
213
227
|
@lines[mark.first-1].join.length + @line.join.length >= @width
|
214
228
|
then
|
data/lib/ruby2js/version.rb
CHANGED
data/ruby2js.gemspec
CHANGED
@@ -15,18 +15,9 @@ Gem::Specification.new do |s|
|
|
15
15
|
s.files = %w(ruby2js.gemspec README.md) + Dir.glob("{lib}/**/*")
|
16
16
|
s.homepage = "http://github.com/rubys/ruby2js".freeze
|
17
17
|
s.licenses = ["MIT".freeze]
|
18
|
-
s.required_ruby_version = Gem::Requirement.new(">=
|
18
|
+
s.required_ruby_version = Gem::Requirement.new(">= 2.0".freeze)
|
19
19
|
s.summary = "Minimal yet extensible Ruby to JavaScript conversion.".freeze
|
20
20
|
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.2.0') then
|
25
|
-
s.add_runtime_dependency(%q<parser>.freeze, [">= 0"])
|
26
|
-
else
|
27
|
-
s.add_dependency(%q<parser>.freeze, [">= 0"])
|
28
|
-
end
|
29
|
-
else
|
30
|
-
s.add_dependency(%q<parser>.freeze, [">= 0"])
|
31
|
-
end
|
21
|
+
s.add_dependency('parser')
|
22
|
+
s.add_dependency('regexp_parser')
|
32
23
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: ruby2js
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 3.
|
4
|
+
version: 3.3.3
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Sam Ruby
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2020-10-07 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: parser
|
@@ -24,6 +24,20 @@ dependencies:
|
|
24
24
|
- - ">="
|
25
25
|
- !ruby/object:Gem::Version
|
26
26
|
version: '0'
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: regexp_parser
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - ">="
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: '0'
|
34
|
+
type: :runtime
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - ">="
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: '0'
|
27
41
|
description: |2
|
28
42
|
The base package maps Ruby syntax to JavaScript semantics.
|
29
43
|
Filters may be provided to add Ruby-specific or framework specific
|
@@ -60,6 +74,7 @@ files:
|
|
60
74
|
- lib/ruby2js/converter/for.rb
|
61
75
|
- lib/ruby2js/converter/hash.rb
|
62
76
|
- lib/ruby2js/converter/if.rb
|
77
|
+
- lib/ruby2js/converter/import.rb
|
63
78
|
- lib/ruby2js/converter/in.rb
|
64
79
|
- lib/ruby2js/converter/ivar.rb
|
65
80
|
- lib/ruby2js/converter/ivasgn.rb
|
@@ -86,6 +101,7 @@ files:
|
|
86
101
|
- lib/ruby2js/converter/vasgn.rb
|
87
102
|
- lib/ruby2js/converter/while.rb
|
88
103
|
- lib/ruby2js/converter/whilepost.rb
|
104
|
+
- lib/ruby2js/converter/xnode.rb
|
89
105
|
- lib/ruby2js/converter/xstr.rb
|
90
106
|
- lib/ruby2js/es2015.rb
|
91
107
|
- lib/ruby2js/es2015/strict.rb
|
@@ -99,12 +115,16 @@ files:
|
|
99
115
|
- lib/ruby2js/es2019/strict.rb
|
100
116
|
- lib/ruby2js/es2020.rb
|
101
117
|
- lib/ruby2js/es2020/strict.rb
|
118
|
+
- lib/ruby2js/es2021.rb
|
119
|
+
- lib/ruby2js/es2021/strict.rb
|
102
120
|
- lib/ruby2js/execjs.rb
|
103
121
|
- lib/ruby2js/filter.rb
|
104
122
|
- lib/ruby2js/filter/camelCase.rb
|
105
123
|
- lib/ruby2js/filter/cjs.rb
|
124
|
+
- lib/ruby2js/filter/esm.rb
|
106
125
|
- lib/ruby2js/filter/functions.rb
|
107
126
|
- lib/ruby2js/filter/jquery.rb
|
127
|
+
- lib/ruby2js/filter/matchAll.rb
|
108
128
|
- lib/ruby2js/filter/minitest-jasmine.rb
|
109
129
|
- lib/ruby2js/filter/node.rb
|
110
130
|
- lib/ruby2js/filter/nokogiri.rb
|
@@ -114,6 +134,7 @@ files:
|
|
114
134
|
- lib/ruby2js/filter/rubyjs.rb
|
115
135
|
- lib/ruby2js/filter/underscore.rb
|
116
136
|
- lib/ruby2js/filter/vue.rb
|
137
|
+
- lib/ruby2js/filter/wunderbar.rb
|
117
138
|
- lib/ruby2js/haml.rb
|
118
139
|
- lib/ruby2js/rails.rb
|
119
140
|
- lib/ruby2js/serializer.rb
|
@@ -133,15 +154,14 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
133
154
|
requirements:
|
134
155
|
- - ">="
|
135
156
|
- !ruby/object:Gem::Version
|
136
|
-
version:
|
157
|
+
version: '2.0'
|
137
158
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
138
159
|
requirements:
|
139
160
|
- - ">="
|
140
161
|
- !ruby/object:Gem::Version
|
141
162
|
version: '0'
|
142
163
|
requirements: []
|
143
|
-
|
144
|
-
rubygems_version: 2.7.6
|
164
|
+
rubygems_version: 3.1.2
|
145
165
|
signing_key:
|
146
166
|
specification_version: 4
|
147
167
|
summary: Minimal yet extensible Ruby to JavaScript conversion.
|