trackler 2.0.6.36 → 2.0.6.37
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/lib/trackler/version.rb +1 -1
- data/tracks/fsharp/exercises/isogram/IsogramTest.fs +70 -12
- data/tracks/fsharp/exercises/luhn/LuhnTest.fs +103 -9
- data/tracks/fsharp/exercises/nth-prime/NthPrimeTest.fs +53 -14
- data/tracks/go/config.json +5 -0
- data/tracks/go/exercises/forth/cases_test.go +246 -0
- data/tracks/go/exercises/forth/example.go +238 -0
- data/tracks/go/exercises/forth/example_gen.go +99 -0
- data/tracks/go/exercises/forth/forth_test.go +64 -0
- data/tracks/java/exercises/phone-number/src/example/java/PhoneNumber.java +19 -25
- data/tracks/java/exercises/phone-number/src/test/java/PhoneNumberTest.java +44 -30
- data/tracks/ocaml/README.md +11 -0
- data/tracks/ocaml/tools/test-generator/README.md +39 -1
- data/tracks/perl6/.travis.yml +1 -1
- data/tracks/perl6/exercises/allergies/allergies.t +118 -3
- data/tracks/perl6/exercises/atbash-cipher/atbash-cipher.t +91 -3
- data/tracks/perl6/exercises/phone-number/phone-number.t +58 -5
- data/tracks/perl6/exercises/space-age/space-age.t +51 -4
- data/tracks/perl6/exercises/wordy/wordy.t +91 -4
- metadata +6 -7
- data/tracks/perl6/exercises/allergies/cases.json +0 -109
- data/tracks/perl6/exercises/atbash-cipher/cases.json +0 -82
- data/tracks/perl6/exercises/phone-number/cases.json +0 -47
- data/tracks/perl6/exercises/space-age/cases.json +0 -46
- data/tracks/perl6/exercises/wordy/cases.json +0 -89
@@ -1,11 +1,16 @@
|
|
1
|
-
import org.junit.Test;
|
2
1
|
import org.junit.Ignore;
|
3
2
|
import org.junit.Rule;
|
3
|
+
import org.junit.Test;
|
4
4
|
import org.junit.rules.ExpectedException;
|
5
5
|
|
6
|
-
import static org.junit.Assert
|
6
|
+
import static org.junit.Assert.assertEquals;
|
7
7
|
|
8
8
|
public class PhoneNumberTest {
|
9
|
+
private final static String wrongLengthExceptionMessage = "Number must be 10 or 11 digits";
|
10
|
+
private final static String numberIs11DigitsButDoesNotStartWith1ExceptionMessage =
|
11
|
+
"Can only have 11 digits if number starts with '1'";
|
12
|
+
private final static String illegalCharacterExceptionMessage =
|
13
|
+
"Illegal character in phone number. Only digits, spaces, parentheses, hyphens or dots accepted.";
|
9
14
|
|
10
15
|
@Rule
|
11
16
|
public ExpectedException expectedException = ExpectedException.none();
|
@@ -16,7 +21,7 @@ public class PhoneNumberTest {
|
|
16
21
|
final String actualNumber = new PhoneNumber("(123) 456-7890").getNumber();
|
17
22
|
|
18
23
|
assertEquals(
|
19
|
-
|
24
|
+
expectedNumber, actualNumber
|
20
25
|
);
|
21
26
|
}
|
22
27
|
|
@@ -27,68 +32,77 @@ public class PhoneNumberTest {
|
|
27
32
|
final String actualNumber = new PhoneNumber("123.456.7890").getNumber();
|
28
33
|
|
29
34
|
assertEquals(
|
30
|
-
|
35
|
+
expectedNumber, actualNumber
|
31
36
|
);
|
32
37
|
}
|
33
38
|
|
34
39
|
@Ignore
|
35
40
|
@Test
|
36
|
-
public void
|
41
|
+
public void cleansNumberWithMultipleSpaces() {
|
37
42
|
final String expectedNumber = "1234567890";
|
38
|
-
final String actualNumber = new PhoneNumber("
|
43
|
+
final String actualNumber = new PhoneNumber("123 456 7890 ").getNumber();
|
39
44
|
|
40
45
|
assertEquals(
|
41
|
-
|
46
|
+
expectedNumber, actualNumber
|
42
47
|
);
|
43
48
|
}
|
44
49
|
|
45
50
|
@Ignore
|
46
51
|
@Test
|
47
|
-
public void
|
52
|
+
public void invalidWhen9Digits() {
|
48
53
|
expectedException.expect(IllegalArgumentException.class);
|
49
|
-
expectedException.expectMessage(
|
50
|
-
new PhoneNumber("
|
54
|
+
expectedException.expectMessage(wrongLengthExceptionMessage);
|
55
|
+
new PhoneNumber("123456789");
|
51
56
|
}
|
52
57
|
|
53
58
|
@Ignore
|
54
59
|
@Test
|
55
|
-
public void
|
60
|
+
public void invalidWhen11Digits() {
|
56
61
|
expectedException.expect(IllegalArgumentException.class);
|
57
|
-
expectedException.expectMessage(
|
58
|
-
new PhoneNumber("
|
62
|
+
expectedException.expectMessage(numberIs11DigitsButDoesNotStartWith1ExceptionMessage);
|
63
|
+
new PhoneNumber("21234567890");
|
59
64
|
}
|
60
65
|
|
61
66
|
@Ignore
|
62
67
|
@Test
|
63
|
-
public void
|
64
|
-
final String
|
65
|
-
final String
|
68
|
+
public void validWhen11DigitsAndFirstIs1() {
|
69
|
+
final String expectedNumber = "1234567890";
|
70
|
+
final String actualNumber = new PhoneNumber("11234567890").getNumber();
|
66
71
|
|
67
72
|
assertEquals(
|
68
|
-
|
73
|
+
expectedNumber, actualNumber
|
69
74
|
);
|
70
75
|
}
|
71
76
|
|
72
77
|
@Ignore
|
73
78
|
@Test
|
74
|
-
public void
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
assertEquals(
|
79
|
-
expectedPrettyNumber, actualPrettyNumber
|
80
|
-
);
|
79
|
+
public void invalidWhen12Digits() {
|
80
|
+
expectedException.expect(IllegalArgumentException.class);
|
81
|
+
expectedException.expectMessage(wrongLengthExceptionMessage);
|
82
|
+
new PhoneNumber("321234567890");
|
81
83
|
}
|
82
84
|
|
83
85
|
@Ignore
|
84
86
|
@Test
|
85
|
-
public void
|
86
|
-
|
87
|
-
|
87
|
+
public void invalidWithLetters() {
|
88
|
+
expectedException.expect(IllegalArgumentException.class);
|
89
|
+
expectedException.expectMessage(illegalCharacterExceptionMessage);
|
90
|
+
new PhoneNumber("123-abc-7890");
|
91
|
+
}
|
88
92
|
|
89
|
-
|
90
|
-
|
91
|
-
|
93
|
+
@Ignore
|
94
|
+
@Test
|
95
|
+
public void invalidWithPunctuation() {
|
96
|
+
expectedException.expect(IllegalArgumentException.class);
|
97
|
+
expectedException.expectMessage(illegalCharacterExceptionMessage);
|
98
|
+
new PhoneNumber("123-@:!-7890");
|
92
99
|
}
|
93
100
|
|
101
|
+
@Ignore
|
102
|
+
@Test
|
103
|
+
public void invalidWithRightNumberOfDigitsButLettersMixedIn() {
|
104
|
+
expectedException.expect(IllegalArgumentException.class);
|
105
|
+
expectedException.expectMessage(illegalCharacterExceptionMessage);
|
106
|
+
new PhoneNumber("1a2b3c4d5e6f7g8h9i0j");
|
107
|
+
}
|
94
108
|
}
|
data/tracks/ocaml/README.md
CHANGED
@@ -47,6 +47,17 @@ In this example, the Makefile would look for an implementation in ocaml_exercise
|
|
47
47
|
|
48
48
|
All pull requests are run through a Travis CI build, which compiles and runs tests.
|
49
49
|
|
50
|
+
## Canonical test data
|
51
|
+
|
52
|
+
If you are implementing an existing test, there may be "canonical data" for it in the [x-common](https://github.com/exercism/x-common) repository.
|
53
|
+
An example: https://github.com/exercism/x-common/blob/master/exercises/bracket-push/canonical-data.json
|
54
|
+
|
55
|
+
You should base your tests off this data, in order to provide consistency across different language tracks.
|
56
|
+
|
57
|
+
There is a test generator which can create test code from these json files and an OCaml template file that you
|
58
|
+
would need to create. It is a work in progress, so may not work for every exercise. If you wish to use it, there
|
59
|
+
is documentation [here](tools/test-generator/README.md).
|
60
|
+
|
50
61
|
## Feedback
|
51
62
|
|
52
63
|
If you find this documentation is inaccurate or incomplete, or can be improved in any way, please don't hesitate to raise an [issue](https://github.com/exercism/xocaml/issues) or submit a pull request.
|
@@ -1 +1,39 @@
|
|
1
|
-
|
1
|
+
## What does it do
|
2
|
+
|
3
|
+
The test generator takes canonical-data.json files from the x-common folder, and
|
4
|
+
uses them to create Ocaml tests.
|
5
|
+
|
6
|
+
For each exercise, it requires a template file under the tools/test-generator/templates folder.
|
7
|
+
The template format is rather ad-hoc, but works for most of the exercises that have
|
8
|
+
canonical data.
|
9
|
+
|
10
|
+
## Building
|
11
|
+
|
12
|
+
In the folder tools/test-generator, type ```Make```
|
13
|
+
This will build and run the unit tests
|
14
|
+
|
15
|
+
## Running
|
16
|
+
|
17
|
+
The test generator should be run whenever test canonical data is updated.
|
18
|
+
|
19
|
+
You will need the latest version of x-common checked out locally, at the same level as your
|
20
|
+
xocaml repo.
|
21
|
+
|
22
|
+
Please note: running will overwrite tests in the xocaml/exercises folders (this is the default, there
|
23
|
+
is a command line option to write the tests to a different folder - run test_gen.native --help).
|
24
|
+
|
25
|
+
To run, type test_gen.native at the command line.
|
26
|
+
|
27
|
+
If you type git status, you will see test files that have been updated.
|
28
|
+
|
29
|
+
Some files can be generated but will look better after hand-editing. An example is the minesweeper exercise,
|
30
|
+
where a list that is part of the input is better presented in a 2D vertically aligned format. To handle this,
|
31
|
+
the test generator saves it's files in a folder in your home (~/.xocaml-generated - this can be overridden as
|
32
|
+
a command line option). If after generation, the file is unchanged from the saved copy, then the test generator
|
33
|
+
will not overwrite the test in the repo - so git status will be clean.
|
34
|
+
|
35
|
+
## Extending
|
36
|
+
|
37
|
+
If you find an exercise that the generator cannot handle, pull requests to extend it are welcome.
|
38
|
+
|
39
|
+
|
data/tracks/perl6/.travis.yml
CHANGED
@@ -3,15 +3,14 @@
|
|
3
3
|
use Test;
|
4
4
|
use JSON::Tiny;
|
5
5
|
|
6
|
-
use lib
|
6
|
+
use lib $?FILE.IO.dirname;
|
7
7
|
|
8
8
|
my $module = %*ENV<EXERCISM> ?? 'Example' !! 'Allergies';
|
9
9
|
require ::($module) <&allergic-to &list-allergies>;
|
10
10
|
|
11
11
|
plan 2;
|
12
12
|
|
13
|
-
my %cases
|
14
|
-
|
13
|
+
my %cases;
|
15
14
|
subtest 'allergic-to' => {
|
16
15
|
my @cases = |%cases{'allergic_to'}{'cases'};
|
17
16
|
|
@@ -38,3 +37,119 @@ subtest 'list' => {
|
|
38
37
|
or diag $_;
|
39
38
|
}
|
40
39
|
};
|
40
|
+
|
41
|
+
done-testing;
|
42
|
+
|
43
|
+
INIT {
|
44
|
+
%cases := from-json 「
|
45
|
+
{
|
46
|
+
"allergic_to": {
|
47
|
+
"description": [
|
48
|
+
"Given a number and a substance, indicate whether Tom is allergic ",
|
49
|
+
"to that substance.",
|
50
|
+
"Test cases for this method involve more than one assertion.",
|
51
|
+
"Each case in 'expected' specifies what the method should return for",
|
52
|
+
"the given substance."
|
53
|
+
],
|
54
|
+
"cases": [
|
55
|
+
{
|
56
|
+
"description": "no allergies means not allergic",
|
57
|
+
"score": 0,
|
58
|
+
"expected": [
|
59
|
+
{
|
60
|
+
"substance": "peanuts",
|
61
|
+
"result": false
|
62
|
+
},
|
63
|
+
{
|
64
|
+
"substance": "cats",
|
65
|
+
"result": false
|
66
|
+
},
|
67
|
+
{
|
68
|
+
"substance": "strawberries",
|
69
|
+
"result": false
|
70
|
+
}
|
71
|
+
]
|
72
|
+
},
|
73
|
+
{
|
74
|
+
"description": "is allergic to eggs",
|
75
|
+
"score": 1,
|
76
|
+
"expected": [
|
77
|
+
{
|
78
|
+
"substance": "eggs",
|
79
|
+
"result": true
|
80
|
+
}
|
81
|
+
]
|
82
|
+
},
|
83
|
+
{
|
84
|
+
"description": "allergic to eggs in addition to other stuff",
|
85
|
+
"score": 5,
|
86
|
+
"expected": [
|
87
|
+
{
|
88
|
+
"substance": "eggs",
|
89
|
+
"result": true
|
90
|
+
},
|
91
|
+
{
|
92
|
+
"substance": "shellfish",
|
93
|
+
"result": true
|
94
|
+
},
|
95
|
+
{
|
96
|
+
"substance": "strawberries",
|
97
|
+
"result": false
|
98
|
+
}
|
99
|
+
]
|
100
|
+
}
|
101
|
+
]
|
102
|
+
},
|
103
|
+
"list": {
|
104
|
+
"description": ["Given a number, list all things Tom is allergic to"],
|
105
|
+
"cases": [
|
106
|
+
{
|
107
|
+
"description": "no allergies at all",
|
108
|
+
"score": 0,
|
109
|
+
"expected": []
|
110
|
+
},
|
111
|
+
{
|
112
|
+
"description": "allergic to just eggs",
|
113
|
+
"score": 1,
|
114
|
+
"expected": ["eggs"]
|
115
|
+
},
|
116
|
+
{
|
117
|
+
"description": "allergic to just peanuts",
|
118
|
+
"score": 2,
|
119
|
+
"expected": ["peanuts"]
|
120
|
+
},
|
121
|
+
{
|
122
|
+
"description": "allergic to just strawberries",
|
123
|
+
"score": 8,
|
124
|
+
"expected": ["strawberries"]
|
125
|
+
},
|
126
|
+
{
|
127
|
+
"description": "allergic to eggs and peanuts",
|
128
|
+
"score": 3,
|
129
|
+
"expected": ["eggs", "peanuts"]
|
130
|
+
},
|
131
|
+
{
|
132
|
+
"description": "allergic to more than eggs but not peanuts",
|
133
|
+
"score": 5,
|
134
|
+
"expected": ["eggs", "shellfish"]
|
135
|
+
},
|
136
|
+
{
|
137
|
+
"description": "allergic to lots of stuff",
|
138
|
+
"score": 248,
|
139
|
+
"expected": ["strawberries", "tomatoes", "chocolate", "pollen", "cats"]
|
140
|
+
},
|
141
|
+
{
|
142
|
+
"description": "allergic to everything",
|
143
|
+
"score": 255,
|
144
|
+
"expected": ["eggs", "peanuts", "shellfish", "strawberries", "tomatoes", "chocolate", "pollen", "cats"]
|
145
|
+
},
|
146
|
+
{
|
147
|
+
"description": "ignore non allergen score parts",
|
148
|
+
"score": 509,
|
149
|
+
"expected": ["eggs", "shellfish", "strawberries", "tomatoes", "chocolate", "pollen", "cats"]
|
150
|
+
}
|
151
|
+
]
|
152
|
+
}
|
153
|
+
}
|
154
|
+
」
|
155
|
+
}
|
@@ -3,15 +3,14 @@
|
|
3
3
|
use Test;
|
4
4
|
use JSON::Tiny;
|
5
5
|
|
6
|
-
use lib
|
6
|
+
use lib $?FILE.IO.dirname;
|
7
7
|
|
8
8
|
my $module = %*ENV<EXERCISM> ?? 'Example' !! 'Cipher';
|
9
9
|
require ::($module) <&encode &decode>;
|
10
10
|
|
11
11
|
plan 2;
|
12
12
|
|
13
|
-
my %cases
|
14
|
-
|
13
|
+
my %cases;
|
15
14
|
subtest 'encode' => {
|
16
15
|
my @cases = |%cases.<encode>.<cases>;
|
17
16
|
|
@@ -29,3 +28,92 @@ subtest 'decode' => {
|
|
29
28
|
is decode( .<phrase> ), .<expected>, .<description>
|
30
29
|
for @cases;
|
31
30
|
};
|
31
|
+
|
32
|
+
done-testing;
|
33
|
+
|
34
|
+
INIT {
|
35
|
+
%cases := from-json 「
|
36
|
+
{
|
37
|
+
"#": [
|
38
|
+
"The tests are divided into two groups: ",
|
39
|
+
"* Encoding from English to atbash cipher",
|
40
|
+
"* Decoding from atbash cipher to all-lowercase-mashed-together English"
|
41
|
+
],
|
42
|
+
"encode": {
|
43
|
+
"description": ["Test encoding from English to atbash"],
|
44
|
+
"cases": [
|
45
|
+
{
|
46
|
+
"description": "encode yes",
|
47
|
+
"phrase": "yes",
|
48
|
+
"expected": "bvh"
|
49
|
+
},
|
50
|
+
{
|
51
|
+
"description": "encode no",
|
52
|
+
"phrase": "no",
|
53
|
+
"expected": "ml"
|
54
|
+
},
|
55
|
+
{
|
56
|
+
"description": "encode OMG",
|
57
|
+
"phrase": "OMG",
|
58
|
+
"expected": "lnt"
|
59
|
+
},
|
60
|
+
{
|
61
|
+
"description": "encode spaces",
|
62
|
+
"phrase": "O M G",
|
63
|
+
"expected": "lnt"
|
64
|
+
},
|
65
|
+
{
|
66
|
+
"description": "encode mindblowingly",
|
67
|
+
"phrase": "mindblowingly",
|
68
|
+
"expected": "nrmwy oldrm tob"
|
69
|
+
},
|
70
|
+
{
|
71
|
+
"description": "encode numbers",
|
72
|
+
"phrase": "Testing,1 2 3, testing.",
|
73
|
+
"expected": "gvhgr mt123 gvhgr mt"
|
74
|
+
},
|
75
|
+
{
|
76
|
+
"description": "encode deep thought",
|
77
|
+
"phrase": "Truth is fiction.",
|
78
|
+
"expected": "gifgs rhurx grlm"
|
79
|
+
},
|
80
|
+
{
|
81
|
+
"description": "encode all the letters",
|
82
|
+
"phrase": "The quick brown fox jumps over the lazy dog.",
|
83
|
+
"expected": "gsvjf rxpyi ldmul cqfnk hlevi gsvoz abwlt"
|
84
|
+
},
|
85
|
+
{
|
86
|
+
"description": "encode ignores non ascii",
|
87
|
+
"phrase": "non ascii éignored",
|
88
|
+
"expected": "mlmzh xrrrt mlivw"
|
89
|
+
}
|
90
|
+
]
|
91
|
+
},
|
92
|
+
"decode": {
|
93
|
+
"description": ["Test decoding from atbash to English"],
|
94
|
+
"cases": [
|
95
|
+
{
|
96
|
+
"description": "decode exercism",
|
97
|
+
"phrase": "vcvix rhn",
|
98
|
+
"expected": "exercism"
|
99
|
+
},
|
100
|
+
{
|
101
|
+
"description": "decode a sentence",
|
102
|
+
"phrase": "zmlyh gzxov rhlug vmzhg vkkrm thglm v",
|
103
|
+
"expected": "anobstacleisoftenasteppingstone"
|
104
|
+
},
|
105
|
+
{
|
106
|
+
"description": "decode numbers",
|
107
|
+
"phrase": "gvhgr mt123 gvhgr mt",
|
108
|
+
"expected": "testing123testing"
|
109
|
+
},
|
110
|
+
{
|
111
|
+
"description": "decode all the letters",
|
112
|
+
"phrase": "gsvjf rxpyi ldmul cqfnk hlevi gsvoz abwlt",
|
113
|
+
"expected": "thequickbrownfoxjumpsoverthelazydog"
|
114
|
+
}
|
115
|
+
]
|
116
|
+
}
|
117
|
+
}
|
118
|
+
」
|
119
|
+
}
|
@@ -2,15 +2,14 @@
|
|
2
2
|
use v6;
|
3
3
|
use Test;
|
4
4
|
use JSON::Tiny;
|
5
|
-
use lib
|
5
|
+
use lib $?FILE.IO.dirname;
|
6
6
|
|
7
7
|
plan 12;
|
8
8
|
my $module = %*ENV<EXERCISM> ?? 'Example' !! 'Phone';
|
9
9
|
use-ok $module;
|
10
10
|
require ::($module) <Phone>;
|
11
11
|
|
12
|
-
my %
|
13
|
-
|
12
|
+
my %cases;
|
14
13
|
subtest 'number, area-code and pretty methods', {
|
15
14
|
plan 3;
|
16
15
|
ok Phone.can('number'), 'can Phone.number';
|
@@ -18,7 +17,7 @@ subtest 'number, area-code and pretty methods', {
|
|
18
17
|
ok Phone.can('pretty'), 'can Phone.pretty';
|
19
18
|
} or fail 'Missing method(s).';
|
20
19
|
|
21
|
-
for @(%
|
20
|
+
for @(%cases<valid>) {
|
22
21
|
my $phone = Phone.new(number => .<input>);
|
23
22
|
my $msg = 'for ' ~ .<test>;
|
24
23
|
is $phone.number, .<number>, "number $msg";
|
@@ -29,5 +28,59 @@ for @(%tests<valid>) {
|
|
29
28
|
todo 'Optional Exception Tests' unless %*ENV<EXERCISM>; # Remove this line for invalid input tests
|
30
29
|
subtest 'Throw exceptions for invalid input', {
|
31
30
|
plan 5;
|
32
|
-
throws-like {Phone.new(number => .<input>)}, Exception, .<test> for @(%
|
31
|
+
throws-like {Phone.new(number => .<input>)}, Exception, .<test> for @(%cases<invalid>);
|
32
|
+
}
|
33
|
+
|
34
|
+
done-testing;
|
35
|
+
|
36
|
+
INIT {
|
37
|
+
%cases := from-json 「
|
38
|
+
{
|
39
|
+
"valid": [
|
40
|
+
{
|
41
|
+
"input": 1234567890,
|
42
|
+
"number": "1234567890",
|
43
|
+
"area-code": "123",
|
44
|
+
"pretty": "(123) 456-7890",
|
45
|
+
"test": "10 digit integer"
|
46
|
+
},
|
47
|
+
{
|
48
|
+
"input": "+1 (234) 555-6789",
|
49
|
+
"number": "2345556789",
|
50
|
+
"area-code": "234",
|
51
|
+
"pretty": "(234) 555-6789",
|
52
|
+
"test": "11 digit formatted number"
|
53
|
+
},
|
54
|
+
{
|
55
|
+
"input": "1.379.555.2468",
|
56
|
+
"number": "3795552468",
|
57
|
+
"area-code": "379",
|
58
|
+
"pretty": "(379) 555-2468",
|
59
|
+
"test": "11 digit number containing separators"
|
60
|
+
}
|
61
|
+
],
|
62
|
+
"invalid": [
|
63
|
+
{
|
64
|
+
"input": "",
|
65
|
+
"test": "empty input"
|
66
|
+
},
|
67
|
+
{
|
68
|
+
"input": "13579",
|
69
|
+
"test": "5 digit number"
|
70
|
+
},
|
71
|
+
{
|
72
|
+
"input": "123456789011",
|
73
|
+
"test": "12 digit number"
|
74
|
+
},
|
75
|
+
{
|
76
|
+
"input": "+2 (468) 555-1379",
|
77
|
+
"test": "11 digit number not beginning with 1"
|
78
|
+
},
|
79
|
+
{
|
80
|
+
"input": "phone number",
|
81
|
+
"test": "not a number"
|
82
|
+
}
|
83
|
+
]
|
84
|
+
}
|
85
|
+
」
|
33
86
|
}
|