Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
malwaredllc
GitHub Repository: malwaredllc/byob
Path: blob/master/web-gui/buildyourownbotnet/assets/js/codemirror/mode/javascript/javascript.js
1293 views
1
// TODO actually recognize syntax of TypeScript constructs
2
3
CodeMirror.defineMode("javascript", function(config, parserConfig) {
4
var indentUnit = config.indentUnit;
5
var statementIndent = parserConfig.statementIndent;
6
var jsonMode = parserConfig.json;
7
var isTS = parserConfig.typescript;
8
9
// Tokenizer
10
11
var keywords = function(){
12
function kw(type) {return {type: type, style: "keyword"};}
13
var A = kw("keyword a"), B = kw("keyword b"), C = kw("keyword c");
14
var operator = kw("operator"), atom = {type: "atom", style: "atom"};
15
16
var jsKeywords = {
17
"if": kw("if"), "while": A, "with": A, "else": B, "do": B, "try": B, "finally": B,
18
"return": C, "break": C, "continue": C, "new": C, "delete": C, "throw": C, "debugger": C,
19
"var": kw("var"), "const": kw("var"), "let": kw("var"),
20
"function": kw("function"), "catch": kw("catch"),
21
"for": kw("for"), "switch": kw("switch"), "case": kw("case"), "default": kw("default"),
22
"in": operator, "typeof": operator, "instanceof": operator,
23
"true": atom, "false": atom, "null": atom, "undefined": atom, "NaN": atom, "Infinity": atom,
24
"this": kw("this"), "module": kw("module"), "class": kw("class"), "super": kw("atom"),
25
"yield": C, "export": kw("export"), "import": kw("import"), "extends": C
26
};
27
28
// Extend the 'normal' keywords with the TypeScript language extensions
29
if (isTS) {
30
var type = {type: "variable", style: "variable-3"};
31
var tsKeywords = {
32
// object-like things
33
"interface": kw("interface"),
34
"extends": kw("extends"),
35
"constructor": kw("constructor"),
36
37
// scope modifiers
38
"public": kw("public"),
39
"private": kw("private"),
40
"protected": kw("protected"),
41
"static": kw("static"),
42
43
// types
44
"string": type, "number": type, "bool": type, "any": type
45
};
46
47
for (var attr in tsKeywords) {
48
jsKeywords[attr] = tsKeywords[attr];
49
}
50
}
51
52
return jsKeywords;
53
}();
54
55
var isOperatorChar = /[+\-*&%=<>!?|~^]/;
56
57
function readRegexp(stream) {
58
var escaped = false, next, inSet = false;
59
while ((next = stream.next()) != null) {
60
if (!escaped) {
61
if (next == "/" && !inSet) return;
62
if (next == "[") inSet = true;
63
else if (inSet && next == "]") inSet = false;
64
}
65
escaped = !escaped && next == "\\";
66
}
67
}
68
69
// Used as scratch variables to communicate multiple values without
70
// consing up tons of objects.
71
var type, content;
72
function ret(tp, style, cont) {
73
type = tp; content = cont;
74
return style;
75
}
76
function tokenBase(stream, state) {
77
var ch = stream.next();
78
if (ch == '"' || ch == "'") {
79
state.tokenize = tokenString(ch);
80
return state.tokenize(stream, state);
81
} else if (ch == "." && stream.match(/^\d+(?:[eE][+\-]?\d+)?/)) {
82
return ret("number", "number");
83
} else if (ch == "." && stream.match("..")) {
84
return ret("spread", "meta");
85
} else if (/[\[\]{}\(\),;\:\.]/.test(ch)) {
86
return ret(ch);
87
} else if (ch == "=" && stream.eat(">")) {
88
return ret("=>", "operator");
89
} else if (ch == "0" && stream.eat(/x/i)) {
90
stream.eatWhile(/[\da-f]/i);
91
return ret("number", "number");
92
} else if (/\d/.test(ch)) {
93
stream.match(/^\d*(?:\.\d*)?(?:[eE][+\-]?\d+)?/);
94
return ret("number", "number");
95
} else if (ch == "/") {
96
if (stream.eat("*")) {
97
state.tokenize = tokenComment;
98
return tokenComment(stream, state);
99
} else if (stream.eat("/")) {
100
stream.skipToEnd();
101
return ret("comment", "comment");
102
} else if (state.lastType == "operator" || state.lastType == "keyword c" ||
103
state.lastType == "sof" || /^[\[{}\(,;:]$/.test(state.lastType)) {
104
readRegexp(stream);
105
stream.eatWhile(/[gimy]/); // 'y' is "sticky" option in Mozilla
106
return ret("regexp", "string-2");
107
} else {
108
stream.eatWhile(isOperatorChar);
109
return ret("operator", "operator", stream.current());
110
}
111
} else if (ch == "`") {
112
state.tokenize = tokenQuasi;
113
return tokenQuasi(stream, state);
114
} else if (ch == "#") {
115
stream.skipToEnd();
116
return ret("error", "error");
117
} else if (isOperatorChar.test(ch)) {
118
stream.eatWhile(isOperatorChar);
119
return ret("operator", "operator", stream.current());
120
} else {
121
stream.eatWhile(/[\w\$_]/);
122
var word = stream.current(), known = keywords.propertyIsEnumerable(word) && keywords[word];
123
return (known && state.lastType != ".") ? ret(known.type, known.style, word) :
124
ret("variable", "variable", word);
125
}
126
}
127
128
function tokenString(quote) {
129
return function(stream, state) {
130
var escaped = false, next;
131
while ((next = stream.next()) != null) {
132
if (next == quote && !escaped) break;
133
escaped = !escaped && next == "\\";
134
}
135
if (!escaped) state.tokenize = tokenBase;
136
return ret("string", "string");
137
};
138
}
139
140
function tokenComment(stream, state) {
141
var maybeEnd = false, ch;
142
while (ch = stream.next()) {
143
if (ch == "/" && maybeEnd) {
144
state.tokenize = tokenBase;
145
break;
146
}
147
maybeEnd = (ch == "*");
148
}
149
return ret("comment", "comment");
150
}
151
152
function tokenQuasi(stream, state) {
153
var escaped = false, next;
154
while ((next = stream.next()) != null) {
155
if (!escaped && (next == "`" || next == "$" && stream.eat("{"))) {
156
state.tokenize = tokenBase;
157
break;
158
}
159
escaped = !escaped && next == "\\";
160
}
161
return ret("quasi", "string-2", stream.current());
162
}
163
164
var brackets = "([{}])";
165
// This is a crude lookahead trick to try and notice that we're
166
// parsing the argument patterns for a fat-arrow function before we
167
// actually hit the arrow token. It only works if the arrow is on
168
// the same line as the arguments and there's no strange noise
169
// (comments) in between. Fallback is to only notice when we hit the
170
// arrow, and not declare the arguments as locals for the arrow
171
// body.
172
function findFatArrow(stream, state) {
173
if (state.fatArrowAt) state.fatArrowAt = null;
174
var arrow = stream.string.indexOf("=>", stream.start);
175
if (arrow < 0) return;
176
177
var depth = 0, sawSomething = false;
178
for (var pos = arrow - 1; pos >= 0; --pos) {
179
var ch = stream.string.charAt(pos);
180
var bracket = brackets.indexOf(ch);
181
if (bracket >= 0 && bracket < 3) {
182
if (!depth) { ++pos; break; }
183
if (--depth == 0) break;
184
} else if (bracket >= 3 && bracket < 6) {
185
++depth;
186
} else if (/[$\w]/.test(ch)) {
187
sawSomething = true;
188
} else if (sawSomething && !depth) {
189
++pos;
190
break;
191
}
192
}
193
if (sawSomething && !depth) state.fatArrowAt = pos;
194
}
195
196
// Parser
197
198
var atomicTypes = {"atom": true, "number": true, "variable": true, "string": true, "regexp": true, "this": true};
199
200
function JSLexical(indented, column, type, align, prev, info) {
201
this.indented = indented;
202
this.column = column;
203
this.type = type;
204
this.prev = prev;
205
this.info = info;
206
if (align != null) this.align = align;
207
}
208
209
function inScope(state, varname) {
210
for (var v = state.localVars; v; v = v.next)
211
if (v.name == varname) return true;
212
for (var cx = state.context; cx; cx = cx.prev) {
213
for (var v = cx.vars; v; v = v.next)
214
if (v.name == varname) return true;
215
}
216
}
217
218
function parseJS(state, style, type, content, stream) {
219
var cc = state.cc;
220
// Communicate our context to the combinators.
221
// (Less wasteful than consing up a hundred closures on every call.)
222
cx.state = state; cx.stream = stream; cx.marked = null, cx.cc = cc;
223
224
if (!state.lexical.hasOwnProperty("align"))
225
state.lexical.align = true;
226
227
while(true) {
228
var combinator = cc.length ? cc.pop() : jsonMode ? expression : statement;
229
if (combinator(type, content)) {
230
while(cc.length && cc[cc.length - 1].lex)
231
cc.pop()();
232
if (cx.marked) return cx.marked;
233
if (type == "variable" && inScope(state, content)) return "variable-2";
234
return style;
235
}
236
}
237
}
238
239
// Combinator utils
240
241
var cx = {state: null, column: null, marked: null, cc: null};
242
function pass() {
243
for (var i = arguments.length - 1; i >= 0; i--) cx.cc.push(arguments[i]);
244
}
245
function cont() {
246
pass.apply(null, arguments);
247
return true;
248
}
249
function register(varname) {
250
function inList(list) {
251
for (var v = list; v; v = v.next)
252
if (v.name == varname) return true;
253
return false;
254
}
255
var state = cx.state;
256
if (state.context) {
257
cx.marked = "def";
258
if (inList(state.localVars)) return;
259
state.localVars = {name: varname, next: state.localVars};
260
} else {
261
if (inList(state.globalVars)) return;
262
if (parserConfig.globalVars)
263
state.globalVars = {name: varname, next: state.globalVars};
264
}
265
}
266
267
// Combinators
268
269
var defaultVars = {name: "this", next: {name: "arguments"}};
270
function pushcontext() {
271
cx.state.context = {prev: cx.state.context, vars: cx.state.localVars};
272
cx.state.localVars = defaultVars;
273
}
274
function popcontext() {
275
cx.state.localVars = cx.state.context.vars;
276
cx.state.context = cx.state.context.prev;
277
}
278
function pushlex(type, info) {
279
var result = function() {
280
var state = cx.state, indent = state.indented;
281
if (state.lexical.type == "stat") indent = state.lexical.indented;
282
state.lexical = new JSLexical(indent, cx.stream.column(), type, null, state.lexical, info);
283
};
284
result.lex = true;
285
return result;
286
}
287
function poplex() {
288
var state = cx.state;
289
if (state.lexical.prev) {
290
if (state.lexical.type == ")")
291
state.indented = state.lexical.indented;
292
state.lexical = state.lexical.prev;
293
}
294
}
295
poplex.lex = true;
296
297
function expect(wanted) {
298
return function(type) {
299
if (type == wanted) return cont();
300
else if (wanted == ";") return pass();
301
else return cont(arguments.callee);
302
};
303
}
304
305
function statement(type, value) {
306
if (type == "var") return cont(pushlex("vardef", value.length), vardef, expect(";"), poplex);
307
if (type == "keyword a") return cont(pushlex("form"), expression, statement, poplex);
308
if (type == "keyword b") return cont(pushlex("form"), statement, poplex);
309
if (type == "{") return cont(pushlex("}"), block, poplex);
310
if (type == ";") return cont();
311
if (type == "if") return cont(pushlex("form"), expression, statement, poplex, maybeelse);
312
if (type == "function") return cont(functiondef);
313
if (type == "for") return cont(pushlex("form"), forspec, statement, poplex);
314
if (type == "variable") return cont(pushlex("stat"), maybelabel);
315
if (type == "switch") return cont(pushlex("form"), expression, pushlex("}", "switch"), expect("{"),
316
block, poplex, poplex);
317
if (type == "case") return cont(expression, expect(":"));
318
if (type == "default") return cont(expect(":"));
319
if (type == "catch") return cont(pushlex("form"), pushcontext, expect("("), funarg, expect(")"),
320
statement, poplex, popcontext);
321
if (type == "module") return cont(pushlex("form"), pushcontext, afterModule, popcontext, poplex);
322
if (type == "class") return cont(pushlex("form"), className, objlit, poplex);
323
if (type == "export") return cont(pushlex("form"), afterExport, poplex);
324
if (type == "import") return cont(pushlex("form"), afterImport, poplex);
325
return pass(pushlex("stat"), expression, expect(";"), poplex);
326
}
327
function expression(type) {
328
return expressionInner(type, false);
329
}
330
function expressionNoComma(type) {
331
return expressionInner(type, true);
332
}
333
function expressionInner(type, noComma) {
334
if (cx.state.fatArrowAt == cx.stream.start) {
335
var body = noComma ? arrowBodyNoComma : arrowBody;
336
if (type == "(") return cont(pushcontext, pushlex(")"), commasep(pattern, ")"), poplex, expect("=>"), body, popcontext);
337
else if (type == "variable") return pass(pushcontext, pattern, expect("=>"), body, popcontext);
338
}
339
340
var maybeop = noComma ? maybeoperatorNoComma : maybeoperatorComma;
341
if (atomicTypes.hasOwnProperty(type)) return cont(maybeop);
342
if (type == "function") return cont(functiondef);
343
if (type == "keyword c") return cont(noComma ? maybeexpressionNoComma : maybeexpression);
344
if (type == "(") return cont(pushlex(")"), maybeexpression, comprehension, expect(")"), poplex, maybeop);
345
if (type == "operator" || type == "spread") return cont(noComma ? expressionNoComma : expression);
346
if (type == "[") return cont(pushlex("]"), arrayLiteral, poplex, maybeop);
347
if (type == "{") return contCommasep(objprop, "}", null, maybeop);
348
return cont();
349
}
350
function maybeexpression(type) {
351
if (type.match(/[;\}\)\],]/)) return pass();
352
return pass(expression);
353
}
354
function maybeexpressionNoComma(type) {
355
if (type.match(/[;\}\)\],]/)) return pass();
356
return pass(expressionNoComma);
357
}
358
359
function maybeoperatorComma(type, value) {
360
if (type == ",") return cont(expression);
361
return maybeoperatorNoComma(type, value, false);
362
}
363
function maybeoperatorNoComma(type, value, noComma) {
364
var me = noComma == false ? maybeoperatorComma : maybeoperatorNoComma;
365
var expr = noComma == false ? expression : expressionNoComma;
366
if (value == "=>") return cont(pushcontext, noComma ? arrowBodyNoComma : arrowBody, popcontext);
367
if (type == "operator") {
368
if (/\+\+|--/.test(value)) return cont(me);
369
if (value == "?") return cont(expression, expect(":"), expr);
370
return cont(expr);
371
}
372
if (type == "quasi") { cx.cc.push(me); return quasi(value); }
373
if (type == ";") return;
374
if (type == "(") return contCommasep(expressionNoComma, ")", "call", me);
375
if (type == ".") return cont(property, me);
376
if (type == "[") return cont(pushlex("]"), maybeexpression, expect("]"), poplex, me);
377
}
378
function quasi(value) {
379
if (value.slice(value.length - 2) != "${") return cont();
380
return cont(expression, continueQuasi);
381
}
382
function continueQuasi(type) {
383
if (type == "}") {
384
cx.marked = "string-2";
385
cx.state.tokenize = tokenQuasi;
386
return cont();
387
}
388
}
389
function arrowBody(type) {
390
findFatArrow(cx.stream, cx.state);
391
if (type == "{") return pass(statement);
392
return pass(expression);
393
}
394
function arrowBodyNoComma(type) {
395
findFatArrow(cx.stream, cx.state);
396
if (type == "{") return pass(statement);
397
return pass(expressionNoComma);
398
}
399
function maybelabel(type) {
400
if (type == ":") return cont(poplex, statement);
401
return pass(maybeoperatorComma, expect(";"), poplex);
402
}
403
function property(type) {
404
if (type == "variable") {cx.marked = "property"; return cont();}
405
}
406
function objprop(type, value) {
407
if (type == "variable") {
408
cx.marked = "property";
409
if (value == "get" || value == "set") return cont(getterSetter);
410
} else if (type == "number" || type == "string") {
411
cx.marked = type + " property";
412
} else if (type == "[") {
413
return cont(expression, expect("]"), afterprop);
414
}
415
if (atomicTypes.hasOwnProperty(type)) return cont(afterprop);
416
}
417
function getterSetter(type) {
418
if (type != "variable") return pass(afterprop);
419
cx.marked = "property";
420
return cont(functiondef);
421
}
422
function afterprop(type) {
423
if (type == ":") return cont(expressionNoComma);
424
if (type == "(") return pass(functiondef);
425
}
426
function commasep(what, end) {
427
function proceed(type) {
428
if (type == ",") {
429
var lex = cx.state.lexical;
430
if (lex.info == "call") lex.pos = (lex.pos || 0) + 1;
431
return cont(what, proceed);
432
}
433
if (type == end) return cont();
434
return cont(expect(end));
435
}
436
return function(type) {
437
if (type == end) return cont();
438
return pass(what, proceed);
439
};
440
}
441
function contCommasep(what, end, info) {
442
for (var i = 3; i < arguments.length; i++)
443
cx.cc.push(arguments[i]);
444
return cont(pushlex(end, info), commasep(what, end), poplex);
445
}
446
function block(type) {
447
if (type == "}") return cont();
448
return pass(statement, block);
449
}
450
function maybetype(type) {
451
if (isTS && type == ":") return cont(typedef);
452
}
453
function typedef(type) {
454
if (type == "variable"){cx.marked = "variable-3"; return cont();}
455
}
456
function vardef() {
457
return pass(pattern, maybetype, maybeAssign, vardefCont);
458
}
459
function pattern(type, value) {
460
if (type == "variable") { register(value); return cont(); }
461
if (type == "[") return contCommasep(pattern, "]");
462
if (type == "{") return contCommasep(proppattern, "}");
463
}
464
function proppattern(type, value) {
465
if (type == "variable" && !cx.stream.match(/^\s*:/, false)) {
466
register(value);
467
return cont(maybeAssign);
468
}
469
if (type == "variable") cx.marked = "property";
470
return cont(expect(":"), pattern, maybeAssign);
471
}
472
function maybeAssign(_type, value) {
473
if (value == "=") return cont(expressionNoComma);
474
}
475
function vardefCont(type) {
476
if (type == ",") return cont(vardef);
477
}
478
function maybeelse(type, value) {
479
if (type == "keyword b" && value == "else") return cont(pushlex("form"), statement, poplex);
480
}
481
function forspec(type) {
482
if (type == "(") return cont(pushlex(")"), forspec1, expect(")"), poplex);
483
}
484
function forspec1(type) {
485
if (type == "var") return cont(vardef, expect(";"), forspec2);
486
if (type == ";") return cont(forspec2);
487
if (type == "variable") return cont(formaybeinof);
488
return pass(expression, expect(";"), forspec2);
489
}
490
function formaybeinof(_type, value) {
491
if (value == "in" || value == "of") { cx.marked = "keyword"; return cont(expression); }
492
return cont(maybeoperatorComma, forspec2);
493
}
494
function forspec2(type, value) {
495
if (type == ";") return cont(forspec3);
496
if (value == "in" || value == "of") { cx.marked = "keyword"; return cont(expression); }
497
return pass(expression, expect(";"), forspec3);
498
}
499
function forspec3(type) {
500
if (type != ")") cont(expression);
501
}
502
function functiondef(type, value) {
503
if (value == "*") {cx.marked = "keyword"; return cont(functiondef);}
504
if (type == "variable") {register(value); return cont(functiondef);}
505
if (type == "(") return cont(pushcontext, pushlex(")"), commasep(funarg, ")"), poplex, statement, popcontext);
506
}
507
function funarg(type) {
508
if (type == "spread") return cont(funarg);
509
return pass(pattern, maybetype);
510
}
511
function className(type, value) {
512
if (type == "variable") {register(value); return cont(classNameAfter);}
513
}
514
function classNameAfter(_type, value) {
515
if (value == "extends") return cont(expression);
516
}
517
function objlit(type) {
518
if (type == "{") return contCommasep(objprop, "}");
519
}
520
function afterModule(type, value) {
521
if (type == "string") return cont(statement);
522
if (type == "variable") { register(value); return cont(maybeFrom); }
523
}
524
function afterExport(_type, value) {
525
if (value == "*") { cx.marked = "keyword"; return cont(maybeFrom, expect(";")); }
526
if (value == "default") { cx.marked = "keyword"; return cont(expression, expect(";")); }
527
return pass(statement);
528
}
529
function afterImport(type) {
530
if (type == "string") return cont();
531
return pass(importSpec, maybeFrom);
532
}
533
function importSpec(type, value) {
534
if (type == "{") return contCommasep(importSpec, "}");
535
if (type == "variable") register(value);
536
return cont();
537
}
538
function maybeFrom(_type, value) {
539
if (value == "from") { cx.marked = "keyword"; return cont(expression); }
540
}
541
function arrayLiteral(type) {
542
if (type == "]") return cont();
543
return pass(expressionNoComma, maybeArrayComprehension);
544
}
545
function maybeArrayComprehension(type) {
546
if (type == "for") return pass(comprehension, expect("]"));
547
if (type == ",") return cont(commasep(expressionNoComma, "]"));
548
return pass(commasep(expressionNoComma, "]"));
549
}
550
function comprehension(type) {
551
if (type == "for") return cont(forspec, comprehension);
552
if (type == "if") return cont(expression, comprehension);
553
}
554
555
// Interface
556
557
return {
558
startState: function(basecolumn) {
559
var state = {
560
tokenize: tokenBase,
561
lastType: "sof",
562
cc: [],
563
lexical: new JSLexical((basecolumn || 0) - indentUnit, 0, "block", false),
564
localVars: parserConfig.localVars,
565
context: parserConfig.localVars && {vars: parserConfig.localVars},
566
indented: 0
567
};
568
if (parserConfig.globalVars) state.globalVars = parserConfig.globalVars;
569
return state;
570
},
571
572
token: function(stream, state) {
573
if (stream.sol()) {
574
if (!state.lexical.hasOwnProperty("align"))
575
state.lexical.align = false;
576
state.indented = stream.indentation();
577
findFatArrow(stream, state);
578
}
579
if (state.tokenize != tokenComment && stream.eatSpace()) return null;
580
var style = state.tokenize(stream, state);
581
if (type == "comment") return style;
582
state.lastType = type == "operator" && (content == "++" || content == "--") ? "incdec" : type;
583
return parseJS(state, style, type, content, stream);
584
},
585
586
indent: function(state, textAfter) {
587
if (state.tokenize == tokenComment) return CodeMirror.Pass;
588
if (state.tokenize != tokenBase) return 0;
589
var firstChar = textAfter && textAfter.charAt(0), lexical = state.lexical;
590
// Kludge to prevent 'maybelse' from blocking lexical scope pops
591
for (var i = state.cc.length - 1; i >= 0; --i) {
592
var c = state.cc[i];
593
if (c == poplex) lexical = lexical.prev;
594
else if (c != maybeelse) break;
595
}
596
if (lexical.type == "stat" && firstChar == "}") lexical = lexical.prev;
597
if (statementIndent && lexical.type == ")" && lexical.prev.type == "stat")
598
lexical = lexical.prev;
599
var type = lexical.type, closing = firstChar == type;
600
601
if (type == "vardef") return lexical.indented + (state.lastType == "operator" || state.lastType == "," ? lexical.info + 1 : 0);
602
else if (type == "form" && firstChar == "{") return lexical.indented;
603
else if (type == "form") return lexical.indented + indentUnit;
604
else if (type == "stat")
605
return lexical.indented + (state.lastType == "operator" || state.lastType == "," ? statementIndent || indentUnit : 0);
606
else if (lexical.info == "switch" && !closing && parserConfig.doubleIndentSwitch != false)
607
return lexical.indented + (/^(?:case|default)\b/.test(textAfter) ? indentUnit : 2 * indentUnit);
608
else if (lexical.align) return lexical.column + (closing ? 0 : 1);
609
else return lexical.indented + (closing ? 0 : indentUnit);
610
},
611
612
electricChars: ":{}",
613
blockCommentStart: jsonMode ? null : "/*",
614
blockCommentEnd: jsonMode ? null : "*/",
615
lineComment: jsonMode ? null : "//",
616
fold: "brace",
617
618
helperType: jsonMode ? "json" : "javascript",
619
jsonMode: jsonMode
620
};
621
});
622
623
CodeMirror.defineMIME("text/javascript", "javascript");
624
CodeMirror.defineMIME("text/ecmascript", "javascript");
625
CodeMirror.defineMIME("application/javascript", "javascript");
626
CodeMirror.defineMIME("application/ecmascript", "javascript");
627
CodeMirror.defineMIME("application/json", {name: "javascript", json: true});
628
CodeMirror.defineMIME("application/x-json", {name: "javascript", json: true});
629
CodeMirror.defineMIME("text/typescript", { name: "javascript", typescript: true });
630
CodeMirror.defineMIME("application/typescript", { name: "javascript", typescript: true });
631
632