codemirror-rails 3.12 → 3.13
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/codemirror-rails.gemspec +1 -1
- data/lib/codemirror/rails/version.rb +2 -2
- data/vendor/assets/javascripts/codemirror.js +168 -116
- data/vendor/assets/javascripts/codemirror/addons/comment/comment.js +144 -0
- data/vendor/assets/javascripts/codemirror/addons/display/placeholder.js +4 -4
- data/vendor/assets/javascripts/codemirror/addons/edit/closebrackets.js +2 -2
- data/vendor/assets/javascripts/codemirror/addons/fold/brace-fold.js +9 -3
- data/vendor/assets/javascripts/codemirror/addons/lint/lint.js +13 -13
- data/vendor/assets/javascripts/codemirror/addons/runmode/runmode.js +5 -1
- data/vendor/assets/javascripts/codemirror/addons/runmode/runmode.node.js +13 -1
- data/vendor/assets/javascripts/codemirror/addons/search/match-highlighter.js +4 -4
- data/vendor/assets/javascripts/codemirror/addons/search/search.js +1 -1
- data/vendor/assets/javascripts/codemirror/addons/search/searchcursor.js +15 -5
- data/vendor/assets/javascripts/codemirror/addons/selection/active-line.js +6 -6
- data/vendor/assets/javascripts/codemirror/addons/selection/mark-selection.js +89 -15
- data/vendor/assets/javascripts/codemirror/keymaps/vim.js +451 -187
- data/vendor/assets/javascripts/codemirror/modes/clike.js +6 -3
- data/vendor/assets/javascripts/codemirror/modes/clojure.js +3 -1
- data/vendor/assets/javascripts/codemirror/modes/cobol.js +240 -0
- data/vendor/assets/javascripts/codemirror/modes/coffeescript.js +2 -1
- data/vendor/assets/javascripts/codemirror/modes/commonlisp.js +5 -1
- data/vendor/assets/javascripts/codemirror/modes/css.js +63 -24
- data/vendor/assets/javascripts/codemirror/modes/erlang.js +3 -2
- data/vendor/assets/javascripts/codemirror/modes/gas.js +5 -1
- data/vendor/assets/javascripts/codemirror/modes/go.js +4 -1
- data/vendor/assets/javascripts/codemirror/modes/haml.js +153 -0
- data/vendor/assets/javascripts/codemirror/modes/haskell.js +5 -1
- data/vendor/assets/javascripts/codemirror/modes/javascript.js +5 -1
- data/vendor/assets/javascripts/codemirror/modes/less.js +0 -8
- data/vendor/assets/javascripts/codemirror/modes/lua.js +5 -1
- data/vendor/assets/javascripts/codemirror/modes/markdown.js +2 -2
- data/vendor/assets/javascripts/codemirror/modes/ocaml.js +4 -1
- data/vendor/assets/javascripts/codemirror/modes/php.js +3 -0
- data/vendor/assets/javascripts/codemirror/modes/python.js +2 -1
- data/vendor/assets/javascripts/codemirror/modes/ruby.js +2 -1
- data/vendor/assets/javascripts/codemirror/modes/rust.js +4 -1
- data/vendor/assets/javascripts/codemirror/modes/sass.js +8 -27
- data/vendor/assets/javascripts/codemirror/modes/scheme.js +3 -1
- data/vendor/assets/javascripts/codemirror/modes/smalltalk.js +6 -4
- data/vendor/assets/javascripts/codemirror/modes/sql.js +3 -4
- data/vendor/assets/javascripts/codemirror/modes/stex.js +1 -1
- data/vendor/assets/javascripts/codemirror/modes/xml.js +2 -0
- data/vendor/assets/javascripts/codemirror/modes/yaml.js +3 -1
- data/vendor/assets/stylesheets/codemirror.css +7 -4
- data/vendor/assets/stylesheets/codemirror/addons/lint/lint.css +3 -3
- data/vendor/assets/stylesheets/codemirror/themes/rubyblue.css +1 -1
- metadata +14 -6
- data/vendor/assets/javascripts/codemirror/modes/test.js +0 -64
@@ -158,7 +158,10 @@ CodeMirror.defineMode("go", function(config) {
|
|
158
158
|
else return ctx.indented + (closing ? 0 : indentUnit);
|
159
159
|
},
|
160
160
|
|
161
|
-
electricChars: "{}:"
|
161
|
+
electricChars: "{}:",
|
162
|
+
blockCommentStart: "/*",
|
163
|
+
blockCommentEnd: "*/",
|
164
|
+
lineComment: "//"
|
162
165
|
};
|
163
166
|
});
|
164
167
|
|
@@ -0,0 +1,153 @@
|
|
1
|
+
(function() {
|
2
|
+
"use strict";
|
3
|
+
|
4
|
+
// full haml mode. This handled embeded ruby and html fragments too
|
5
|
+
CodeMirror.defineMode("haml", function(config) {
|
6
|
+
var htmlMode = CodeMirror.getMode(config, {name: "htmlmixed"});
|
7
|
+
var rubyMode = CodeMirror.getMode(config, "ruby");
|
8
|
+
|
9
|
+
function rubyInQuote(endQuote) {
|
10
|
+
return function(stream, state) {
|
11
|
+
var ch = stream.peek();
|
12
|
+
if (ch == endQuote && state.rubyState.tokenize.length == 1) {
|
13
|
+
// step out of ruby context as it seems to complete processing all the braces
|
14
|
+
stream.next();
|
15
|
+
state.tokenize = html;
|
16
|
+
return "closeAttributeTag";
|
17
|
+
} else {
|
18
|
+
return ruby(stream, state);
|
19
|
+
}
|
20
|
+
};
|
21
|
+
}
|
22
|
+
|
23
|
+
function ruby(stream, state) {
|
24
|
+
if (stream.match("-#")) {
|
25
|
+
stream.skipToEnd();
|
26
|
+
return "comment";
|
27
|
+
}
|
28
|
+
return rubyMode.token(stream, state.rubyState);
|
29
|
+
}
|
30
|
+
|
31
|
+
function html(stream, state) {
|
32
|
+
var ch = stream.peek();
|
33
|
+
|
34
|
+
// handle haml declarations. All declarations that cant be handled here
|
35
|
+
// will be passed to html mode
|
36
|
+
if (state.previousToken.style == "comment" ) {
|
37
|
+
if (state.indented > state.previousToken.indented) {
|
38
|
+
stream.skipToEnd();
|
39
|
+
return "commentLine";
|
40
|
+
}
|
41
|
+
}
|
42
|
+
|
43
|
+
if (state.startOfLine) {
|
44
|
+
if (ch == "!" && stream.match("!!")) {
|
45
|
+
stream.skipToEnd();
|
46
|
+
return "tag";
|
47
|
+
} else if (stream.match(/^%[\w:#\.]+=/)) {
|
48
|
+
state.tokenize = ruby;
|
49
|
+
return "hamlTag";
|
50
|
+
} else if (stream.match(/^%[\w:]+/)) {
|
51
|
+
return "hamlTag";
|
52
|
+
} else if (ch == "/" ) {
|
53
|
+
stream.skipToEnd();
|
54
|
+
return "comment";
|
55
|
+
}
|
56
|
+
}
|
57
|
+
|
58
|
+
if (state.startOfLine || state.previousToken.style == "hamlTag") {
|
59
|
+
if ( ch == "#" || ch == ".") {
|
60
|
+
stream.match(/[\w-#\.]*/);
|
61
|
+
return "hamlAttribute";
|
62
|
+
}
|
63
|
+
}
|
64
|
+
|
65
|
+
// donot handle --> as valid ruby, make it HTML close comment instead
|
66
|
+
if (state.startOfLine && !stream.match("-->", false) && (ch == "=" || ch == "-" )) {
|
67
|
+
state.tokenize = ruby;
|
68
|
+
return null;
|
69
|
+
}
|
70
|
+
|
71
|
+
if (state.previousToken.style == "hamlTag" ||
|
72
|
+
state.previousToken.style == "closeAttributeTag" ||
|
73
|
+
state.previousToken.style == "hamlAttribute") {
|
74
|
+
if (ch == "(") {
|
75
|
+
state.tokenize = rubyInQuote(")");
|
76
|
+
return null;
|
77
|
+
} else if (ch == "{") {
|
78
|
+
state.tokenize = rubyInQuote("}");
|
79
|
+
return null;
|
80
|
+
}
|
81
|
+
}
|
82
|
+
|
83
|
+
return htmlMode.token(stream, state.htmlState);
|
84
|
+
}
|
85
|
+
|
86
|
+
return {
|
87
|
+
// default to html mode
|
88
|
+
startState: function() {
|
89
|
+
var htmlState = htmlMode.startState();
|
90
|
+
var rubyState = rubyMode.startState();
|
91
|
+
return {
|
92
|
+
htmlState: htmlState,
|
93
|
+
rubyState: rubyState,
|
94
|
+
indented: 0,
|
95
|
+
previousToken: { style: null, indented: 0},
|
96
|
+
tokenize: html
|
97
|
+
};
|
98
|
+
},
|
99
|
+
|
100
|
+
copyState: function(state) {
|
101
|
+
return {
|
102
|
+
htmlState : CodeMirror.copyState(htmlMode, state.htmlState),
|
103
|
+
rubyState: CodeMirror.copyState(rubyMode, state.rubyState),
|
104
|
+
indented: state.indented,
|
105
|
+
previousToken: state.previousToken,
|
106
|
+
tokenize: state.tokenize
|
107
|
+
};
|
108
|
+
},
|
109
|
+
|
110
|
+
token: function(stream, state) {
|
111
|
+
if (stream.sol()) {
|
112
|
+
state.indented = stream.indentation();
|
113
|
+
state.startOfLine = true;
|
114
|
+
}
|
115
|
+
if (stream.eatSpace()) return null;
|
116
|
+
var style = state.tokenize(stream, state);
|
117
|
+
state.startOfLine = false;
|
118
|
+
// dont record comment line as we only want to measure comment line with
|
119
|
+
// the opening comment block
|
120
|
+
if (style && style != "commentLine") {
|
121
|
+
state.previousToken = { style: style, indented: state.indented };
|
122
|
+
}
|
123
|
+
// if current state is ruby and the previous token is not `,` reset the
|
124
|
+
// tokenize to html
|
125
|
+
if (stream.eol() && state.tokenize == ruby) {
|
126
|
+
stream.backUp(1);
|
127
|
+
var ch = stream.peek();
|
128
|
+
stream.next();
|
129
|
+
if (ch && ch != ",") {
|
130
|
+
state.tokenize = html;
|
131
|
+
}
|
132
|
+
}
|
133
|
+
// reprocess some of the specific style tag when finish setting previousToken
|
134
|
+
if (style == "hamlTag") {
|
135
|
+
style = "tag";
|
136
|
+
} else if (style == "commentLine") {
|
137
|
+
style = "comment";
|
138
|
+
} else if (style == "hamlAttribute") {
|
139
|
+
style = "attribute";
|
140
|
+
} else if (style == "closeAttributeTag") {
|
141
|
+
style = null;
|
142
|
+
}
|
143
|
+
return style;
|
144
|
+
},
|
145
|
+
|
146
|
+
indent: function(state) {
|
147
|
+
return state.indented;
|
148
|
+
}
|
149
|
+
};
|
150
|
+
}, "htmlmixed", "ruby");
|
151
|
+
|
152
|
+
CodeMirror.defineMIME("text/x-haml", "haml");
|
153
|
+
})();
|
@@ -234,7 +234,11 @@ CodeMirror.defineMode("haskell", function() {
|
|
234
234
|
var t = state.f(stream, function(s) { state.f = s; });
|
235
235
|
var w = stream.current();
|
236
236
|
return (w in wellKnownWords) ? wellKnownWords[w] : t;
|
237
|
-
}
|
237
|
+
},
|
238
|
+
|
239
|
+
blockCommentStart: "{-",
|
240
|
+
blockCommentEnd: "-}",
|
241
|
+
lineComment: "--"
|
238
242
|
};
|
239
243
|
|
240
244
|
});
|
@@ -291,7 +291,7 @@ CodeMirror.defineMode("javascript", function(config, parserConfig) {
|
|
291
291
|
}
|
292
292
|
|
293
293
|
function maybeoperatorComma(type, value) {
|
294
|
-
if (type == ",") return
|
294
|
+
if (type == ",") return pass();
|
295
295
|
return maybeoperatorNoComma(type, value, maybeoperatorComma);
|
296
296
|
}
|
297
297
|
function maybeoperatorNoComma(type, value, me) {
|
@@ -453,6 +453,9 @@ CodeMirror.defineMode("javascript", function(config, parserConfig) {
|
|
453
453
|
},
|
454
454
|
|
455
455
|
electricChars: ":{}",
|
456
|
+
blockCommentStart: jsonMode ? null : "/*",
|
457
|
+
blockCommentEnd: jsonMode ? null : "*/",
|
458
|
+
lineComment: jsonMode ? null : "//",
|
456
459
|
|
457
460
|
jsonMode: jsonMode
|
458
461
|
};
|
@@ -463,5 +466,6 @@ CodeMirror.defineMIME("text/ecmascript", "javascript");
|
|
463
466
|
CodeMirror.defineMIME("application/javascript", "javascript");
|
464
467
|
CodeMirror.defineMIME("application/ecmascript", "javascript");
|
465
468
|
CodeMirror.defineMIME("application/json", {name: "javascript", json: true});
|
469
|
+
CodeMirror.defineMIME("application/x-json", {name: "javascript", json: true});
|
466
470
|
CodeMirror.defineMIME("text/typescript", { name: "javascript", typescript: true });
|
467
471
|
CodeMirror.defineMIME("application/typescript", { name: "javascript", typescript: true });
|
@@ -7,12 +7,6 @@
|
|
7
7
|
CodeMirror.defineMode("less", function(config) {
|
8
8
|
var indentUnit = config.indentUnit, type;
|
9
9
|
function ret(style, tp) {type = tp; return style;}
|
10
|
-
//html tags
|
11
|
-
var tags = "a abbr acronym address applet area article aside audio b base basefont bdi bdo big blockquote body br button canvas caption cite code col colgroup command datalist dd del details dfn dir div dl dt em embed fieldset figcaption figure font footer form frame frameset h1 h2 h3 h4 h5 h6 head header hgroup hr html i iframe img input ins keygen kbd label legend li link map mark menu meta meter nav noframes noscript object ol optgroup option output p param pre progress q rp rt ruby s samp script section select small source span strike strong style sub summary sup table tbody td textarea tfoot th thead time title tr track tt u ul var video wbr".split(' ');
|
12
|
-
|
13
|
-
function inTagsArray(val){
|
14
|
-
for(var i=0; i<tags.length; i++)if(val === tags[i])return true;
|
15
|
-
}
|
16
10
|
|
17
11
|
var selectors = /(^\:root$|^\:nth\-child$|^\:nth\-last\-child$|^\:nth\-of\-type$|^\:nth\-last\-of\-type$|^\:first\-child$|^\:last\-child$|^\:first\-of\-type$|^\:last\-of\-type$|^\:only\-child$|^\:only\-of\-type$|^\:empty$|^\:link|^\:visited$|^\:active$|^\:hover$|^\:focus$|^\:target$|^\:lang$|^\:enabled^\:disabled$|^\:checked$|^\:first\-line$|^\:first\-letter$|^\:before$|^\:after$|^\:not$|^\:required$|^\:invalid$)/;
|
18
12
|
|
@@ -135,8 +129,6 @@ CodeMirror.defineMode("less", function(config) {
|
|
135
129
|
//stream.backUp(stream.current().length-1);
|
136
130
|
//return ret(null, ch); //console.log( stream.current() );
|
137
131
|
return ret("number", "unit");
|
138
|
-
}else if( inTagsArray(stream.current().toLowerCase()) ){ // match html tags
|
139
|
-
return ret("tag", "tag");
|
140
132
|
}else if( /\/|[\s\)]/.test(stream.peek() || stream.eol() || (stream.eatSpace() && stream.peek() == "/")) && stream.current().indexOf(".") !== -1){
|
141
133
|
if(stream.current().substring(stream.current().length-1,stream.current().length) == "{"){
|
142
134
|
stream.backUp(1);
|
@@ -133,7 +133,11 @@ CodeMirror.defineMode("lua", function(config, parserConfig) {
|
|
133
133
|
indent: function(state, textAfter) {
|
134
134
|
var closing = dedentPartial.test(textAfter);
|
135
135
|
return state.basecol + indentUnit * (state.indentDepth - (closing ? 1 : 0));
|
136
|
-
}
|
136
|
+
},
|
137
|
+
|
138
|
+
lineComment: "--",
|
139
|
+
blockCommentStart: "--[[",
|
140
|
+
blockCommentEnd: "]]"
|
137
141
|
};
|
138
142
|
});
|
139
143
|
|
@@ -1,7 +1,7 @@
|
|
1
1
|
CodeMirror.defineMode("markdown", function(cmCfg, modeCfg) {
|
2
2
|
|
3
|
-
var htmlFound = CodeMirror.
|
4
|
-
var htmlMode = CodeMirror.getMode(cmCfg, htmlFound ? "
|
3
|
+
var htmlFound = CodeMirror.modes.hasOwnProperty("xml");
|
4
|
+
var htmlMode = CodeMirror.getMode(cmCfg, htmlFound ? {name: "xml", htmlMode: true} : "text/plain");
|
5
5
|
var aliases = {
|
6
6
|
html: "htmlmixed",
|
7
7
|
js: "javascript",
|
@@ -106,7 +106,10 @@ CodeMirror.defineMode('ocaml', function() {
|
|
106
106
|
token: function(stream, state) {
|
107
107
|
if (stream.eatSpace()) return null;
|
108
108
|
return state.tokenize(stream, state);
|
109
|
-
}
|
109
|
+
},
|
110
|
+
|
111
|
+
blockCommentStart: "(*",
|
112
|
+
blockCommentEnd: "*)"
|
110
113
|
};
|
111
114
|
});
|
112
115
|
|
@@ -186,8 +186,9 @@ CodeMirror.defineMode("ruby", function(config) {
|
|
186
186
|
return ct.indented + (closing ? 0 : config.indentUnit) +
|
187
187
|
(state.continuedLine ? config.indentUnit : 0);
|
188
188
|
},
|
189
|
-
electricChars: "}de" // enD and rescuE
|
190
189
|
|
190
|
+
electricChars: "}de", // enD and rescuE
|
191
|
+
lineComment: "#"
|
191
192
|
};
|
192
193
|
});
|
193
194
|
|
@@ -425,7 +425,10 @@ CodeMirror.defineMode("rust", function() {
|
|
425
425
|
return lexical.indented + (closing ? 0 : (lexical.info == "alt" ? altIndentUnit : indentUnit));
|
426
426
|
},
|
427
427
|
|
428
|
-
electricChars: "{}"
|
428
|
+
electricChars: "{}",
|
429
|
+
blockCommentStart: "/*",
|
430
|
+
blockCommentEnd: "*/",
|
431
|
+
lineComment: "//"
|
429
432
|
};
|
430
433
|
});
|
431
434
|
|
@@ -3,24 +3,13 @@ CodeMirror.defineMode("sass", function(config) {
|
|
3
3
|
return new RegExp("^" + words.join("|"));
|
4
4
|
};
|
5
5
|
|
6
|
-
var tags = ["&", "a","abbr","acronym","address","applet","area","article","aside","audio","b","base","basefont","bdi","bdo","big","blockquote","body","br","button","canvas","caption","cite","code","col","colgroup","command","datalist","dd","del","details","dfn","dir","div","dl","dt","em","embed","fieldset","figcaption","figure","font","footer","form","frame","frameset","h1","h2","h3","h4","h5","h6","head","header","hgroup","hr","html","i","iframe","img","input","ins","keygen","kbd","label","legend","li","link","map","mark","menu","meta","meter","nav","noframes","noscript","object","ol","optgroup","option","output","p","param","pre","progress","q","rp","rt","ruby","s","samp","script","section","select","small","source","span","strike","strong","style","sub","summary","sup","table","tbody","td","textarea","tfoot","th","thead","time","title","tr","track","tt","u","ul","var","video","wbr"];
|
7
6
|
var keywords = ["true", "false", "null", "auto"];
|
8
7
|
var keywordsRegexp = new RegExp("^" + keywords.join("|"));
|
9
8
|
|
10
9
|
var operators = ["\\(", "\\)", "=", ">", "<", "==", ">=", "<=", "\\+", "-", "\\!=", "/", "\\*", "%", "and", "or", "not"];
|
11
10
|
var opRegexp = tokenRegexp(operators);
|
12
11
|
|
13
|
-
|
14
|
-
for(var i=0; i<tags.length; i++){
|
15
|
-
if(val === tags[i]){
|
16
|
-
return true;
|
17
|
-
}
|
18
|
-
}
|
19
|
-
}
|
20
|
-
|
21
|
-
|
22
|
-
var pseudoElements = [':first-line', ':hover', ':first-letter', ':active', ':visited', ':before', ':after', ':link', ':focus', ':first-child', ':lang'];
|
23
|
-
var pseudoElementsRegexp = new RegExp("^(" + pseudoElements.join("\\b|") + ")");
|
12
|
+
var pseudoElementsRegexp = /^::?[\w\-]+/;
|
24
13
|
|
25
14
|
var urlTokens = function(stream, state){
|
26
15
|
var ch = stream.peek();
|
@@ -256,25 +245,17 @@ CodeMirror.defineMode("sass", function(config) {
|
|
256
245
|
}
|
257
246
|
|
258
247
|
// Pseudo element selectors
|
259
|
-
if (stream.match(pseudoElementsRegexp)){
|
248
|
+
if (ch == ':' && stream.match(pseudoElementsRegexp)){
|
260
249
|
return "keyword";
|
261
250
|
}
|
262
251
|
|
263
252
|
// atoms
|
264
253
|
if (stream.eatWhile(/[\w-&]/)){
|
265
|
-
|
266
|
-
var current = stream.current();
|
267
254
|
// matches a property definition
|
268
|
-
if (stream.peek() === ":")
|
269
|
-
|
270
|
-
|
271
|
-
|
272
|
-
}else{
|
273
|
-
stream.next();
|
274
|
-
return "property";
|
275
|
-
}
|
276
|
-
}
|
277
|
-
return "atom";
|
255
|
+
if (stream.peek() === ":" && !stream.match(pseudoElementsRegexp, false))
|
256
|
+
return "property";
|
257
|
+
else
|
258
|
+
return "atom";
|
278
259
|
}
|
279
260
|
|
280
261
|
if (stream.match(opRegexp)){
|
@@ -298,7 +279,7 @@ CodeMirror.defineMode("sass", function(config) {
|
|
298
279
|
dedent(state);
|
299
280
|
}
|
300
281
|
|
301
|
-
if (style === "atom"
|
282
|
+
if (style === "atom"){
|
302
283
|
indent(state);
|
303
284
|
}
|
304
285
|
|
@@ -312,7 +293,7 @@ CodeMirror.defineMode("sass", function(config) {
|
|
312
293
|
var scope = state.scopes[i];
|
313
294
|
|
314
295
|
if (scope.offset <= withCurrentIndent){
|
315
|
-
|
296
|
+
newScopes.push(scope);
|
316
297
|
}
|
317
298
|
}
|
318
299
|
|
@@ -1,6 +1,6 @@
|
|
1
1
|
CodeMirror.defineMode('smalltalk', function(config) {
|
2
2
|
|
3
|
-
var specialChars = /[
|
3
|
+
var specialChars = /[+\-\/\\*~<>=@%|&?!.,:;^]/;
|
4
4
|
var keywords = /true|false|nil|self|super|thisContext/;
|
5
5
|
|
6
6
|
var Context = function(tokenizer, parent) {
|
@@ -36,11 +36,14 @@ CodeMirror.defineMode('smalltalk', function(config) {
|
|
36
36
|
token = nextString(stream, new Context(nextString, context));
|
37
37
|
|
38
38
|
} else if (aChar === '#') {
|
39
|
-
stream.eatWhile(/[^
|
39
|
+
stream.eatWhile(/[^ .\[\]()]/);
|
40
40
|
token.name = 'string-2';
|
41
41
|
|
42
42
|
} else if (aChar === '$') {
|
43
|
-
stream.
|
43
|
+
if (stream.next() === '<') {
|
44
|
+
stream.eatWhile(/[^ >]/);
|
45
|
+
stream.next();
|
46
|
+
}
|
44
47
|
token.name = 'string-2';
|
45
48
|
|
46
49
|
} else if (aChar === '|' && state.expectVariable) {
|
@@ -118,7 +121,6 @@ CodeMirror.defineMode('smalltalk', function(config) {
|
|
118
121
|
state.context = token.context;
|
119
122
|
state.expectVariable = token.eos;
|
120
123
|
|
121
|
-
state.lastToken = token;
|
122
124
|
return token.name;
|
123
125
|
},
|
124
126
|
|