edn2023 1.1.4
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/.gitignore +19 -0
- data/.travis.yml +7 -0
- data/CHANGELOG.md +29 -0
- data/Gemfile +6 -0
- data/LICENSE +22 -0
- data/README.md +268 -0
- data/Rakefile +12 -0
- data/edn2023.gemspec +22 -0
- data/lib/edn/char_stream.rb +84 -0
- data/lib/edn/core_ext.rb +112 -0
- data/lib/edn/metadata.rb +27 -0
- data/lib/edn/parser.rb +92 -0
- data/lib/edn/reader.rb +23 -0
- data/lib/edn/ruby_edn_parser.rb +266 -0
- data/lib/edn/type/list.rb +13 -0
- data/lib/edn/type/symbol.rb +39 -0
- data/lib/edn/type/unknown.rb +9 -0
- data/lib/edn/type/uuid.rb +9 -0
- data/lib/edn/types.rb +3 -0
- data/lib/edn/version.rb +3 -0
- data/lib/edn.rb +80 -0
- data/spec/edn/char_stream_spec.rb +111 -0
- data/spec/edn/metadata_spec.rb +38 -0
- data/spec/edn/parser_spec.rb +162 -0
- data/spec/edn/reader_spec.rb +23 -0
- data/spec/edn_spec.rb +114 -0
- data/spec/exemplars/big_decimal.edn +1 -0
- data/spec/exemplars/big_decimal.rb +1 -0
- data/spec/exemplars/big_int.edn +1 -0
- data/spec/exemplars/big_int.rb +1 -0
- data/spec/exemplars/char.edn +1 -0
- data/spec/exemplars/char.rb +1 -0
- data/spec/exemplars/empty_string.edn +1 -0
- data/spec/exemplars/empty_string.rb +1 -0
- data/spec/exemplars/false.edn +1 -0
- data/spec/exemplars/false.rb +1 -0
- data/spec/exemplars/float.edn +1 -0
- data/spec/exemplars/float.rb +1 -0
- data/spec/exemplars/float_neg_exp.edn +1 -0
- data/spec/exemplars/float_neg_exp.rb +1 -0
- data/spec/exemplars/float_point_dec_neg_exp.edn +1 -0
- data/spec/exemplars/float_point_dec_neg_exp.rb +1 -0
- data/spec/exemplars/float_point_plus_exp.edn +1 -0
- data/spec/exemplars/float_point_plus_exp.rb +1 -0
- data/spec/exemplars/float_pointneg_exp.edn +1 -0
- data/spec/exemplars/float_pointneg_exp.rb +1 -0
- data/spec/exemplars/float_pos_exp.edn +1 -0
- data/spec/exemplars/float_pos_exp.rb +1 -0
- data/spec/exemplars/float_sign_exp.edn +1 -0
- data/spec/exemplars/float_sign_exp.rb +1 -0
- data/spec/exemplars/float_with_exp.edn +1 -0
- data/spec/exemplars/float_with_exp.rb +1 -0
- data/spec/exemplars/float_with_exp_no_dec.edn +1 -0
- data/spec/exemplars/float_with_exp_no_dec.rb +1 -0
- data/spec/exemplars/gt_symbol.edn +1 -0
- data/spec/exemplars/gt_symbol.rb +1 -0
- data/spec/exemplars/integer.edn +1 -0
- data/spec/exemplars/integer.rb +1 -0
- data/spec/exemplars/keyword.edn +1 -0
- data/spec/exemplars/keyword.rb +1 -0
- data/spec/exemplars/keyword_with_namespace.edn +1 -0
- data/spec/exemplars/keyword_with_namespace.rb +1 -0
- data/spec/exemplars/list_empty.edn +1 -0
- data/spec/exemplars/list_empty.rb +1 -0
- data/spec/exemplars/list_mixed.edn +1 -0
- data/spec/exemplars/list_mixed.rb +1 -0
- data/spec/exemplars/list_nested.edn +1 -0
- data/spec/exemplars/list_nested.rb +1 -0
- data/spec/exemplars/list_one_element.edn +1 -0
- data/spec/exemplars/list_one_element.rb +1 -0
- data/spec/exemplars/long_string.edn +1 -0
- data/spec/exemplars/long_string.rb +1 -0
- data/spec/exemplars/map_empty.edn +1 -0
- data/spec/exemplars/map_empty.rb +1 -0
- data/spec/exemplars/map_nested.edn +1 -0
- data/spec/exemplars/map_nested.rb +1 -0
- data/spec/exemplars/map_one_element.edn +1 -0
- data/spec/exemplars/map_one_element.rb +1 -0
- data/spec/exemplars/map_two_entry.edn +1 -0
- data/spec/exemplars/map_two_entry.rb +1 -0
- data/spec/exemplars/mmv +4 -0
- data/spec/exemplars/nil.edn +1 -0
- data/spec/exemplars/nil.rb +1 -0
- data/spec/exemplars/set_empty.edn +1 -0
- data/spec/exemplars/set_empty.rb +1 -0
- data/spec/exemplars/set_nested.edn +1 -0
- data/spec/exemplars/set_nested.rb +1 -0
- data/spec/exemplars/set_one_element.edn +1 -0
- data/spec/exemplars/set_one_element.rb +1 -0
- data/spec/exemplars/set_two_elements.edn +1 -0
- data/spec/exemplars/set_two_elements.rb +1 -0
- data/spec/exemplars/simple_skip.edn +1 -0
- data/spec/exemplars/simple_skip.rb +1 -0
- data/spec/exemplars/skip_more_space.edn +1 -0
- data/spec/exemplars/skip_more_space.rb +1 -0
- data/spec/exemplars/skip_more_vector_elements.edn +1 -0
- data/spec/exemplars/skip_more_vector_elements.rb +1 -0
- data/spec/exemplars/skip_some_vector_elements.edn +1 -0
- data/spec/exemplars/skip_some_vector_elements.rb +1 -0
- data/spec/exemplars/skip_two_vector_elements.edn +1 -0
- data/spec/exemplars/skip_two_vector_elements.rb +1 -0
- data/spec/exemplars/skip_vector_element.edn +1 -0
- data/spec/exemplars/skip_vector_element.rb +1 -0
- data/spec/exemplars/skip_with_spaces.edn +1 -0
- data/spec/exemplars/skip_with_spaces.rb +1 -0
- data/spec/exemplars/skip_yet_more_space.edn +1 -0
- data/spec/exemplars/skip_yet_more_space.rb +1 -0
- data/spec/exemplars/special_symbol.edn +1 -0
- data/spec/exemplars/special_symbol.rb +1 -0
- data/spec/exemplars/string_with_newline.edn +1 -0
- data/spec/exemplars/string_with_newline.rb +1 -0
- data/spec/exemplars/symbol.edn +1 -0
- data/spec/exemplars/symbol.rb +1 -0
- data/spec/exemplars/symbol_begins_with_false.edn +1 -0
- data/spec/exemplars/symbol_begins_with_false.rb +1 -0
- data/spec/exemplars/symbol_begins_with_nil.edn +1 -0
- data/spec/exemplars/symbol_begins_with_nil.rb +1 -0
- data/spec/exemplars/symbol_with_dash.edn +1 -0
- data/spec/exemplars/symbol_with_dash.rb +1 -0
- data/spec/exemplars/symbol_with_namespace.edn +1 -0
- data/spec/exemplars/symbol_with_namespace.rb +1 -0
- data/spec/exemplars/tagged_instant.edn +1 -0
- data/spec/exemplars/tagged_instant.rb +1 -0
- data/spec/exemplars/tagged_uuid.edn +1 -0
- data/spec/exemplars/tagged_uuid.rb +1 -0
- data/spec/exemplars/true.edn +1 -0
- data/spec/exemplars/true.rb +1 -0
- data/spec/exemplars/utf8.edn +1 -0
- data/spec/exemplars/utf8.rb +1 -0
- data/spec/exemplars/vector_empty.edn +1 -0
- data/spec/exemplars/vector_empty.rb +1 -0
- data/spec/exemplars/vector_mixed.edn +1 -0
- data/spec/exemplars/vector_mixed.rb +1 -0
- data/spec/exemplars/vector_nested.edn +1 -0
- data/spec/exemplars/vector_nested.rb +1 -0
- data/spec/exemplars/vector_one_element.edn +1 -0
- data/spec/exemplars/vector_one_element.rb +1 -0
- data/spec/exemplars/whole_number_with_exp.edn +1 -0
- data/spec/exemplars/whole_number_with_exp.rb +1 -0
- data/spec/spec_helper.rb +164 -0
- metadata +357 -0
@@ -0,0 +1,162 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe 'edn_parser' do
|
4
|
+
include RantlyHelpers
|
5
|
+
|
6
|
+
let(:parser) { EDN.new_parser }
|
7
|
+
|
8
|
+
it "can contain comments" do
|
9
|
+
edn = ";; This is some sample data\n[1 2 ;; the first two values\n3]"
|
10
|
+
EDN.read(edn).should == [1, 2, 3]
|
11
|
+
end
|
12
|
+
|
13
|
+
it "can discard using the discard reader macro" do
|
14
|
+
edn = "[1 2 #_3 {:foo #_bar :baz}]"
|
15
|
+
EDN.read(edn).should == [1, 2, {:foo => :baz}]
|
16
|
+
end
|
17
|
+
|
18
|
+
context "element" do
|
19
|
+
it "should consume metadata with the element" do
|
20
|
+
x = EDN.read('^{:doc "test"} [1 2]')
|
21
|
+
x.should == [1, 2]
|
22
|
+
x.metadata.should == {doc: "test"}
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
context "integer" do
|
27
|
+
it "should consume integers" do
|
28
|
+
rant(RantlyHelpers::INTEGER).each do |int|
|
29
|
+
(EDN.read int.to_s).should == int.to_i
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
it "should consume integers prefixed with a +" do
|
34
|
+
rant(RantlyHelpers::INTEGER).each do |int|
|
35
|
+
(EDN.read "+#{int.to_i.abs.to_s}").should == int.to_i.abs
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
context "float" do
|
41
|
+
it "should consume simple floats" do
|
42
|
+
rant(RantlyHelpers::FLOAT).each do |float|
|
43
|
+
EDN.read(float.to_s).should == float.to_f
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
47
|
+
it "should consume floats with exponents" do
|
48
|
+
rant(RantlyHelpers::FLOAT_WITH_EXP).each do |float|
|
49
|
+
EDN.read(float.to_s).should == float.to_f
|
50
|
+
end
|
51
|
+
end
|
52
|
+
|
53
|
+
it "should consume floats prefixed with a +" do
|
54
|
+
rant(RantlyHelpers::FLOAT).each do |float|
|
55
|
+
EDN.read("+#{float.to_f.abs.to_s}").should == float.to_f.abs
|
56
|
+
end
|
57
|
+
end
|
58
|
+
end
|
59
|
+
|
60
|
+
context "symbol" do
|
61
|
+
context "special cases" do
|
62
|
+
it "should consume '/'" do
|
63
|
+
EDN.read('/').should == EDN::Type::Symbol.new(:"/")
|
64
|
+
end
|
65
|
+
|
66
|
+
it "should consume '.'" do
|
67
|
+
EDN.read('.').should == EDN::Type::Symbol.new(:".")
|
68
|
+
end
|
69
|
+
|
70
|
+
it "should consume '-'" do
|
71
|
+
EDN.read('-').should == EDN::Type::Symbol.new(:"-")
|
72
|
+
end
|
73
|
+
end
|
74
|
+
end
|
75
|
+
|
76
|
+
context "keyword" do
|
77
|
+
it "should consume any keywords" do
|
78
|
+
rant(RantlyHelpers::SYMBOL).each do |symbol|
|
79
|
+
EDN.read(":#{symbol}").should == symbol.to_sym
|
80
|
+
end
|
81
|
+
end
|
82
|
+
end
|
83
|
+
|
84
|
+
context "string" do
|
85
|
+
it "should consume any string" do
|
86
|
+
rant(RantlyHelpers::RUBY_STRING).each do |string|
|
87
|
+
EDN.read(string.to_edn).should == string
|
88
|
+
end
|
89
|
+
end
|
90
|
+
end
|
91
|
+
|
92
|
+
context "character" do
|
93
|
+
it "should consume any character" do
|
94
|
+
rant(RantlyHelpers::RUBY_CHAR).each do |char|
|
95
|
+
EDN.read(char.to_edn).should == char
|
96
|
+
end
|
97
|
+
end
|
98
|
+
end
|
99
|
+
|
100
|
+
context "vector" do
|
101
|
+
it "should consume an empty vector" do
|
102
|
+
EDN.read('[]').should == []
|
103
|
+
EDN.read('[ ]').should == []
|
104
|
+
end
|
105
|
+
|
106
|
+
it "should consume vectors of mixed elements" do
|
107
|
+
rant(RantlyHelpers::VECTOR).each do |vector|
|
108
|
+
expect { EDN.read(vector) }.to_not raise_error
|
109
|
+
end
|
110
|
+
end
|
111
|
+
end
|
112
|
+
|
113
|
+
context "list" do
|
114
|
+
it "should consume an empty list" do
|
115
|
+
EDN.read('()').should == []
|
116
|
+
EDN.read('( )').should == []
|
117
|
+
end
|
118
|
+
|
119
|
+
it "should consume lists of mixed elements" do
|
120
|
+
rant(RantlyHelpers::LIST).each do |list|
|
121
|
+
expect { EDN.read(list) }.to_not raise_error
|
122
|
+
end
|
123
|
+
end
|
124
|
+
end
|
125
|
+
|
126
|
+
context "set" do
|
127
|
+
it "should consume an empty set" do
|
128
|
+
EDN.read('#{}').should == Set.new
|
129
|
+
EDN.read('#{ }').should == Set.new
|
130
|
+
end
|
131
|
+
|
132
|
+
it "should consume sets of mixed elements" do
|
133
|
+
rant(RantlyHelpers::SET).each do |set|
|
134
|
+
EDN.read(set)
|
135
|
+
end
|
136
|
+
end
|
137
|
+
end
|
138
|
+
|
139
|
+
context "map" do
|
140
|
+
it "should consume maps of mixed elements" do
|
141
|
+
rant(RantlyHelpers::MAP).each do |map|
|
142
|
+
expect { EDN.read(map) }.not_to raise_error
|
143
|
+
end
|
144
|
+
end
|
145
|
+
end
|
146
|
+
|
147
|
+
context "tagged element" do
|
148
|
+
context "#inst" do
|
149
|
+
it "should consume #inst" do
|
150
|
+
rant(RantlyHelpers::INST).each do |element|
|
151
|
+
expect { EDN.read(element) }.not_to raise_error
|
152
|
+
end
|
153
|
+
end
|
154
|
+
end
|
155
|
+
|
156
|
+
it "should consume tagged elements" do
|
157
|
+
rant(RantlyHelpers::TAGGED_ELEMENT).each do |element|
|
158
|
+
expect { EDN.read(element) }.not_to raise_error
|
159
|
+
end
|
160
|
+
end
|
161
|
+
end
|
162
|
+
end
|
@@ -0,0 +1,23 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe EDN::Reader do
|
4
|
+
let(:reader) { EDN::Reader.new("[1 2] 3 :a {:b c} ") }
|
5
|
+
|
6
|
+
it "should read each value" do
|
7
|
+
reader.read.should == [1, 2]
|
8
|
+
reader.read.should == 3
|
9
|
+
reader.read.should == :a
|
10
|
+
reader.read.should == {:b => ~"c"}
|
11
|
+
end
|
12
|
+
|
13
|
+
it "should respond to each" do
|
14
|
+
reader.each do |element|
|
15
|
+
element.should_not be_nil
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
it "returns a special end of file value if asked" do
|
20
|
+
4.times { reader.read(:the_end).should_not == :the_end }
|
21
|
+
reader.read(:no_more).should == :no_more
|
22
|
+
end
|
23
|
+
end
|
data/spec/edn_spec.rb
ADDED
@@ -0,0 +1,114 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
require 'stringio'
|
3
|
+
|
4
|
+
describe EDN do
|
5
|
+
include RantlyHelpers
|
6
|
+
|
7
|
+
ExemplarPattern = "#{File.dirname(__FILE__)}/exemplars/*.edn"
|
8
|
+
|
9
|
+
context 'Exemplar' do
|
10
|
+
edn_files = Dir[ExemplarPattern]
|
11
|
+
edn_files.each do |edn_file|
|
12
|
+
rb_file = edn_file.sub(/\.edn$/, '.rb')
|
13
|
+
it "reads file #{File.basename(edn_file)} correctly" do
|
14
|
+
expected = eval(File.read(rb_file))
|
15
|
+
actual = EDN.read(File.read(edn_file))
|
16
|
+
actual.should == expected
|
17
|
+
end
|
18
|
+
|
19
|
+
it "round trips the value in #{File.basename(edn_file)} correctly" do
|
20
|
+
expected = eval(File.read(rb_file))
|
21
|
+
actual = EDN.read(File.read(edn_file))
|
22
|
+
round_trip = EDN.read(actual.to_edn)
|
23
|
+
round_trip.should == expected
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
|
29
|
+
context "#read" do
|
30
|
+
#it "reads from a stream" do
|
31
|
+
# io = StringIO.new("123")
|
32
|
+
# EDN.read(io).should == 123
|
33
|
+
#end
|
34
|
+
|
35
|
+
#it "reads mutiple values from a stream" do
|
36
|
+
# io = StringIO.new("123 456 789")
|
37
|
+
# EDN.read(io).should == 123
|
38
|
+
# EDN.read(io).should == 456
|
39
|
+
# EDN.read(io).should == 789
|
40
|
+
#end
|
41
|
+
|
42
|
+
it "raises an exception on eof by default" do
|
43
|
+
expect { EDN.read('') }.to raise_error
|
44
|
+
end
|
45
|
+
|
46
|
+
#it "allows you to specify an eof value" do
|
47
|
+
# io = StringIO.new("123 456")
|
48
|
+
# EDN.read(io, :my_eof).should == 123
|
49
|
+
# EDN.read(io, :my_eof).should == 456
|
50
|
+
# EDN.read(io, :my_eof).should == :my_eof
|
51
|
+
#end
|
52
|
+
|
53
|
+
it "allows you to specify nil as an eof value" do
|
54
|
+
EDN.read("", nil).should == nil
|
55
|
+
end
|
56
|
+
end
|
57
|
+
|
58
|
+
context "reading data" do
|
59
|
+
it "treats carriage returns like whitespace" do
|
60
|
+
EDN.read("\r\n[\r\n]\r\n").should == []
|
61
|
+
EDN.read("\r[\r]\r\r").should == []
|
62
|
+
end
|
63
|
+
|
64
|
+
it "reads any valid element" do
|
65
|
+
elements = rant(RantlyHelpers::ELEMENT)
|
66
|
+
elements.each do |element|
|
67
|
+
begin
|
68
|
+
if element == "nil"
|
69
|
+
EDN.read(element).should be_nil
|
70
|
+
else
|
71
|
+
EDN.read(element).should_not be_nil
|
72
|
+
end
|
73
|
+
rescue Exception => ex
|
74
|
+
puts "Bad element: #{element}"
|
75
|
+
raise ex
|
76
|
+
end
|
77
|
+
end
|
78
|
+
end
|
79
|
+
end
|
80
|
+
|
81
|
+
context "#register" do
|
82
|
+
it "uses the identity function when no handler is given" do
|
83
|
+
EDN.register "some/tag"
|
84
|
+
EDN.read("#some/tag {}").class.should == Hash
|
85
|
+
end
|
86
|
+
end
|
87
|
+
|
88
|
+
context "writing" do
|
89
|
+
it "writes any valid element" do
|
90
|
+
elements = rant(RantlyHelpers::ELEMENT)
|
91
|
+
elements.each do |element|
|
92
|
+
expect {
|
93
|
+
begin
|
94
|
+
EDN.read(element).to_edn
|
95
|
+
rescue Exception => ex
|
96
|
+
puts "Bad element: #{element}"
|
97
|
+
raise ex
|
98
|
+
end
|
99
|
+
}.to_not raise_error
|
100
|
+
end
|
101
|
+
end
|
102
|
+
|
103
|
+
it "writes equivalent edn to what it reads" do
|
104
|
+
elements = rant(RantlyHelpers::ELEMENT)
|
105
|
+
elements.each do |element|
|
106
|
+
ruby_element = EDN.read(element)
|
107
|
+
ruby_element.should == EDN.read(ruby_element.to_edn)
|
108
|
+
if ruby_element.respond_to?(:metadata)
|
109
|
+
ruby_element.metadata.should == EDN.read(ruby_element.to_edn).metadata
|
110
|
+
end
|
111
|
+
end
|
112
|
+
end
|
113
|
+
end
|
114
|
+
end
|
@@ -0,0 +1 @@
|
|
1
|
+
123412341231212121241234M
|
@@ -0,0 +1 @@
|
|
1
|
+
123412341231212121241234
|
@@ -0,0 +1 @@
|
|
1
|
+
123412341231212121241234
|
@@ -0,0 +1 @@
|
|
1
|
+
123412341231212121241234
|
@@ -0,0 +1 @@
|
|
1
|
+
\c
|
@@ -0,0 +1 @@
|
|
1
|
+
"c"
|
@@ -0,0 +1 @@
|
|
1
|
+
""
|
@@ -0,0 +1 @@
|
|
1
|
+
""
|
@@ -0,0 +1 @@
|
|
1
|
+
false
|
@@ -0,0 +1 @@
|
|
1
|
+
false
|
@@ -0,0 +1 @@
|
|
1
|
+
3.14
|
@@ -0,0 +1 @@
|
|
1
|
+
3.14
|
@@ -0,0 +1 @@
|
|
1
|
+
3e-10
|
@@ -0,0 +1 @@
|
|
1
|
+
3.0e-10
|
@@ -0,0 +1 @@
|
|
1
|
+
3.0e-10
|
@@ -0,0 +1 @@
|
|
1
|
+
3.0e-10
|
@@ -0,0 +1 @@
|
|
1
|
+
3.e+10
|
@@ -0,0 +1 @@
|
|
1
|
+
3.0e10
|
@@ -0,0 +1 @@
|
|
1
|
+
3.e-10
|
@@ -0,0 +1 @@
|
|
1
|
+
3.0e-10
|
@@ -0,0 +1 @@
|
|
1
|
+
3e+10
|
@@ -0,0 +1 @@
|
|
1
|
+
3.0e10
|
@@ -0,0 +1 @@
|
|
1
|
+
3.0e+10
|
@@ -0,0 +1 @@
|
|
1
|
+
3.0e10
|
@@ -0,0 +1 @@
|
|
1
|
+
3.0e10
|
@@ -0,0 +1 @@
|
|
1
|
+
3.0e10
|
@@ -0,0 +1 @@
|
|
1
|
+
3.e10
|
@@ -0,0 +1 @@
|
|
1
|
+
3.0e10
|
@@ -0,0 +1 @@
|
|
1
|
+
>
|
@@ -0,0 +1 @@
|
|
1
|
+
EDN::Type::Symbol.new('>')
|
@@ -0,0 +1 @@
|
|
1
|
+
1
|
@@ -0,0 +1 @@
|
|
1
|
+
1
|
@@ -0,0 +1 @@
|
|
1
|
+
:hello
|
@@ -0,0 +1 @@
|
|
1
|
+
:hello
|
@@ -0,0 +1 @@
|
|
1
|
+
:hello/world
|
@@ -0,0 +1 @@
|
|
1
|
+
:"hello/world"
|
@@ -0,0 +1 @@
|
|
1
|
+
()
|
@@ -0,0 +1 @@
|
|
1
|
+
[]
|
@@ -0,0 +1 @@
|
|
1
|
+
("hello" 1 2)
|
@@ -0,0 +1 @@
|
|
1
|
+
['hello', 1, 2]
|
@@ -0,0 +1 @@
|
|
1
|
+
((1 (:hi)))
|
@@ -0,0 +1 @@
|
|
1
|
+
[[1, [:hi]]]
|
@@ -0,0 +1 @@
|
|
1
|
+
(1)
|
@@ -0,0 +1 @@
|
|
1
|
+
[1]
|