codemirror-lang-raku 0.3.0 → 0.4.1

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.
package/dist/index.js CHANGED
@@ -26,12 +26,13 @@ const smiley = 201,
26
26
  MethodName = 14,
27
27
  declaredName = 206,
28
28
  declaredMethodName = 207,
29
+ declaredVariable = 208,
29
30
  Version = 15,
30
- regexStart = 208,
31
- regexBodyEnd = 209,
32
- regexLitOpen = 210,
33
- regexLitClose = 211,
34
- regexText = 212,
31
+ regexStart = 209,
32
+ regexBodyEnd = 210,
33
+ regexLitOpen = 211,
34
+ regexLitClose = 212,
35
+ regexText = 213,
35
36
  CharacterClass = 16,
36
37
  Assertion = 17,
37
38
  regexQuote = 18,
@@ -39,18 +40,18 @@ const smiley = 201,
39
40
  regexComment = 20,
40
41
  regexBlockComment = 21,
41
42
  regexCapture = 22,
42
- quoteContent = 213,
43
- quoteNestOpen = 214,
44
- quoteNestClose = 215,
45
- quoteEnd = 216,
46
- rawString = 217,
47
- quoteStart = 218,
43
+ quoteContent = 214,
44
+ quoteNestOpen = 215,
45
+ quoteNestClose = 216,
46
+ quoteEnd = 217,
47
+ rawString = 218,
48
+ quoteStart = 219,
48
49
  interpolatingWordList = 23,
49
50
  regexLiteral = 24,
50
51
  transliteration = 25,
51
- plainName = 219,
52
+ plainName = 220,
52
53
  wordOperator = 26,
53
- multiName = 220,
54
+ multiName = 221,
54
55
  operatorVariable = 27,
55
56
  LineComment = 28,
56
57
  DocComment = 29,
@@ -91,7 +92,7 @@ const smiley = 201,
91
92
  // embedded comments. Raku accepts any Unicode bracket pair; this lists
92
93
  // the ones that are likely to be typed.
93
94
  const brackets$1 = {};
94
- for (let pair of ["()", "[]", "{}", "<>", "«»", "「」", "『』", "()", "[]", "{}", "【】", "〈〉", "《》", "〔〕"])
95
+ for (let pair of ["()", "[]", "{}", "<>", "«»", "「」", "「」", "『』", "()", "[]", "{}", "【】", "〈〉", "《》", "〔〕"])
95
96
  brackets$1[pair.charCodeAt(0)] = pair.charCodeAt(1);
96
97
  function isAsciiLetter(ch) { return ch >= 97 /* Ch.a */ && ch <= 122 /* Ch.z */ || ch >= 65 /* Ch.A */ && ch <= 90 /* Ch.Z */; }
97
98
  function isDigit(ch) { return ch >= 48 /* Ch._0 */ && ch <= 57 /* Ch._9 */; }
@@ -267,7 +268,7 @@ for (let term of [VariableName, AttributeName, SpecialVariable, operatorVariable
267
268
  regexText, CharacterClass, Assertion, regexQuote, regexOperator, regexComment,
268
269
  regexBlockComment, regexCapture])
269
270
  termModes.set(term, 1 /* Mode.AfterTerm */);
270
- for (let term of [Identifier, TypeName, smiley, noSmiley, declaredName, declaredMethodName, PackageName, RoutineName,
271
+ for (let term of [Identifier, TypeName, smiley, noSmiley, declaredName, declaredMethodName, declaredVariable, PackageName, RoutineName,
271
272
  methodRoutineName, multiName, multiRoutineName, RegexName, EnumName, SubsetName, ConstantName])
272
273
  termModes.set(term, 2 /* Mode.AfterName */);
273
274
  // The `}` of "{...}" in a string does not take a subscript.
@@ -281,6 +282,10 @@ function modeAfterOperator(first, second, third, after) {
281
282
  // A lone `*` is as often the whatever star as a multiplication.
282
283
  if (first == 42 /* Ch.Star */ && !isOperatorChar(second))
283
284
  return 2 /* Mode.AfterName */;
285
+ // A power in superscript, $x², leaves the term complete. These are
286
+ // the characters that the grammar's Operator token takes for one.
287
+ if (first == 0xb2 || first == 0xb3 || first == 0xb9 || first == 0x2070 || first >= 0x2074 && first <= 0x207b)
288
+ return 1 /* Mode.AfterTerm */;
284
289
  // Postfix increment and decrement leave the term complete.
285
290
  if ((first == 43 /* Ch.Plus */ || first == 45 /* Ch.Hyphen */) && second == first && !isOperatorChar(third) &&
286
291
  (after == 1 /* Mode.AfterTerm */ || after == 3 /* Mode.AfterBlock */))
@@ -534,16 +539,24 @@ const blockComment = new ExternalTokenizer(input => {
534
539
  let end = embeddedCommentEnd(input, 0);
535
540
  if (!end)
536
541
  return;
542
+ // A declarator comment with brackets, #|( ... ) and #=( ... ), is
543
+ // still a declarator comment.
544
+ let term = input.peek(1) == 96 /* Ch.Backtick */ ? BlockComment : DocComment;
537
545
  if (end < 0)
538
546
  skipToEnd(input);
539
547
  else
540
548
  input.advance(end);
541
- input.acceptToken(BlockComment);
549
+ input.acceptToken(term);
542
550
  });
543
551
  // The offset after the embedded comment that starts at offset `at`.
544
552
  // Zero when none starts there, and -1 when it is not closed.
553
+ //
554
+ // A declarator comment with brackets that is not closed is none: it is
555
+ // left to be a comment of one line, so that one that is being typed
556
+ // does not take the declarations after it.
545
557
  function embeddedCommentEnd(input, at) {
546
- if (input.peek(at) != 35 /* Ch.Hash */ || input.peek(at + 1) != 96 /* Ch.Backtick */)
558
+ let mark = input.peek(at + 1);
559
+ if (input.peek(at) != 35 /* Ch.Hash */ || mark != 96 /* Ch.Backtick */ && mark != 124 /* Ch.Pipe */ && mark != 61 /* Ch.Equals */)
547
560
  return 0;
548
561
  let open = input.peek(at + 2), close = brackets$1[open];
549
562
  if (close == null)
@@ -551,7 +564,8 @@ function embeddedCommentEnd(input, at) {
551
564
  let count = 1;
552
565
  while (input.peek(at + 2 + count) == open)
553
566
  count++;
554
- return rawEnd(input, at + 2 + count, { open, close, count, escapes: false });
567
+ let end = rawEnd(input, at + 2 + count, { open, close, count, escapes: false });
568
+ return end < 0 && mark != 96 /* Ch.Backtick */ ? 0 : end;
555
569
  }
556
570
  function isBlank(ch) { return ch == 32 /* Ch.Space */ || ch == 9 /* Ch.Tab */ || ch == 13 /* Ch.Return */; }
557
571
  // The offset of the first character at or after `pos` that is not a blank.
@@ -784,7 +798,9 @@ function quoteCharOpening(open, close, at, interpolates, escapes = true) {
784
798
  // The delimiters, other than brackets, that are accepted after a quote word.
785
799
  function isQuoteDelimiter(ch) {
786
800
  return ch == 47 /* Ch.Slash */ || ch == 33 /* Ch.Bang */ || ch == 124 /* Ch.Pipe */ || ch == 126 /* Ch.Tilde */ || ch == 94 /* Ch.Caret */ ||
787
- ch == 37 /* Ch.Percent */ || ch == 64 /* Ch.At */ || ch == 34 /* Ch.DoubleQuote */ || ch == 39 /* Ch.Apostrophe */;
801
+ ch == 37 /* Ch.Percent */ || ch == 64 /* Ch.At */ || ch == 34 /* Ch.DoubleQuote */ || ch == 39 /* Ch.Apostrophe */ || ch == 96 /* Ch.Backtick */ ||
802
+ // A symbol outside of ASCII: Q♥a♥
803
+ ch > 0xa0 && ch != 0xd7 && ch != 0xf7 && !isIdentifierStart(ch) && !isSpace(ch) && ch < 0xd800;
788
804
  }
789
805
  // Reads the start of a quote at offset `at`: a quote character, or a
790
806
  // quote word (q, qq, m, s, ...) with its adverbs and its delimiter.
@@ -799,8 +815,16 @@ function readOpening(input, at = 0) {
799
815
  return quoteCharOpening(next, 0x201d, at, 63 /* Interpolate.All */);
800
816
  if (next == 0x2018 /* ‘ */)
801
817
  return quoteCharOpening(next, 0x2019, at, 0);
818
+ if (next == 0x201e /* „ */)
819
+ return quoteCharOpening(next, 0x201d, at, 63 /* Interpolate.All */);
820
+ if (next == 0x201d /* ” */)
821
+ return quoteCharOpening(next, next, at, 63 /* Interpolate.All */);
822
+ if (next == 0x201a /* ‚ */)
823
+ return quoteCharOpening(next, 0x2019, at, 0);
802
824
  if (next == 0x300c /* 「 */)
803
825
  return quoteCharOpening(next, 0x300d, at, 0, false);
826
+ if (next == 0xff62 /* 「 */)
827
+ return quoteCharOpening(next, 0xff63, at, 0, false);
804
828
  if (!isAsciiLetter(next))
805
829
  return null;
806
830
  let pos = at + 1;
@@ -879,14 +903,14 @@ function readOpening(input, at = 0) {
879
903
  // The offset after the delimiter that closes a quote whose content
880
904
  // starts at `pos`, or -1 when it is not closed.
881
905
  function rawEnd(input, pos, opening) {
882
- let { open, close, count } = opening;
906
+ let { open, close, count } = opening, other = otherClose(open);
883
907
  for (let depth = 1;;) {
884
908
  let ch = input.peek(pos);
885
909
  if (ch < 0)
886
910
  return -1;
887
911
  if (ch == 92 /* Ch.Backslash */ && opening.escapes)
888
912
  pos += 2;
889
- else if (ch == close && repeats(input, pos, close, count)) {
913
+ else if (ch == close && repeats(input, pos, close, count) || ch == other) {
890
914
  pos += count;
891
915
  if (--depth == 0)
892
916
  return pos;
@@ -899,26 +923,111 @@ function rawEnd(input, pos, opening) {
899
923
  pos++;
900
924
  }
901
925
  }
926
+ // The character that closes a quote in a regex that opens with `ch`,
927
+ // or 0 when `ch` opens none: 'a', "a", ‘a’, ‚a’, “a”, „a”, 「a」
928
+ function quoteClose(ch) {
929
+ return ch == 39 /* Ch.Apostrophe */ || ch == 34 /* Ch.DoubleQuote */ ? ch : ch == 0x2018 || ch == 0x201a ? 0x2019 :
930
+ ch == 0x201c || ch == 0x201e ? 0x201d : ch == 0xff62 ? 0xff63 : 0;
931
+ }
932
+ // A low quote is also closed by the quote that points the other way:
933
+ // ‚a‘, „a“. This is that quote for the given opening one, or -1.
934
+ function otherClose(open) { return open == 0x201a ? 0x2018 : open == 0x201e ? 0x201c : -1; }
902
935
  // The offset after a quoted string that starts at `pos`, or -1.
903
936
  function quotedEnd(input, pos) {
904
- let quote = input.peek(pos);
937
+ let open = input.peek(pos), close = quoteClose(open), other = otherClose(open);
905
938
  for (pos++;;) {
906
939
  let ch = input.peek(pos);
907
940
  if (ch < 0 || ch == 10 /* Ch.Newline */)
908
941
  return -1;
909
- if (ch == 92 /* Ch.Backslash */)
942
+ // Nothing is escaped in 「...」.
943
+ if (ch == 92 /* Ch.Backslash */ && open != 0xff62)
910
944
  pos += 2;
911
- else if (ch == quote)
945
+ else if (ch == close || ch == other)
912
946
  return pos + 1;
913
947
  else
914
948
  pos++;
915
949
  }
916
950
  }
951
+ // The offset after the arguments of the assertion that starts with the
952
+ // `<` at `pos`, or 0 when it has none on its line. The arguments are
953
+ // code, in which the delimiter of the regex does not end it:
954
+ // <name(1/2)>, <:name(/x/)>, <name: /a<b>+/ >
955
+ function assertionArgumentsEnd(input, pos) {
956
+ // An assertion can add up several names: <+:Lu +:name(/SMALL/)>
957
+ for (let at = pos + 1;;) {
958
+ while (isAssertionMark(input.peek(at)) || isBlank(input.peek(at)))
959
+ at++;
960
+ let end = nameEnd(input, at);
961
+ if (end < 0)
962
+ return 0;
963
+ // With parentheses, up to the one that closes them. After a colon
964
+ // and a space, up to the `>` that closes the assertion.
965
+ let open = input.peek(end);
966
+ if (open == 40 /* Ch.ParenOpen */)
967
+ return balancedEnd(input, end + 1, 40 /* Ch.ParenOpen */, 41 /* Ch.ParenClose */);
968
+ if (open == 58 /* Ch.Colon */ && isBlank(input.peek(end + 1)))
969
+ return balancedEnd(input, end + 1, 60 /* Ch.Less */, 62 /* Ch.Greater */);
970
+ at = end;
971
+ if (!isAssertionMark(input.peek(at)) && !isBlank(input.peek(at)))
972
+ return 0;
973
+ }
974
+ }
975
+ // The characters that come before the name in an assertion: <.ws>, <?before>, <+alpha>
976
+ function isAssertionMark(ch) {
977
+ return ch == 46 /* Ch.Dot */ || ch == 63 /* Ch.Question */ || ch == 33 /* Ch.Bang */ || ch == 58 /* Ch.Colon */ || ch == 38 /* Ch.Amp */ || ch == 43 /* Ch.Plus */ ||
978
+ ch == 45 /* Ch.Hyphen */;
979
+ }
980
+ // The offset after the code that the `<` or `:` at `pos` in a regex
981
+ // starts, or 0 when it starts none.
982
+ function regexCodeEnd(input, pos) {
983
+ return input.peek(pos) == 60 /* Ch.Less */ ? assertionArgumentsEnd(input, pos) : regexDeclarationEnd(input, pos);
984
+ }
985
+ // The offset after the declaration that starts with the `:` at `pos`
986
+ // in a regex, or 0 when none does: `:my $c = $/;`. It is code up to
987
+ // its `;`, in which the delimiter of the regex does not end it.
988
+ function regexDeclarationEnd(input, pos) {
989
+ let end = nameEnd(input, pos + 1);
990
+ if (end < 0 || end - pos > 9 || !isBlank(input.peek(end)) ||
991
+ !/^(my|our|state|constant|temp|let)$/.test(word(input, pos + 1, end)))
992
+ return 0;
993
+ for (;;) {
994
+ let ch = input.peek(end);
995
+ if (ch < 0 || ch == 10 /* Ch.Newline */)
996
+ return 0;
997
+ if (ch == 59 /* Ch.Semicolon */)
998
+ return end + 1;
999
+ let quoted = quoteClose(ch) ? quotedEnd(input, end) : -1;
1000
+ end = quoted > 0 ? quoted : end + 1;
1001
+ }
1002
+ }
1003
+ // The offset after the `close` that matches an `open` before `pos`, or
1004
+ // 0 when there is none on the line. Quotes are gone over.
1005
+ function balancedEnd(input, pos, open, close) {
1006
+ for (let depth = 1;;) {
1007
+ let ch = input.peek(pos);
1008
+ if (ch < 0 || ch == 10 /* Ch.Newline */)
1009
+ return 0;
1010
+ if (ch == 92 /* Ch.Backslash */)
1011
+ pos += 2;
1012
+ else if (quoteClose(ch)) {
1013
+ let quoted = quotedEnd(input, pos);
1014
+ pos = quoted < 0 ? pos + 1 : quoted;
1015
+ }
1016
+ else {
1017
+ pos++;
1018
+ if (ch == open)
1019
+ depth++;
1020
+ else if (ch == close && --depth == 0)
1021
+ return pos;
1022
+ }
1023
+ }
1024
+ }
917
1025
  // The offset of the delimiter that closes a regex whose content starts
918
1026
  // at `pos`, or -1. Delimiters do not count inside quotes, character
919
- // classes, comments and code blocks.
920
- function regexEnd(input, { start: pos, open, close, count }) {
921
- for (let depth = 1;;) {
1027
+ // classes, comments and code blocks. `code` is set for the inside of a
1028
+ // code block, where a `<` is an operator.
1029
+ function regexEnd(input, { start: pos, open, close, count }, code = false) {
1030
+ for (let depth = 1, codeEnd;;) {
922
1031
  let ch = input.peek(pos);
923
1032
  if (ch < 0)
924
1033
  return -1;
@@ -934,10 +1043,25 @@ function regexEnd(input, { start: pos, open, close, count }) {
934
1043
  pos += count;
935
1044
  depth++;
936
1045
  }
937
- else if (ch == 39 /* Ch.Apostrophe */ || ch == 34 /* Ch.DoubleQuote */) {
1046
+ else if (quoteClose(ch)) {
938
1047
  let end = quotedEnd(input, pos);
939
1048
  pos = end < 0 ? pos + 1 : end;
940
1049
  }
1050
+ else if (!code && ch == 60 /* Ch.Less */ && isBlank(input.peek(pos + 1))) {
1051
+ // A list of words, in which quotes are text: < a ' b >
1052
+ let end = pos + 2;
1053
+ while (input.peek(end) != 62 /* Ch.Greater */ && input.peek(end) != 10 /* Ch.Newline */ && input.peek(end) >= 0)
1054
+ end++;
1055
+ pos = input.peek(end) == 62 /* Ch.Greater */ ? end + 1 : pos + 1;
1056
+ }
1057
+ else if (!code && (ch == 60 /* Ch.Less */ || ch == 58 /* Ch.Colon */) && (codeEnd = regexCodeEnd(input, pos)) > 0) {
1058
+ pos = codeEnd;
1059
+ }
1060
+ else if (!code && (ch == 36 /* Ch.Dollar */ || ch == 64 /* Ch.At */) && input.peek(pos + 1) == 40 /* Ch.ParenOpen */) {
1061
+ // Code that is interpolated: $( rx/ a / )
1062
+ let end = balancedEnd(input, pos + 2, 40 /* Ch.ParenOpen */, 41 /* Ch.ParenClose */);
1063
+ pos = end > 0 ? end : pos + 1;
1064
+ }
941
1065
  else if (ch == 60 /* Ch.Less */ && (input.peek(pos + 1) == 91 /* Ch.BracketOpen */ ||
942
1066
  (input.peek(pos + 1) == 45 /* Ch.Hyphen */ || input.peek(pos + 1) == 43 /* Ch.Plus */) && input.peek(pos + 2) == 91 /* Ch.BracketOpen */)) {
943
1067
  // <[...]>, <-[...]>, and combinations: <+[a..z]-[aeiou]>
@@ -978,7 +1102,7 @@ function regexEnd(input, { start: pos, open, close, count }) {
978
1102
  pos++;
979
1103
  }
980
1104
  else if (ch == 123 /* Ch.BraceOpen */ && close != 125 /* Ch.BraceClose */) {
981
- let end = regexEnd(input, { start: pos + 1, open: 123 /* Ch.BraceOpen */, close: 125 /* Ch.BraceClose */, count: 1 });
1105
+ let end = regexEnd(input, { start: pos + 1, open: 123 /* Ch.BraceOpen */, close: 125 /* Ch.BraceClose */, count: 1 }, true);
982
1106
  pos = end < 0 ? pos + 1 : end + 1;
983
1107
  }
984
1108
  else {
@@ -986,6 +1110,21 @@ function regexEnd(input, { start: pos, open, close, count }) {
986
1110
  }
987
1111
  }
988
1112
  }
1113
+ // The offset after the `/` that closes the replacement of s/a/b/, which
1114
+ // starts at `pos`, or -1. A `$/` in it does not close it, when a `/`
1115
+ // follows on the same line: in s/a/$/, the `$` is text.
1116
+ function replacementEnd(input, pos) {
1117
+ for (let match = false;;) {
1118
+ let ch = input.peek(pos);
1119
+ if (ch < 0 || match && ch == 10 /* Ch.Newline */)
1120
+ return -1;
1121
+ if (ch == 47 /* Ch.Slash */)
1122
+ return pos + 1;
1123
+ if (ch == 36 /* Ch.Dollar */ && input.peek(pos + 1) == 47 /* Ch.Slash */)
1124
+ match = true;
1125
+ pos += match && ch == 36 /* Ch.Dollar */ || ch == 92 /* Ch.Backslash */ ? 2 : 1;
1126
+ }
1127
+ }
989
1128
  // The offset after a regex or substitution, given its opening, or -1.
990
1129
  function regexTokenEnd(input, opening) {
991
1130
  let end = regexEnd(input, opening);
@@ -993,8 +1132,12 @@ function regexTokenEnd(input, opening) {
993
1132
  return -1;
994
1133
  end += opening.count;
995
1134
  // s/a/b/ has a second part. s{a} = 'b' does not.
996
- if (opening.kind != "regex" && opening.open == opening.close)
997
- end = rawEnd(input, end, opening);
1135
+ if (opening.kind != "regex" && opening.open == opening.close) {
1136
+ // A `$/` in the replacement is the match variable, not a `$` before
1137
+ // the closing delimiter: s/(a)/[$/]/. Unless nothing closes it then.
1138
+ let withMatch = opening.close == 47 /* Ch.Slash */ ? replacementEnd(input, end) : -1;
1139
+ end = withMatch < 0 ? rawEnd(input, end, opening) : withMatch;
1140
+ }
998
1141
  return end;
999
1142
  }
1000
1143
  // The opening of a bare regex: /a/
@@ -1098,6 +1241,8 @@ const declarators$1 = /^(sub|method|submethod|token|rule|regex)$/;
1098
1241
  function startsDeclarator(name) {
1099
1242
  return ["sub", "method", "submethod", "token", "rule", "regex"].some(declarator => declarator.startsWith(name));
1100
1243
  }
1244
+ // What stands between the parentheses of a set operator.
1245
+ const setOperators = /^(<=?|>=?|<\+|>\+|==|[|&\-^+.]|elem|cont)$/;
1101
1246
  const operatorCategory = /^(infix|prefix|postfix|circumfix|postcircumfix|term)$/;
1102
1247
  function isWordOperator(name) {
1103
1248
  return name == "x" || name == "xx" || name == "min" || name == "max" || name == "Z" || name == "X";
@@ -1113,6 +1258,16 @@ const termToken = new ExternalTokenizer((input, stack) => {
1113
1258
  return;
1114
1259
  }
1115
1260
  let next = input.next, { mode } = context(stack);
1261
+ // The set operators that are written in parentheses: $a (<=) $b, $x (elem) $s
1262
+ // Not right after the term, where the parentheses hold arguments: $f(elem)
1263
+ if (next == 40 /* Ch.ParenOpen */ && mode == 1 /* Mode.AfterTerm */ && isSpace(input.peek(-1))) {
1264
+ let end = 1;
1265
+ while (end < 6 && input.peek(end) != 41 /* Ch.ParenClose */ && input.peek(end) >= 0)
1266
+ end++;
1267
+ if (input.peek(end) == 41 /* Ch.ParenClose */ && setOperators.test(word(input, 1, end)))
1268
+ input.acceptToken(wordOperator, end + 1);
1269
+ return;
1270
+ }
1116
1271
  if (isIdentifierStart(next)) {
1117
1272
  // The Z, X and R meta operators: Z+, X~, R-, Z=>
1118
1273
  if (mode == 1 /* Mode.AfterTerm */ && (next == 90 /* Ch.Z */ || next == 88 /* Ch.X */ || next == 82 /* Ch.R */) &&
@@ -1155,7 +1310,25 @@ const termToken = new ExternalTokenizer((input, stack) => {
1155
1310
  // space before it, it is a variable: `my Array[Int] %h`.
1156
1311
  if (mode == 1 /* Mode.AfterTerm */ && isIdentifierStart(input.peek(1)) && !isSpace(input.peek(-1)))
1157
1312
  return input.acceptToken(wordOperator, 1);
1158
- // An operator as a routine: &infix:<+>
1313
+ // An operator as a routine: &[+], &[»+»], &[max]
1314
+ // After a term, the `&` is an operator: $a &[1, 2]
1315
+ if (next == 38 /* Ch.Amp */ && input.peek(1) == 91 /* Ch.BracketOpen */ && mode != 1 /* Mode.AfterTerm */) {
1316
+ // A meta operator brings brackets of its own: &[R[~~]]
1317
+ for (let end = 2, depth = 1; end < 14; end++) {
1318
+ let ch = input.peek(end);
1319
+ if (ch < 0 || isSpace(ch))
1320
+ break;
1321
+ if (ch == 91 /* Ch.BracketOpen */)
1322
+ depth++;
1323
+ else if (ch == 93 /* Ch.BracketClose */ && --depth == 0) {
1324
+ if (end > 2)
1325
+ input.acceptToken(operatorVariable, end + 1);
1326
+ break;
1327
+ }
1328
+ }
1329
+ return;
1330
+ }
1331
+ // The same by its full name: &infix:<+>
1159
1332
  if (next == 38 /* Ch.Amp */) {
1160
1333
  let end = nameEnd(input, 1);
1161
1334
  if (end > 0 && operatorCategory.test(word(input, 1, end))) {
@@ -1243,7 +1416,7 @@ const quoteToken = new ExternalTokenizer((input, stack) => {
1243
1416
  let { quote } = context(stack);
1244
1417
  if (!quote)
1245
1418
  return;
1246
- let { open, close, count, interpolates } = quote, nests = open != close;
1419
+ let { open, close, count, interpolates } = quote, nests = open != close, other = otherClose(open);
1247
1420
  // After a variable, a subscript or a call continues the interpolation.
1248
1421
  // `[` and `(` are left to the grammar's own tokens.
1249
1422
  if (afterQuotedVariable(stack)) {
@@ -1261,7 +1434,7 @@ const quoteToken = new ExternalTokenizer((input, stack) => {
1261
1434
  let next = input.next;
1262
1435
  if (next < 0)
1263
1436
  break;
1264
- let atClose = next == close && repeats(input, 0, close, count);
1437
+ let atClose = next == close && repeats(input, 0, close, count) || next == other;
1265
1438
  if (atClose || nests && next == open && repeats(input, 0, open, count)) {
1266
1439
  if (input.pos > start)
1267
1440
  break;
@@ -1367,14 +1540,21 @@ function isRegexOperator(ch) {
1367
1540
  // When it is not closed on its line, this is the negated offset of the
1368
1541
  // end of the text that was gone over to find that out.
1369
1542
  function assertionEnd(input) {
1543
+ // A list of words, in which quotes and brackets are text: < a ' b >
1544
+ let words = isBlank(input.peek(1));
1370
1545
  for (let pos = 1, depth = 1;;) {
1371
1546
  let ch = input.peek(pos);
1372
1547
  if (ch < 0 || ch == 10 /* Ch.Newline */)
1373
1548
  return -pos;
1374
- if (ch == 92 /* Ch.Backslash */) {
1549
+ if (words) {
1550
+ pos++;
1551
+ if (ch == 62 /* Ch.Greater */)
1552
+ return pos;
1553
+ }
1554
+ else if (ch == 92 /* Ch.Backslash */) {
1375
1555
  pos += input.peek(pos + 1) == 10 /* Ch.Newline */ || input.peek(pos + 1) < 0 ? 1 : 2;
1376
1556
  }
1377
- else if (ch == 39 /* Ch.Apostrophe */ || ch == 34 /* Ch.DoubleQuote */) {
1557
+ else if (quoteClose(ch)) {
1378
1558
  let end = quotedEnd(input, pos);
1379
1559
  pos = end < 0 ? pos + 1 : end;
1380
1560
  }
@@ -1468,7 +1648,7 @@ const regexToken = new ExternalTokenizer((input, stack) => {
1468
1648
  skipLine(input);
1469
1649
  return input.acceptToken(regexComment);
1470
1650
  }
1471
- if (next == 39 /* Ch.Apostrophe */ || next == 34 /* Ch.DoubleQuote */) {
1651
+ if (quoteClose(next)) {
1472
1652
  let end = quotedEnd(input, 0);
1473
1653
  if (end > 0 && end <= limit)
1474
1654
  return input.acceptToken(regexQuote, end);
@@ -1534,7 +1714,7 @@ const regexToken = new ExternalTokenizer((input, stack) => {
1534
1714
  input.advance();
1535
1715
  let ch = input.next;
1536
1716
  if (ch < 0 || input.pos == literalEnd ||
1537
- ch == 10 /* Ch.Newline */ || ch == 92 /* Ch.Backslash */ || ch == 39 /* Ch.Apostrophe */ || ch == 34 /* Ch.DoubleQuote */ ||
1717
+ ch == 10 /* Ch.Newline */ || ch == 92 /* Ch.Backslash */ || quoteClose(ch) ||
1538
1718
  ch == 60 /* Ch.Less */ || ch == 62 /* Ch.Greater */ || ch == 171 /* Ch.GuillemetOpen */ || ch == 187 /* Ch.GuillemetClose */ ||
1539
1719
  ch == 41 /* Ch.ParenClose */ && input.peek(1) == 62 /* Ch.Greater */ ||
1540
1720
  ch == 123 /* Ch.BraceOpen */ || ch == 125 /* Ch.BraceClose */ || ch == 35 /* Ch.Hash */ || ch == 36 /* Ch.Dollar */ ||
@@ -1582,6 +1762,26 @@ function categoryEnd(input, nameStart, pos) {
1582
1762
  let close = first == 60 /* Ch.Less */ ? 62 /* Ch.Greater */ : first == 171 /* Ch.GuillemetOpen */ ? 187 /* Ch.GuillemetClose */ : -1;
1583
1763
  if (close < 0)
1584
1764
  return pos;
1765
+ // With double angles, blanks can surround the operator, which can
1766
+ // hold a `>` itself: infix:<< stash-eq >>, infix:<<(>=)>>
1767
+ // When this is not that form, the operator starts with `<`: infix:<<=>
1768
+ if (first == 60 /* Ch.Less */ && input.peek(open + 1) == 60 /* Ch.Less */) {
1769
+ let start = blanksEnd(input, open + 2);
1770
+ let closes = (at) => input.peek(at) == close && input.peek(at + 1) == close && input.peek(at + 2) != close;
1771
+ // An operator is short, and a token must not look far past its end.
1772
+ for (let end = start; end < start + maxGap; end++) {
1773
+ let ch = input.peek(end);
1774
+ // Not a shift in code without spaces: infix:<<=>($a){$a>>1}
1775
+ if (end > start && closes(end) && !continuesName(input, end + 2) && input.peek(end + 2) != 36 /* Ch.Dollar */)
1776
+ return end + 2;
1777
+ if (ch < 0 || isSpace(ch)) {
1778
+ let after = blanksEnd(input, end);
1779
+ if (end > start && closes(after))
1780
+ return after + 2;
1781
+ break;
1782
+ }
1783
+ }
1784
+ }
1585
1785
  // The two halves of a circumfix are separated by one space.
1586
1786
  let spaces = /circumfix$/.test(word(input, nameStart, pos)) ? 1 : 0;
1587
1787
  for (let i = open + 1;; i++) {
@@ -1597,8 +1797,17 @@ function categoryEnd(input, nameStart, pos) {
1597
1797
  // specialized identifiers, and specialization does not look at the
1598
1798
  // parse state, so these positions get tokens of their own.
1599
1799
  const nameToken = new ExternalTokenizer((input, stack) => {
1800
+ let next = input.next;
1801
+ // The name of a constant can have a sigil: constant $LIMIT = 3
1802
+ if ((next == 36 /* Ch.Dollar */ || next == 64 /* Ch.At */ || next == 37 /* Ch.Percent */ || next == 38 /* Ch.Amp */) && stack.canShift(declaredVariable)) {
1803
+ let end = nameEnd(input, 1);
1804
+ // constant &infix:<plus> = &infix:<+>
1805
+ if (end > 0)
1806
+ input.acceptToken(declaredVariable, next == 38 /* Ch.Amp */ ? categoryEnd(input, 1, end) : end);
1807
+ return;
1808
+ }
1600
1809
  // Only a method declaration takes a mark: `method !private`, `method ^meta`.
1601
- let mark = input.next == 33 /* Ch.Bang */ || input.next == 94 /* Ch.Caret */ ? 1 : 0;
1810
+ let mark = next == 33 /* Ch.Bang */ || next == 94 /* Ch.Caret */ ? 1 : 0;
1602
1811
  let end = nameEnd(input, mark);
1603
1812
  if (end < 0)
1604
1813
  return;
@@ -1607,7 +1816,17 @@ const nameToken = new ExternalTokenizer((input, stack) => {
1607
1816
  input.acceptToken(MethodName, end);
1608
1817
  return;
1609
1818
  }
1819
+ let named = end;
1610
1820
  end = categoryEnd(input, mark, end);
1821
+ // Blanks can come before the `:sym<...>` of a declaration: token c :sym<a> { a }
1822
+ if (end == named) {
1823
+ let sym = gapEnd(input, end);
1824
+ if (sym > end && word(input, sym, sym + 4) == ":sym") {
1825
+ let symEnd = categoryEnd(input, mark, sym);
1826
+ if (symEnd > sym)
1827
+ end = symEnd;
1828
+ }
1829
+ }
1611
1830
  if (!mark && stack.canShift(declaredName))
1612
1831
  input.acceptToken(declaredName, end);
1613
1832
  else if (stack.canShift(declaredMethodName))
@@ -1667,11 +1886,11 @@ const spec_identifier = {__proto__:null,class:80, role:82, grammar:84, module:86
1667
1886
  const spec_capIdentifier = {__proto__:null,True:332, False:334, Nil:336, BEGIN:338, CHECK:340, INIT:342, END:344, ENTER:346, LEAVE:348, KEEP:350, UNDO:352, FIRST:354, NEXT:356, LAST:358, PRE:360, POST:362, CATCH:364, CONTROL:366, QUIT:368, CLOSE:370, DOC:372};
1668
1887
  const parser$1 = LRParser.deserialize({
1669
1888
  version: 14,
1670
- states: "/`QfQDdOOO*zO#tOOO+POWOOO+UO,UOOO+uOSO'#C{O,PQDdO'#DPO,WQDdO'#DSO,_QDdO'#D^OOQ.W'#Df'#DfO,fQDdO'#D`O5zQ8WO'#D|OOQ.W'#D}'#D}O6PQ7gO'#EOOOQ.W'#EQ'#EQO6sO!%SO'#EQOOQ.W'#HU'#HUOOQ.W'#HT'#HTOOQ.W'#Gf'#GfQfQDdOOO6zQEUO'#DTO7RQEUO'#D`O7YQEUO'#D`O@rQEUO'#DgO@|QEUO'#DsOJqQEUO'#DvO!&fQEUO'#DyOOQ.W'#H^'#H^O!0ZO!!^OOO!1XO!%SOOOOOS'#Gg'#GgO!1`OSO,59gOOQ.W,59g,59gOOQ.W,59k,59kO!1jQDdO,59kOOQ.W,59n,59nO!1qQDdO,59nOOQ.W,59x,59xO!1xQDdO,59xOOQ.W'#Gh'#GhO!;bQDdO'#HWOOQ.W'#HW'#HWOOQ.W,59z,59zOOQ.W,5:h,5:hOOQ.W,5:j,5:jO!;iO!%SO'#ERO!;pQDdO'#ESOOO&j'#HZ'#HZO!;wO!0jO'#HZOOO&j'#Gj'#GjO!<uO!%SO,5:lOOQ.W,5:l,5:lOOQ.W-E:d-E:dOOQ.W'#DZ'#DZOOQ.W,59o,59oO,fQDdO,59oOOQ.W'#Db'#DbO,fQDdO,59zOOQ.W'#De'#DeO!<|QDdO,5:ROOQ.W'#Dk'#DkO!=TQ:[O'#DlOOQ.W,5:R,5:RO!<|QDdO,5:ROOQ.W'#Du'#DuOOQ.W,5:_,5:_OOQ.W'#Dx'#DxOOQ.W,5:b,5:bOOQ.W'#D{'#D{OOQ.W,5:e,5:eO!=]QDdO'#DrOOO#t'#HX'#HXOOO#t'#Gi'#GiO!0ZO!!^OOQOOOOOO!1XO!%SOOOOOS-E:e-E:eOOQ.W1G/R1G/ROOQ.W1G/V1G/VOOQ.W1G/Y1G/YOOQ.W1G/d1G/dOOQ.W-E:f-E:fOOQ.W,5=r,5=rOOO&j,5:m,5:mO!=dO!%SO,5:mOOO&j,5:n,5:nO!=kQDdO,5:nOOO2Q'#H]'#H]OOO2Q'#Gk'#GkO!=rO!0jO,5=uOOO&j-E:h-E:hOOQ.W1G0W1G0WOOQ.W1G/Z1G/ZOOQ.W1G/f1G/fOOQ.W1G/m1G/mO!?kO!!^O'#DmOOQ.W,5:W,5:WO!?rQ7fO,5:WO!?wQDdO1G/mOOO#t,5:^,5:^O!@OQDdO,5:^OOO#t-E:g-E:gOOO&j1G0X1G0XOOO&j1G0Y1G0YOOO2Q-E:i-E:iO!@VO!!^O,5:XOOQY,5:X,5:XOOQ.W1G/r1G/rOOQ.W7+%X7+%XOOO#t1G/x1G/xOOQY1G/s1G/s",
1671
- stateData: "!@j~O%vOSlOSmOSPOSZOS[OS~OQSO]YO__Og_Oh_Oi_Oj_Ok_Op_OrTOuUOxcOycOzcO{cO|cO!PVO!R`O!TdO!VeO!WeO![fO!]fO!^fO!c_O!d_O!e_O!hgO!khO!niO!s_O!w_O!xjO!yjO!zjO!{jO!|jO!}jO#OjO#PjO#QjO#RjO#SjO#TjO#UjO#VjO#WjO#XjO#YjO#ZjO#[jO#]jO#^jO#_jO#`jO#ajO#bjO#cjO#djO#ejO#fjO#gjO#hjO#ijO#jjO#kjO#ljO#mjO#njO#ojO#pjO#qjO#rjO#sjO#tjO#ujO#vjO#wjO#xjO#yjO#zjO#{jO#|jO#}jO$OjO$PjO$QjO$RjO$SjO$TjO$UjO$VjO$WjO$XjO$YjO$ZjO$[jO$]jO$^jO$_jO$`jO$ajO$bjO$cjO$djO$ejO$fjO$gjO$hjO$ijO$jjO$kjO$ljO$mjO$njO$ojO$pjO$qjO$rjO$sjO$tjO$ujO$vjO$wjO$xjO$yjO$zjO${jO$|jO$}jO%OjO%PjO%QjO%R_O%S_O%T_O%U_O%q]O%r^O%sZO%tWO%yZO%|[O&O_O~O%jkO~O%elO~O%rlO~OSmOTmOUmOVmOWmOXmOYmO%dmO~ORoO%coO~P+ZOqpO~PfOtrO~PfO!OtO~PfOQSO]YO__Og_Oh_Oi_Oj_Ok_Op_OrTOuUOxcOycOzcO{cO|cO!PVO!RxO!TdO!VeO!WeO![fO!]fO!^fO!c_O!d_O!e_O!hgO!khO!niO!s_O!w_O!xjO!yjO!zjO!{jO!|jO!}jO#OjO#PjO#QjO#RjO#SjO#TjO#UjO#VjO#WjO#XjO#YjO#ZjO#[jO#]jO#^jO#_jO#`jO#ajO#bjO#cjO#djO#ejO#fjO#gjO#hjO#ijO#jjO#kjO#ljO#mjO#njO#ojO#pjO#qjO#rjO#sjO#tjO#ujO#vjO#wjO#xjO#yjO#zjO#{jO#|jO#}jO$OjO$PjO$QjO$RjO$SjO$TjO$UjO$VjO$WjO$XjO$YjO$ZjO$[jO$]jO$^jO$_jO$`jO$ajO$bjO$cjO$djO$ejO$fjO$gjO$hjO$ijO$jjO$kjO$ljO$mjO$njO$ojO$pjO$qjO$rjO$sjO$tjO$ujO$vjO$wjO$xjO$yjO$zjO${jO$|jO$}jO%OjO%PjO%QjO%R_O%S_O%T_O%U_O%q]O%r^O%sZO%tWO%yZO%|[O&O_O~O^zO~O%a{O%b{O~O!P}O!b!OO!c!PO!d!PO!e!PO%m!OO%n|O&O!PO~O%p!SO~P6XO%f!UO~P,fO%f!XO~P,fO%g!ZO~P,fOQSO]YO__Og_Oh_Oi_Oj_Ok_Op_OrTOuUOxcOycOzcO{cO|cO!P!^O!TdO!VeO!WeO![fO!]fO!^fO!c_O!d_O!e_O!hgO!khO!niO!s_O!w_O!xjO!yjO!zjO!{jO!|jO!}jO#OjO#PjO#QjO#RjO#SjO#TjO#UjO#VjO#WjO#XjO#YjO#ZjO#[jO#]jO#^jO#_jO#`jO#ajO#bjO#cjO#djO#ejO#fjO#gjO#hjO#ijO#jjO#kjO#ljO#mjO#njO#ojO#pjO#qjO#rjO#sjO#tjO#ujO#vjO#wjO#xjO#yjO#zjO#{jO#|jO#}jO$OjO$PjO$QjO$RjO$SjO$TjO$UjO$VjO$WjO$XjO$YjO$ZjO$[jO$]jO$^jO$_jO$`jO$ajO$bjO$cjO$djO$ejO$fjO$gjO$hjO$ijO$jjO$kjO$ljO$mjO$njO$ojO$pjO$qjO$rjO$sjO$tjO$ujO$vjO$wjO$xjO$yjO$zjO${jO$|jO$}jO%OjO%PjO%QjO%R_O%S_O%T_O%U_O%q]O%r^O%sZO%tWO%yZO%|[O&O_O~O!R!_O%f!]O~P7aO%f!aOQ!gX]!gX_!gXg!gXh!gXi!gXj!gXk!gXp!gXr!gXu!gXx!gXy!gXz!gX{!gX|!gX!P!gX!R!gX!T!gX!V!gX!W!gX![!gX!]!gX!^!gX!c!gX!d!gX!e!gX!h!gX!k!gX!n!gX!s!gX!w!gX!x!gX!y!gX!z!gX!{!gX!|!gX!}!gX#O!gX#P!gX#Q!gX#R!gX#S!gX#T!gX#U!gX#V!gX#W!gX#X!gX#Y!gX#Z!gX#[!gX#]!gX#^!gX#_!gX#`!gX#a!gX#b!gX#c!gX#d!gX#e!gX#f!gX#g!gX#h!gX#i!gX#j!gX#k!gX#l!gX#m!gX#n!gX#o!gX#p!gX#q!gX#r!gX#s!gX#t!gX#u!gX#v!gX#w!gX#x!gX#y!gX#z!gX#{!gX#|!gX#}!gX$O!gX$P!gX$Q!gX$R!gX$S!gX$T!gX$U!gX$V!gX$W!gX$X!gX$Y!gX$Z!gX$[!gX$]!gX$^!gX$_!gX$`!gX$a!gX$b!gX$c!gX$d!gX$e!gX$f!gX$g!gX$h!gX$i!gX$j!gX$k!gX$l!gX$m!gX$n!gX$o!gX$p!gX$q!gX$r!gX$s!gX$t!gX$u!gX$v!gX$w!gX$x!gX$y!gX$z!gX${!gX$|!gX$}!gX%O!gX%P!gX%Q!gX%R!gX%S!gX%T!gX%U!gX%`!gX%q!gX%r!gX%s!gX%t!gX%y!gX%|!gX&O!gXq!gXt!gX!O!gX~O%f!cOQ!jX]!jX_!jXg!jXh!jXi!jXj!jXk!jXp!jXr!jXu!jXx!jXy!jXz!jX{!jX|!jX!P!jX!R!jX!T!jX!V!jX!W!jX![!jX!]!jX!^!jX!c!jX!d!jX!e!jX!h!jX!k!jX!n!jX!s!jX!w!jX!x!jX!y!jX!z!jX!{!jX!|!jX!}!jX#O!jX#P!jX#Q!jX#R!jX#S!jX#T!jX#U!jX#V!jX#W!jX#X!jX#Y!jX#Z!jX#[!jX#]!jX#^!jX#_!jX#`!jX#a!jX#b!jX#c!jX#d!jX#e!jX#f!jX#g!jX#h!jX#i!jX#j!jX#k!jX#l!jX#m!jX#n!jX#o!jX#p!jX#q!jX#r!jX#s!jX#t!jX#u!jX#v!jX#w!jX#x!jX#y!jX#z!jX#{!jX#|!jX#}!jX$O!jX$P!jX$Q!jX$R!jX$S!jX$T!jX$U!jX$V!jX$W!jX$X!jX$Y!jX$Z!jX$[!jX$]!jX$^!jX$_!jX$`!jX$a!jX$b!jX$c!jX$d!jX$e!jX$f!jX$g!jX$h!jX$i!jX$j!jX$k!jX$l!jX$m!jX$n!jX$o!jX$p!jX$q!jX$r!jX$s!jX$t!jX$u!jX$v!jX$w!jX$x!jX$y!jX$z!jX${!jX$|!jX$}!jX%O!jX%P!jX%Q!jX%R!jX%S!jX%T!jX%U!jX%`!jX%q!jX%r!jX%s!jX%t!jX%y!jX%|!jX&O!jXq!jXt!jX!O!jX~O%f!eOQ!mX]!mX_!mXg!mXh!mXi!mXj!mXk!mXp!mXr!mXu!mXx!mXy!mXz!mX{!mX|!mX!P!mX!R!mX!T!mX!V!mX!W!mX![!mX!]!mX!^!mX!c!mX!d!mX!e!mX!h!mX!k!mX!n!mX!s!mX!w!mX!x!mX!y!mX!z!mX!{!mX!|!mX!}!mX#O!mX#P!mX#Q!mX#R!mX#S!mX#T!mX#U!mX#V!mX#W!mX#X!mX#Y!mX#Z!mX#[!mX#]!mX#^!mX#_!mX#`!mX#a!mX#b!mX#c!mX#d!mX#e!mX#f!mX#g!mX#h!mX#i!mX#j!mX#k!mX#l!mX#m!mX#n!mX#o!mX#p!mX#q!mX#r!mX#s!mX#t!mX#u!mX#v!mX#w!mX#x!mX#y!mX#z!mX#{!mX#|!mX#}!mX$O!mX$P!mX$Q!mX$R!mX$S!mX$T!mX$U!mX$V!mX$W!mX$X!mX$Y!mX$Z!mX$[!mX$]!mX$^!mX$_!mX$`!mX$a!mX$b!mX$c!mX$d!mX$e!mX$f!mX$g!mX$h!mX$i!mX$j!mX$k!mX$l!mX$m!mX$n!mX$o!mX$p!mX$q!mX$r!mX$s!mX$t!mX$u!mX$v!mX$w!mX$x!mX$y!mX$z!mX${!mX$|!mX$}!mX%O!mX%P!mX%Q!mX%R!mX%S!mX%T!mX%U!mX%`!mX%q!mX%r!mX%s!mX%t!mX%y!mX%|!mX&O!mXq!mXt!mX!O!mX~O`!hOa!hOb!hOc!hOd!hOe!hOf!hO!P!gO!b!hO!c!hO!d!hO!e!hO%k!kO%l!hO~O%p!kO~P6XOR!nO%c!nO~P+ZOq!oO~PfOt!pO~PfO!O!qO~PfOQSO]YO__Og_Oh_Oi_Oj_Ok_Op_OrTOuUOxcOycOzcO{cO|cO!PVO!TdO!VeO!WeO![fO!]fO!^fO!c_O!d_O!e_O!hgO!khO!niO!s_O!w_O!xjO!yjO!zjO!{jO!|jO!}jO#OjO#PjO#QjO#RjO#SjO#TjO#UjO#VjO#WjO#XjO#YjO#ZjO#[jO#]jO#^jO#_jO#`jO#ajO#bjO#cjO#djO#ejO#fjO#gjO#hjO#ijO#jjO#kjO#ljO#mjO#njO#ojO#pjO#qjO#rjO#sjO#tjO#ujO#vjO#wjO#xjO#yjO#zjO#{jO#|jO#}jO$OjO$PjO$QjO$RjO$SjO$TjO$UjO$VjO$WjO$XjO$YjO$ZjO$[jO$]jO$^jO$_jO$`jO$ajO$bjO$cjO$djO$ejO$fjO$gjO$hjO$ijO$jjO$kjO$ljO$mjO$njO$ojO$pjO$qjO$rjO$sjO$tjO$ujO$vjO$wjO$xjO$yjO$zjO${jO$|jO$}jO%OjO%PjO%QjO%R_O%S_O%T_O%U_O%q]O%r^O%sZO%tWO%yZO%|[O&O_O~O!R!sO~P!2PO%o!tO~P6XO!O!vO~PfO]YOrTOuUO%q!xO!P%}X!b%}X!c%}X!d%}X!e%}X%m%}X%n%}X%p%}X&O%}X%o%}X~O%p!|O~P6XO!R#PO~P7aO!O#RO%h#QO~O!O#UO~PfO%o#XO~P6XO!O#YO~PfO]YOrTOuUO%q!xO!P%}a!b%}a!c%}a!d%}a!e%}a%m%}a%n%}a%p%}a&O%}a%o%}a~O`!hOa!hOb!hOc!hOd!hOe!hOf!hO!P!gO!b!hO!c!hO!d!hO!e!hO%l!hO~O%i#]O~P!>pO!O#^O~O!R#_O~P7aO!O#`O~PfO%i#aO~P!>pOml!d!e!cp!w%R&O%T%U~",
1672
- goto: ",r&RPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPP&SPPP&mPP&m&SPPPPP'[PP'_P&SP'xPP'{(O&SPPP(i(l(vPPPP(y&SP)P&SP)S&SP)V&m&S&SP&S)Y)YPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPP)b)|*S*g*q+PPPPPPPPPPPPPPPPPPPPPPPP+V+eP,Q,`P,fP,n&S!P_OTUVXbcdefqsuw}!W!Y![!`!g!w#T#V!O_OTUVXbcdefqsuw}!W!Y![!`!g!w#T#VT!x!P!zR!Wch`OTUVbqsu}!g!w#V[xXcde!W!YR!swR!YdR!Ye!PXOTUVXbcdefqsuw}!W!Y![!`!g!w#T#VR!`fQ!_fS#P![!`R#_#TR#S!^X!hk!j#Q#[R!bgR!dhR!fi]!O^l|!R!l!uQbOQqTQsUQuV[!Tbqsu!w#VQ!w}R#V!gQnSR!mn[wXcde!W!YQ![fU!rw![#TR#T!`Q!jkS#W!j#[R#[#QQ!R^Q!llQ!u|V!{!R!l!uQ!z!PR#Z!ziaOTUVbqsu}!g!w#Vh`OTUVbqsu}!g!w#VgvXcdefw!W!Y![!`#TUyXdeQ!VcQ!}!WR#O!YX!ik!j#Q#[]!Q^l|!R!l!uT!y!P!z",
1889
+ states: "/`QfQDdOOO*zO#tOOO+POWOOO+UO,UOOO+uOSO'#C{O,PQDdO'#DPO,WQDdO'#DSO,_QDdO'#D^OOQ.W'#Df'#DfO,fQDdO'#D`O5zQ8WO'#D|OOQ.W'#D}'#D}O6PQ7gO'#EOOOQ.W'#EQ'#EQO6sO!%SO'#EQOOQ.W'#HV'#HVOOQ.W'#HU'#HUOOQ.W'#Gf'#GfQfQDdOOO6zQEUO'#DTO7RQEUO'#D`O7YQEUO'#D`O@rQEUO'#DgO@|QEUO'#DsOJqQEUO'#DvO!&fQEUO'#DyOOQ.W'#H_'#H_O!0^O!!^OOO!1[O!%SOOOOOS'#Gg'#GgO!1cOSO,59gOOQ.W,59g,59gOOQ.W,59k,59kO!1mQDdO,59kOOQ.W,59n,59nO!1tQDdO,59nOOQ.W,59x,59xO!1{QDdO,59xOOQ.W'#Gh'#GhO!;eQDdO'#HXOOQ.W'#HX'#HXOOQ.W,59z,59zOOQ.W,5:h,5:hOOQ.W,5:j,5:jO!;lO!%SO'#ERO!;sQDdO'#ESOOO&j'#H['#H[O!;zO!0jO'#H[OOO&j'#Gj'#GjO!<xO!%SO,5:lOOQ.W,5:l,5:lOOQ.W-E:d-E:dOOQ.W'#DZ'#DZOOQ.W,59o,59oO,fQDdO,59oOOQ.W'#Db'#DbO,fQDdO,59zOOQ.W'#De'#DeO!=PQDdO,5:ROOQ.W'#Dk'#DkO!=WQ:[O'#DlOOQ.W,5:R,5:RO!=PQDdO,5:ROOQ.W'#Du'#DuOOQ.W,5:_,5:_OOQ.W'#Dx'#DxOOQ.W,5:b,5:bOOQ.W'#D{'#D{OOQ.W,5:e,5:eO!=`QDdO'#DrOOO#t'#HY'#HYOOO#t'#Gi'#GiO!0^O!!^OOQOOOOOO!1[O!%SOOOOOS-E:e-E:eOOQ.W1G/R1G/ROOQ.W1G/V1G/VOOQ.W1G/Y1G/YOOQ.W1G/d1G/dOOQ.W-E:f-E:fOOQ.W,5=s,5=sOOO&j,5:m,5:mO!=gO!%SO,5:mOOO&j,5:n,5:nO!=nQDdO,5:nOOO2Q'#H^'#H^OOO2Q'#Gk'#GkO!=uO!0jO,5=vOOO&j-E:h-E:hOOQ.W1G0W1G0WOOQ.W1G/Z1G/ZOOQ.W1G/f1G/fOOQ.W1G/m1G/mO!?nO!!^O'#DmOOQ.W,5:W,5:WO!?uQ7fO,5:WO!?zQDdO1G/mOOO#t,5:^,5:^O!@RQDdO,5:^OOO#t-E:g-E:gOOO&j1G0X1G0XOOO&j1G0Y1G0YOOO2Q-E:i-E:iO!@YO!!^O,5:XOOQY,5:X,5:XOOQ.W1G/r1G/rOOQ.W7+%X7+%XOOO#t1G/x1G/xOOQY1G/s1G/s",
1890
+ stateData: "!@m~O%wOSlOSmOSPOSZOS[OS~OQSO]YO__Og_Oh_Oi_Oj_Ok_Op_OrTOuUOxcOycOzcO{cO|cO!PVO!R`O!TdO!VeO!WeO![fO!]fO!^fO!c_O!d_O!e_O!hgO!khO!niO!s_O!w_O!xjO!yjO!zjO!{jO!|jO!}jO#OjO#PjO#QjO#RjO#SjO#TjO#UjO#VjO#WjO#XjO#YjO#ZjO#[jO#]jO#^jO#_jO#`jO#ajO#bjO#cjO#djO#ejO#fjO#gjO#hjO#ijO#jjO#kjO#ljO#mjO#njO#ojO#pjO#qjO#rjO#sjO#tjO#ujO#vjO#wjO#xjO#yjO#zjO#{jO#|jO#}jO$OjO$PjO$QjO$RjO$SjO$TjO$UjO$VjO$WjO$XjO$YjO$ZjO$[jO$]jO$^jO$_jO$`jO$ajO$bjO$cjO$djO$ejO$fjO$gjO$hjO$ijO$jjO$kjO$ljO$mjO$njO$ojO$pjO$qjO$rjO$sjO$tjO$ujO$vjO$wjO$xjO$yjO$zjO${jO$|jO$}jO%OjO%PjO%QjO%R_O%S_O%T_O%U_O%r]O%s^O%tZO%uWO%zZO%}[O&P_O~O%kkO~O%elO~O%slO~OSmOTmOUmOVmOWmOXmOYmO%dmO~ORoO%coO~P+ZOqpO~PfOtrO~PfO!OtO~PfOQSO]YO__Og_Oh_Oi_Oj_Ok_Op_OrTOuUOxcOycOzcO{cO|cO!PVO!RxO!TdO!VeO!WeO![fO!]fO!^fO!c_O!d_O!e_O!hgO!khO!niO!s_O!w_O!xjO!yjO!zjO!{jO!|jO!}jO#OjO#PjO#QjO#RjO#SjO#TjO#UjO#VjO#WjO#XjO#YjO#ZjO#[jO#]jO#^jO#_jO#`jO#ajO#bjO#cjO#djO#ejO#fjO#gjO#hjO#ijO#jjO#kjO#ljO#mjO#njO#ojO#pjO#qjO#rjO#sjO#tjO#ujO#vjO#wjO#xjO#yjO#zjO#{jO#|jO#}jO$OjO$PjO$QjO$RjO$SjO$TjO$UjO$VjO$WjO$XjO$YjO$ZjO$[jO$]jO$^jO$_jO$`jO$ajO$bjO$cjO$djO$ejO$fjO$gjO$hjO$ijO$jjO$kjO$ljO$mjO$njO$ojO$pjO$qjO$rjO$sjO$tjO$ujO$vjO$wjO$xjO$yjO$zjO${jO$|jO$}jO%OjO%PjO%QjO%R_O%S_O%T_O%U_O%r]O%s^O%tZO%uWO%zZO%}[O&P_O~O^zO~O%a{O%b{O~O!P}O!b!OO!c!PO!d!PO!e!PO%n!OO%o|O&P!PO~O%q!SO~P6XO%f!UO~P,fO%f!XO~P,fO%g!ZO~P,fOQSO]YO__Og_Oh_Oi_Oj_Ok_Op_OrTOuUOxcOycOzcO{cO|cO!P!^O!TdO!VeO!WeO![fO!]fO!^fO!c_O!d_O!e_O!hgO!khO!niO!s_O!w_O!xjO!yjO!zjO!{jO!|jO!}jO#OjO#PjO#QjO#RjO#SjO#TjO#UjO#VjO#WjO#XjO#YjO#ZjO#[jO#]jO#^jO#_jO#`jO#ajO#bjO#cjO#djO#ejO#fjO#gjO#hjO#ijO#jjO#kjO#ljO#mjO#njO#ojO#pjO#qjO#rjO#sjO#tjO#ujO#vjO#wjO#xjO#yjO#zjO#{jO#|jO#}jO$OjO$PjO$QjO$RjO$SjO$TjO$UjO$VjO$WjO$XjO$YjO$ZjO$[jO$]jO$^jO$_jO$`jO$ajO$bjO$cjO$djO$ejO$fjO$gjO$hjO$ijO$jjO$kjO$ljO$mjO$njO$ojO$pjO$qjO$rjO$sjO$tjO$ujO$vjO$wjO$xjO$yjO$zjO${jO$|jO$}jO%OjO%PjO%QjO%R_O%S_O%T_O%U_O%r]O%s^O%tZO%uWO%zZO%}[O&P_O~O!R!_O%f!]O~P7aO%f!aOQ!gX]!gX_!gXg!gXh!gXi!gXj!gXk!gXp!gXr!gXu!gXx!gXy!gXz!gX{!gX|!gX!P!gX!R!gX!T!gX!V!gX!W!gX![!gX!]!gX!^!gX!c!gX!d!gX!e!gX!h!gX!k!gX!n!gX!s!gX!w!gX!x!gX!y!gX!z!gX!{!gX!|!gX!}!gX#O!gX#P!gX#Q!gX#R!gX#S!gX#T!gX#U!gX#V!gX#W!gX#X!gX#Y!gX#Z!gX#[!gX#]!gX#^!gX#_!gX#`!gX#a!gX#b!gX#c!gX#d!gX#e!gX#f!gX#g!gX#h!gX#i!gX#j!gX#k!gX#l!gX#m!gX#n!gX#o!gX#p!gX#q!gX#r!gX#s!gX#t!gX#u!gX#v!gX#w!gX#x!gX#y!gX#z!gX#{!gX#|!gX#}!gX$O!gX$P!gX$Q!gX$R!gX$S!gX$T!gX$U!gX$V!gX$W!gX$X!gX$Y!gX$Z!gX$[!gX$]!gX$^!gX$_!gX$`!gX$a!gX$b!gX$c!gX$d!gX$e!gX$f!gX$g!gX$h!gX$i!gX$j!gX$k!gX$l!gX$m!gX$n!gX$o!gX$p!gX$q!gX$r!gX$s!gX$t!gX$u!gX$v!gX$w!gX$x!gX$y!gX$z!gX${!gX$|!gX$}!gX%O!gX%P!gX%Q!gX%R!gX%S!gX%T!gX%U!gX%`!gX%r!gX%s!gX%t!gX%u!gX%z!gX%}!gX&P!gXq!gXt!gX!O!gX~O%f!cOQ!jX]!jX_!jXg!jXh!jXi!jXj!jXk!jXp!jXr!jXu!jXx!jXy!jXz!jX{!jX|!jX!P!jX!R!jX!T!jX!V!jX!W!jX![!jX!]!jX!^!jX!c!jX!d!jX!e!jX!h!jX!k!jX!n!jX!s!jX!w!jX!x!jX!y!jX!z!jX!{!jX!|!jX!}!jX#O!jX#P!jX#Q!jX#R!jX#S!jX#T!jX#U!jX#V!jX#W!jX#X!jX#Y!jX#Z!jX#[!jX#]!jX#^!jX#_!jX#`!jX#a!jX#b!jX#c!jX#d!jX#e!jX#f!jX#g!jX#h!jX#i!jX#j!jX#k!jX#l!jX#m!jX#n!jX#o!jX#p!jX#q!jX#r!jX#s!jX#t!jX#u!jX#v!jX#w!jX#x!jX#y!jX#z!jX#{!jX#|!jX#}!jX$O!jX$P!jX$Q!jX$R!jX$S!jX$T!jX$U!jX$V!jX$W!jX$X!jX$Y!jX$Z!jX$[!jX$]!jX$^!jX$_!jX$`!jX$a!jX$b!jX$c!jX$d!jX$e!jX$f!jX$g!jX$h!jX$i!jX$j!jX$k!jX$l!jX$m!jX$n!jX$o!jX$p!jX$q!jX$r!jX$s!jX$t!jX$u!jX$v!jX$w!jX$x!jX$y!jX$z!jX${!jX$|!jX$}!jX%O!jX%P!jX%Q!jX%R!jX%S!jX%T!jX%U!jX%`!jX%r!jX%s!jX%t!jX%u!jX%z!jX%}!jX&P!jXq!jXt!jX!O!jX~O%f!eO%h!eOQ!mX]!mX_!mXg!mXh!mXi!mXj!mXk!mXp!mXr!mXu!mXx!mXy!mXz!mX{!mX|!mX!P!mX!R!mX!T!mX!V!mX!W!mX![!mX!]!mX!^!mX!c!mX!d!mX!e!mX!h!mX!k!mX!n!mX!s!mX!w!mX!x!mX!y!mX!z!mX!{!mX!|!mX!}!mX#O!mX#P!mX#Q!mX#R!mX#S!mX#T!mX#U!mX#V!mX#W!mX#X!mX#Y!mX#Z!mX#[!mX#]!mX#^!mX#_!mX#`!mX#a!mX#b!mX#c!mX#d!mX#e!mX#f!mX#g!mX#h!mX#i!mX#j!mX#k!mX#l!mX#m!mX#n!mX#o!mX#p!mX#q!mX#r!mX#s!mX#t!mX#u!mX#v!mX#w!mX#x!mX#y!mX#z!mX#{!mX#|!mX#}!mX$O!mX$P!mX$Q!mX$R!mX$S!mX$T!mX$U!mX$V!mX$W!mX$X!mX$Y!mX$Z!mX$[!mX$]!mX$^!mX$_!mX$`!mX$a!mX$b!mX$c!mX$d!mX$e!mX$f!mX$g!mX$h!mX$i!mX$j!mX$k!mX$l!mX$m!mX$n!mX$o!mX$p!mX$q!mX$r!mX$s!mX$t!mX$u!mX$v!mX$w!mX$x!mX$y!mX$z!mX${!mX$|!mX$}!mX%O!mX%P!mX%Q!mX%R!mX%S!mX%T!mX%U!mX%`!mX%r!mX%s!mX%t!mX%u!mX%z!mX%}!mX&P!mXq!mXt!mX!O!mX~O`!hOa!hOb!hOc!hOd!hOe!hOf!hO!P!gO!b!hO!c!hO!d!hO!e!hO%l!kO%m!hO~O%q!kO~P6XOR!nO%c!nO~P+ZOq!oO~PfOt!pO~PfO!O!qO~PfOQSO]YO__Og_Oh_Oi_Oj_Ok_Op_OrTOuUOxcOycOzcO{cO|cO!PVO!TdO!VeO!WeO![fO!]fO!^fO!c_O!d_O!e_O!hgO!khO!niO!s_O!w_O!xjO!yjO!zjO!{jO!|jO!}jO#OjO#PjO#QjO#RjO#SjO#TjO#UjO#VjO#WjO#XjO#YjO#ZjO#[jO#]jO#^jO#_jO#`jO#ajO#bjO#cjO#djO#ejO#fjO#gjO#hjO#ijO#jjO#kjO#ljO#mjO#njO#ojO#pjO#qjO#rjO#sjO#tjO#ujO#vjO#wjO#xjO#yjO#zjO#{jO#|jO#}jO$OjO$PjO$QjO$RjO$SjO$TjO$UjO$VjO$WjO$XjO$YjO$ZjO$[jO$]jO$^jO$_jO$`jO$ajO$bjO$cjO$djO$ejO$fjO$gjO$hjO$ijO$jjO$kjO$ljO$mjO$njO$ojO$pjO$qjO$rjO$sjO$tjO$ujO$vjO$wjO$xjO$yjO$zjO${jO$|jO$}jO%OjO%PjO%QjO%R_O%S_O%T_O%U_O%r]O%s^O%tZO%uWO%zZO%}[O&P_O~O!R!sO~P!2SO%p!tO~P6XO!O!vO~PfO]YOrTOuUO%r!xO!P&OX!b&OX!c&OX!d&OX!e&OX%n&OX%o&OX%q&OX&P&OX%p&OX~O%q!|O~P6XO!R#PO~P7aO!O#RO%i#QO~O!O#UO~PfO%p#XO~P6XO!O#YO~PfO]YOrTOuUO%r!xO!P&Oa!b&Oa!c&Oa!d&Oa!e&Oa%n&Oa%o&Oa%q&Oa&P&Oa%p&Oa~O`!hOa!hOb!hOc!hOd!hOe!hOf!hO!P!gO!b!hO!c!hO!d!hO!e!hO%m!hO~O%j#]O~P!>sO!O#^O~O!R#_O~P7aO!O#`O~PfO%j#aO~P!>sOml!d!e!cp!w%R&P%T%U~",
1891
+ goto: ",s&SPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPP&TPPP&nPP&n&TPPPPP']PP'`P&TP'yPP'|(P&TPPP(j(m(wPPPP(z&TP)Q&TP)T&TP)W&n&T&TP&T)Z)ZPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPP)c)}*T*h*r+QPPPPPPPPPPPPPPPPPPPPPPPP+W+fP,R,aP,gP,o&T!P_OTUVXbcdefqsuw}!W!Y![!`!g!w#T#V!O_OTUVXbcdefqsuw}!W!Y![!`!g!w#T#VT!x!P!zR!Wch`OTUVbqsu}!g!w#V[xXcde!W!YR!swR!YdR!Ye!PXOTUVXbcdefqsuw}!W!Y![!`!g!w#T#VR!`fQ!_fS#P![!`R#_#TR#S!^X!hk!j#Q#[R!bgR!dhR!fi]!O^l|!R!l!uQbOQqTQsUQuV[!Tbqsu!w#VQ!w}R#V!gQnSR!mn[wXcde!W!YQ![fU!rw![#TR#T!`Q!jkS#W!j#[R#[#QQ!R^Q!llQ!u|V!{!R!l!uQ!z!PR#Z!ziaOTUVbqsu}!g!w#Vh`OTUVbqsu}!g!w#VgvXcdefw!W!Y![!`#TUyXdeQ!VcQ!}!WR#O!YX!ik!j#Q#[]!Q^l|!R!l!uT!y!P!z",
1673
1892
  nodeNames: "⚠ BlockComment PodDirective PodDirective PodDirective PodHeading PodStrong PodEmphasis PodCode PodLink PodFormat Heredoc Heredoc . MethodName Version CharacterClass Assertion StringLiteral Operator LineComment BlockComment VariableName StringLiteral Regex Regex Operator VariableName LineComment DocComment Program Pod Number ) ( Parens ] [ Brackets PackageDeclaration class role grammar module package PackageName } { Block ; RoutineDeclaration sub RoutineName method submethod RoutineName RoutineName RegexDeclaration token rule regex RegexName Block Regex Escape VariableName AttributeName SpecialVariable Block EnumDeclaration enum EnumName SubsetDeclaration subset SubsetName ConstantDeclaration constant ConstantName MethodCall Identifier TypeName Number StringLiteral NestedDelimiters Interpolation PairKey my our has state temp let anon augment supersede unit multi proto only if elsif else unless with orwith without for while until loop repeat given when default do gather take try return next last redo proceed succeed react whenever supply emit start use need import require no is does of returns handles where will trusts hides and or not xor so andthen orelse notandthen div mod gcd lcm eq ne lt gt le ge cmp leg eqv but self True False Nil BEGIN CHECK INIT END ENTER LEAVE KEEP UNDO FIRST NEXT LAST PRE POST CATCH CONTROL QUIT CLOSE DOC Operator , : . Regex Heredoc StringLiteral",
1674
- maxTerm: 232,
1893
+ maxTerm: 233,
1675
1894
  context: trackContext,
1676
1895
  nodeProps: [
1677
1896
  ["openedBy", 33,"(",36,"[",46,"{"],
@@ -1679,11 +1898,11 @@ const parser$1 = LRParser.deserialize({
1679
1898
  ],
1680
1899
  skippedNodes: [0,1,11,12,28,29],
1681
1900
  repeatNodeCount: 6,
1682
- tokenData: "!$`~R!aX^%Wpq%Wqr%{st']tu(|uv5Rvw8axy:Wyz:]z{%{{|%{|}:b}!O%{!O!P:g!P!Q%{!Q!R;V!R![=f![!]@Z!]!^FQ!^!_%{!_!`%{!`!a%{!a!b%{!b!cFV!c!}Gy!}#OJu#O#PJz#P#Q! T#Q#R%{#R#S! Y#T#o! Y#o#p!$U#p#q%{#q#r!$Z#r#s%{#y#z%W$f$g%W$p$q! Y$q$r%{${$|! Y%Q%R! Y%R%S%{%W%o! Y%o%p%{%p&a! Y&a&b%{&b#BY! Y#BY#BZ%W#BZ$IS! Y$IS$I_%W$Iz$I{%{$I|$JO%W$JT$JU%W$KV$KW%W%&Y%+t%{&/x&Et! Y&FU&FV%W&Gh;'S! Y;'S;=`!#x?&r?Bj! Y?Hw?Ic! Y?Ii?JT! Y?J`?L{! Y~%]Y%v~X^%Wpq%W#y#z%W$f$g%W#BY#BZ%W$IS$I_%W$I|$JO%W$JT$JU%W$KV$KW%W&FU&FV%WP&Qc%RPqr%{z{%{{|%{}!O%{!P!Q%{!^!_%{!_!`%{!`!a%{!a!b%{#O#P%{#Q#R%{#p#q%{#r#s%{$q$r%{%R%S%{%o%p%{&a&b%{$Iz$I{%{%&Y%+t%{~'bWl~OY'zZ!_'z!_!`(c!`#p'z#p#q(c#q;'S'z;'S;=`(]<%lO'z~(PSl~OY'zZ;'S'z;'S;=`(]<%lO'z~(`P;=`<%l'z~(jSm~l~OY(cZ;'S(c;'S;=`(v<%lO(c~(yP;=`<%l(c~)Rk&O~qr*vz{.|!O!P-h!P!Q1x!Q![1}![!]2V!_!`.|!a!b.|!c!}3_#Q#R2V#R#S3_#T#o3_#r#s.|$p$q3_${$|3_%Q%R3_%W%o3_%p&a3_&b#BY3_#BZ$IS3_&/x&Et3_&Gh;'S3_;'S;=`4{?&r?Bj3_?Hw?Ic3_?Ii?JT3_?J`?L{3_~*{a!c~!c!},Q#R#S,Q#T#o,Q$p$q,Q${$|,Q%Q%R,Q%W%o,Q%p&a,Q&b#BY,Q#BZ$IS,Q&/x&Et,Q&Gh;'S,Q;'S;=`.p?&r?Bj,Q?Hw?Ic,Q?Ii?JT,Q?J`?L{,Q~,Ve!d~wx-h}!O-h!Q![,Q![!].v!c!},Q#R#S,Q#T#o,Q$p$q,Q${$|,Q%Q%R,Q%W%o,Q%p&a,Q&b#BY,Q#BZ$IS,Q&/x&Et,Q&Gh;'S,Q;'S;=`.p?&r?Bj,Q?Hw?Ic,Q?Ii?JT,Q?J`?L{,Q~-ka!c!},Q#R#S,Q#T#o,Q$p$q,Q${$|,Q%Q%R,Q%W%o,Q%p&a,Q&b#BY,Q#BZ$IS,Q&/x&Et,Q&Gh;'S,Q;'S;=`.p?&r?Bj,Q?Hw?Ic,Q?Ii?JT,Q?J`?L{,Q~.sP;=`<%l,Q~.yP![!]-h~/Pa!c!}0U#R#S0U#T#o0U$p$q0U${$|0U%Q%R0U%W%o0U%p&a0U&b#BY0U#BZ$IS0U&/x&Et0U&Gh;'S0U;'S;=`1r?&r?Bj0U?Hw?Ic0U?Ii?JT0U?J`?L{0U~0Ze!e~wx.|}!O.|!Q![0U![!]1l!c!}0U#R#S0U#T#o0U$p$q0U${$|0U%Q%R0U%W%o0U%p&a0U&b#BY0U#BZ$IS0U&/x&Et0U&Gh;'S0U;'S;=`1r?&r?Bj0U?Hw?Ic0U?Ii?JT0U?J`?L{0U~1oP![!].|~1uP;=`<%l0U~1}O!c~~2SP!c~!Q![1}~2Ya!c!}3_#R#S3_#T#o3_$p$q3_${$|3_%Q%R3_%W%o3_%p&a3_&b#BY3_#BZ$IS3_&/x&Et3_&Gh;'S3_;'S;=`4{?&r?Bj3_?Hw?Ic3_?Ii?JT3_?J`?L{3_~3de!c~wx2V}!O2V!Q![3_![!]4u!c!}3_#R#S3_#T#o3_$p$q3_${$|3_%Q%R3_%W%o3_%p&a3_&b#BY3_#BZ$IS3_&/x&Et3_&Gh;'S3_;'S;=`4{?&r?Bj3_?Hw?Ic3_?Ii?JT3_?J`?L{3_~4xP![!]2V~5OP;=`<%l3_~5Wj%RPqr-huv6xz{.|!O!P-h![!]2V!_!`7V!a!b.|!c!}3_#Q#R2V#R#S3_#T#o3_#r#s.|$p$q3_${$|3_%Q%R3_%W%o3_%p&a3_&b#BY3_#BZ$IS3_&/x&Et3_&Gh;'S3_;'S;=`4{?&r?Bj3_?Hw?Ic3_?Ii?JT3_?J`?L{3_P6}P%RP!_!`7QP7VO%RP~7[a%RP!c!}0U#R#S0U#T#o0U$p$q0U${$|0U%Q%R0U%W%o0U%p&a0U&b#BY0U#BZ$IS0U&/x&Et0U&Gh;'S0U;'S;=`1r?&r?Bj0U?Hw?Ic0U?Ii?JT0U?J`?L{0U~8fj%RPqr-hvw6xz{.|!O!P-h![!]2V!_!`7V!a!b.|!c!}3_#Q#R2V#R#S3_#T#o3_#r#s.|$p$q3_${$|3_%Q%R3_%W%o3_%p&a3_&b#BY3_#BZ$IS3_&/x&Et3_&Gh;'S3_;'S;=`4{?&r?Bj3_?Hw?Ic3_?Ii?JT3_?J`?L{3_~:]Or~~:bOq~~:gO%S~~:lQ%U~!O!P:r!_!`7QP:wQ%RP!O!P:}#Q#R7QP;SP%RP#Q#R7Q~;[^!s~!O!P<W!Q![=f!d!e>T!f!g>o!g!h<r!q!r?T!z!{?i#R#S=}#U#V>T#W#X>o#X#Y<r#]#^=a#c#d?T#l#m?i~<ZP!Q![<^~<cT!s~!Q![<^!g!h<r#R#S<W#X#Y<r#]#^=a~<uR{|=O}!O=O!Q![=U~=RP!Q![=U~=ZQ!s~!Q![=U#]#^=a~=fO!s~~=kU!s~!O!P<W!Q![=f!g!h<r#R#S=}#X#Y<r#]#^=a~>QP!Q![=f~>WR!Q!R>a!R!S>a#R#S>a~>fR!s~!Q!R>a!R!S>a#R#S>a~>rQ!Q![>x#R#S>x~>}Q!s~!Q![>x#R#S>x~?WQ!Q!Y?^#R#S?^~?cQ!s~!Q!Y?^#R#S?^~?lS!Q![?x!c!i?x#R#S?x#T#Z?x~?}S!s~!Q![?x!c!i?x#R#S?x#T#Z?x~@`e%T~qrAq!Q![Dm![!]Et!_!`7Q!c!}By#R#SBy#T#oBy$p$qBy${$|By%Q%RBy%W%oBy%p&aBy&b#BYBy#BZ$ISBy&/x&EtBy&Gh;'SBy;'S;=`Dg?&r?BjBy?Hw?IcBy?Ii?JTBy?J`?L{By~Ata!c!}By#R#SBy#T#oBy$p$qBy${$|By%Q%RBy%W%oBy%p&aBy&b#BYBy#BZ$ISBy&/x&EtBy&Gh;'SBy;'S;=`Dg?&r?BjBy?Hw?IcBy?Ii?JTBy?J`?L{By~COe!w~wxAq}!OAq!Q![By![!]Da!c!}By#R#SBy#T#oBy$p$qBy${$|By%Q%RBy%W%oBy%p&aBy&b#BYBy#BZ$ISBy&/x&EtBy&Gh;'SBy;'S;=`Dg?&r?BjBy?Hw?IcBy?Ii?JTBy?J`?L{By~DdP![!]Aq~DjP;=`<%lBy~DpQ!Q![Dm!^!_Dv~DyT!O!PEY!Q![EY!c!}EY#R#SEY#T#oEY~E]U!O!PEY!Q![EY!`!aEo!c!}EY#R#SEY#T#oEY~EtOp~PEwP![!]EzPE}P!_!`7Q~FVO!R~~F[i&O~qr-hz{.|!O!P-h![!]2V!_!`.|!a!b.|!c!}3_#Q#R2V#R#S3_#T#o3_#r#s.|$p$q3_${$|3_%Q%R3_%W%o3_%p&a3_&b#BY3_#BZ$IS3_&/x&Et3_&Gh;'S3_;'S;=`4{?&r?Bj3_?Hw?Ic3_?Ii?JT3_?J`?L{3_~HOe%|~wxIa}!OIa!Q![Gy![!]Jo!c!}Gy#R#SGy#T#oGy$p$qGy${$|Gy%Q%RGy%W%oGy%p&aGy&b#BYGy#BZ$ISGy&/x&EtGy&Gh;'SGy;'S;=`Ji?&r?BjGy?Hw?IcGy?Ii?JTGy?J`?L{Gy~Ida!c!}Gy#R#SGy#T#oGy$p$qGy${$|Gy%Q%RGy%W%oGy%p&aGy&b#BYGy#BZ$ISGy&/x&EtGy&Gh;'SGy;'S;=`Ji?&r?BjGy?Hw?IcGy?Ii?JTGy?J`?L{Gy~JlP;=`<%lGy~JrP![!]Ia~JzOu~RKPu%RPOqMdqrMirzMdz{Mi{|Mi|}Md}!OMi!O!PMd!P!QMi!Q!^Md!^!_Mi!_!`Mi!`!aMi!a!bMi!b#OMd#O#PMi#P#QMd#Q#RMi#R#pMd#p#qMi#q#rMd#r#sMi#s$qMd$q$rMi$r%RMd%R%SMi%S%oMd%o%pMi%p&aMd&a&bMi&b$IzMd$Iz$I{Mi$I{%&YMd%&Y%+tMi%+t;'SMd;'S;=`N{;=`OMdQMiO!bQRMpc!bQ%RPqr%{z{%{{|%{}!O%{!P!Q%{!^!_%{!_!`%{!`!a%{!a!b%{#O#P%{#Q#R%{#p#q%{#r#s%{$q$r%{%R%S%{%o%p%{&a&b%{$Iz$I{%{%&Y%+t%{Q! QP!bQ;=`<%lMd~! YOt~~! _e%y~wx!!p}!O!!p!Q![! Y![!]!$O!c!}! Y#R#S! Y#T#o! Y$p$q! Y${$|! Y%Q%R! Y%W%o! Y%p&a! Y&b#BY! Y#BZ$IS! Y&/x&Et! Y&Gh;'S! Y;'S;=`!#x?&r?Bj! Y?Hw?Ic! Y?Ii?JT! Y?J`?L{! Y~!!sa!c!}! Y#R#S! Y#T#o! Y$p$q! Y${$|! Y%Q%R! Y%W%o! Y%p&a! Y&b#BY! Y#BZ$IS! Y&/x&Et! Y&Gh;'S! Y;'S;=`!#x?&r?Bj! Y?Hw?Ic! Y?Ii?JT! Y?J`?L{! Y~!#{P;=`<%l! Y~!$RP![!]!!p~!$ZO!P~~!$`O!O~",
1901
+ tokenData: "!'z~R!qX^&Ypq&Yqr&}st(wtu*huv6pvw:Oxy;uyz;zz{&}{|&}|}<P}!O&}!O!P<U!P!Q&}!Q!R<t!R![?T![!]Ax!]!^Go!^!_&}!_!`&}!`!a&}!a!b&}!b!cGt!c!}Ih!}#OLd#O#PLi#P#Q!$Z#Q#R&}#R#S!$`#T#o!$`#o#p!'[#p#q&}#q#r!'a#r#s&}#y#z&Y$f$g&Y$g$p&}$p$q!$`$q$r&}$r$s&}$t$x&}$x$y!'f$y$z!'f$z${&}${$|!$`$|%P&}%P%Q!'f%Q%R!$`%R%S&}%S%V?O%V%W&}%W%o!$`%o%p&}%p&a!$`&a&b&}&b#BY!$`#BY#BZ&Y#BZ$IS!$`$IS$I_&Y$Id$Il&}$It$I|&}$I|$JO&Y$JT$JU&Y$JU$KV&}$KV$KW&Y$Kh$Ki!'f$Kl$Kt!'f%!b%!r?O%#m%#n?O%#t&/x&}&/x&Et!$`&FU&FV&Y&Gh;'S!$`;'S;=`!'O?&r?Bj!$`?Hw?Ic!$`?Ii?JT!$`?J`?L{!$`~&_Y%w~X^&Ypq&Y#y#z&Y$f$g&Y#BY#BZ&Y$IS$I_&Y$I|$JO&Y$JT$JU&Y$KV$KW&Y&FU&FV&YP'Sk%RPqr&}z{&}{|&}}!O&}!P!Q&}!^!_&}!_!`&}!`!a&}!a!b&}#O#P&}#Q#R&}#p#q&}#r#s&}$g$p&}$q$r&}$r$s&}$t$x&}$z${&}$|%P&}%R%S&}%V%W&}%o%p&}&a&b&}$Id$Il&}$It$I|&}$JU$KV&}%#t&/x&}~(|Wl~OY)fZ!_)f!_!`)}!`#p)f#p#q)}#q;'S)f;'S;=`)w<%lO)f~)kSl~OY)fZ;'S)f;'S;=`)w<%lO)f~)zP;=`<%l)f~*USm~l~OY)}Z;'S)};'S;=`*b<%lO)}~*eP;=`<%l)}~*ml&P~qr,ez{0k!O!P/V!P!Q3g!Q![3l![!]3t!_!`0k!a!b0k!c!}4|#Q#R3t#R#S4|#T#o4|#r#s0k$h$i3g$p$q4|${$|4|%Q%R4|%W%o4|%p&a4|&b#BY4|#BZ$IS4|&/x&Et4|&Gh;'S4|;'S;=`6j?&r?Bj4|?Hw?Ic4|?Ii?JT4|?J`?L{4|~,ja!c~!c!}-o#R#S-o#T#o-o$p$q-o${$|-o%Q%R-o%W%o-o%p&a-o&b#BY-o#BZ$IS-o&/x&Et-o&Gh;'S-o;'S;=`0_?&r?Bj-o?Hw?Ic-o?Ii?JT-o?J`?L{-o~-te!d~wx/V}!O/V!Q![-o![!]0e!c!}-o#R#S-o#T#o-o$p$q-o${$|-o%Q%R-o%W%o-o%p&a-o&b#BY-o#BZ$IS-o&/x&Et-o&Gh;'S-o;'S;=`0_?&r?Bj-o?Hw?Ic-o?Ii?JT-o?J`?L{-o~/Ya!c!}-o#R#S-o#T#o-o$p$q-o${$|-o%Q%R-o%W%o-o%p&a-o&b#BY-o#BZ$IS-o&/x&Et-o&Gh;'S-o;'S;=`0_?&r?Bj-o?Hw?Ic-o?Ii?JT-o?J`?L{-o~0bP;=`<%l-o~0hP![!]/V~0na!c!}1s#R#S1s#T#o1s$p$q1s${$|1s%Q%R1s%W%o1s%p&a1s&b#BY1s#BZ$IS1s&/x&Et1s&Gh;'S1s;'S;=`3a?&r?Bj1s?Hw?Ic1s?Ii?JT1s?J`?L{1s~1xe!e~wx0k}!O0k!Q![1s![!]3Z!c!}1s#R#S1s#T#o1s$p$q1s${$|1s%Q%R1s%W%o1s%p&a1s&b#BY1s#BZ$IS1s&/x&Et1s&Gh;'S1s;'S;=`3a?&r?Bj1s?Hw?Ic1s?Ii?JT1s?J`?L{1s~3^P![!]0k~3dP;=`<%l1s~3lO!c~~3qP!c~!Q![3l~3wa!c!}4|#R#S4|#T#o4|$p$q4|${$|4|%Q%R4|%W%o4|%p&a4|&b#BY4|#BZ$IS4|&/x&Et4|&Gh;'S4|;'S;=`6j?&r?Bj4|?Hw?Ic4|?Ii?JT4|?J`?L{4|~5Re!c~wx3t}!O3t!Q![4|![!]6d!c!}4|#R#S4|#T#o4|$p$q4|${$|4|%Q%R4|%W%o4|%p&a4|&b#BY4|#BZ$IS4|&/x&Et4|&Gh;'S4|;'S;=`6j?&r?Bj4|?Hw?Ic4|?Ii?JT4|?J`?L{4|~6gP![!]3t~6mP;=`<%l4|~6uj%RPqr/Vuv8gz{0k!O!P/V![!]3t!_!`8t!a!b0k!c!}4|#Q#R3t#R#S4|#T#o4|#r#s0k$p$q4|${$|4|%Q%R4|%W%o4|%p&a4|&b#BY4|#BZ$IS4|&/x&Et4|&Gh;'S4|;'S;=`6j?&r?Bj4|?Hw?Ic4|?Ii?JT4|?J`?L{4|P8lP%RP!_!`8oP8tO%RP~8ya%RP!c!}1s#R#S1s#T#o1s$p$q1s${$|1s%Q%R1s%W%o1s%p&a1s&b#BY1s#BZ$IS1s&/x&Et1s&Gh;'S1s;'S;=`3a?&r?Bj1s?Hw?Ic1s?Ii?JT1s?J`?L{1s~:Tj%RPqr/Vvw8gz{0k!O!P/V![!]3t!_!`8t!a!b0k!c!}4|#Q#R3t#R#S4|#T#o4|#r#s0k$p$q4|${$|4|%Q%R4|%W%o4|%p&a4|&b#BY4|#BZ$IS4|&/x&Et4|&Gh;'S4|;'S;=`6j?&r?Bj4|?Hw?Ic4|?Ii?JT4|?J`?L{4|~;zOr~~<POq~~<UO%S~~<ZQ%U~!O!P<a!_!`8oP<fQ%RP!O!P<l#Q#R8oP<qP%RP#Q#R8o~<y^!s~!O!P=u!Q![?T!d!e?r!f!g@^!g!h>a!q!r@r!z!{AW#R#S?l#U#V?r#W#X@^#X#Y>a#]#^?O#c#d@r#l#mAW~=xP!Q![={~>QT!s~!Q![={!g!h>a#R#S=u#X#Y>a#]#^?O~>dR{|>m}!O>m!Q![>s~>pP!Q![>s~>xQ!s~!Q![>s#]#^?O~?TO!s~~?YU!s~!O!P=u!Q![?T!g!h>a#R#S?l#X#Y>a#]#^?O~?oP!Q![?T~?uR!Q!R@O!R!S@O#R#S@O~@TR!s~!Q!R@O!R!S@O#R#S@O~@aQ!Q![@g#R#S@g~@lQ!s~!Q![@g#R#S@g~@uQ!Q!Y@{#R#S@{~AQQ!s~!Q!Y@{#R#S@{~AZS!Q![Ag!c!iAg#R#SAg#T#ZAg~AlS!s~!Q![Ag!c!iAg#R#SAg#T#ZAg~A}e%T~qrC`!Q![F[![!]Gc!_!`8o!c!}Dh#R#SDh#T#oDh$p$qDh${$|Dh%Q%RDh%W%oDh%p&aDh&b#BYDh#BZ$ISDh&/x&EtDh&Gh;'SDh;'S;=`FU?&r?BjDh?Hw?IcDh?Ii?JTDh?J`?L{Dh~Cca!c!}Dh#R#SDh#T#oDh$p$qDh${$|Dh%Q%RDh%W%oDh%p&aDh&b#BYDh#BZ$ISDh&/x&EtDh&Gh;'SDh;'S;=`FU?&r?BjDh?Hw?IcDh?Ii?JTDh?J`?L{Dh~Dme!w~wxC`}!OC`!Q![Dh![!]FO!c!}Dh#R#SDh#T#oDh$p$qDh${$|Dh%Q%RDh%W%oDh%p&aDh&b#BYDh#BZ$ISDh&/x&EtDh&Gh;'SDh;'S;=`FU?&r?BjDh?Hw?IcDh?Ii?JTDh?J`?L{Dh~FRP![!]C`~FXP;=`<%lDh~F_Q!Q![F[!^!_Fe~FhT!O!PFw!Q![Fw!c!}Fw#R#SFw#T#oFw~FzU!O!PFw!Q![Fw!`!aG^!c!}Fw#R#SFw#T#oFw~GcOp~PGfP![!]GiPGlP!_!`8o~GtO!R~~Gyi&P~qr/Vz{0k!O!P/V![!]3t!_!`0k!a!b0k!c!}4|#Q#R3t#R#S4|#T#o4|#r#s0k$p$q4|${$|4|%Q%R4|%W%o4|%p&a4|&b#BY4|#BZ$IS4|&/x&Et4|&Gh;'S4|;'S;=`6j?&r?Bj4|?Hw?Ic4|?Ii?JT4|?J`?L{4|~Ime%}~wxKO}!OKO!Q![Ih![!]L^!c!}Ih#R#SIh#T#oIh$p$qIh${$|Ih%Q%RIh%W%oIh%p&aIh&b#BYIh#BZ$ISIh&/x&EtIh&Gh;'SIh;'S;=`LW?&r?BjIh?Hw?IcIh?Ii?JTIh?J`?L{Ih~KRa!c!}Ih#R#SIh#T#oIh$p$qIh${$|Ih%Q%RIh%W%oIh%p&aIh&b#BYIh#BZ$ISIh&/x&EtIh&Gh;'SIh;'S;=`LW?&r?BjIh?Hw?IcIh?Ii?JTIh?J`?L{Ih~LZP;=`<%lIh~LaP![!]KO~LiOu~RLn!U%RPOq!!Qqr!!Vrz!!Qz{!!V{|!!V|}!!Q}!O!!V!O!P!!Q!P!Q!!V!Q!^!!Q!^!_!!V!_!`!!V!`!a!!V!a!b!!V!b#O!!Q#O#P!!V#P#Q!!Q#Q#R!!V#R#p!!Q#p#q!!V#q#r!!Q#r#s!!V#s$g!!Q$g$p!!V$p$q!!Q$q$r!!V$r$s!!V$s$t!!Q$t$x!!V$x$z!!Q$z${!!V${$|!!Q$|%P!!V%P%R!!Q%R%S!!V%S%V!!Q%V%W!!V%W%o!!Q%o%p!!V%p&a!!Q&a&b!!V&b$Id!!Q$Id$Il!!V$Il$It!!Q$It$I|!!V$I|$JU!!Q$JU$KV!!V$KV%#t!!Q%#t&/x!!V&/x;'S!!Q;'S;=`!$R;=`O!!QQ!!VO!bQR!!^k!bQ%RPqr&}z{&}{|&}}!O&}!P!Q&}!^!_&}!_!`&}!`!a&}!a!b&}#O#P&}#Q#R&}#p#q&}#r#s&}$g$p&}$q$r&}$r$s&}$t$x&}$z${&}$|%P&}%R%S&}%V%W&}%o%p&}&a&b&}$Id$Il&}$It$I|&}$JU$KV&}%#t&/x&}Q!$WP!bQ;=`<%l!!Q~!$`Ot~~!$ee%z~wx!%v}!O!%v!Q![!$`![!]!'U!c!}!$`#R#S!$`#T#o!$`$p$q!$`${$|!$`%Q%R!$`%W%o!$`%p&a!$`&b#BY!$`#BZ$IS!$`&/x&Et!$`&Gh;'S!$`;'S;=`!'O?&r?Bj!$`?Hw?Ic!$`?Ii?JT!$`?J`?L{!$`~!%ya!c!}!$`#R#S!$`#T#o!$`$p$q!$`${$|!$`%Q%R!$`%W%o!$`%p&a!$`&b#BY!$`#BZ$IS!$`&/x&Et!$`&Gh;'S!$`;'S;=`!'O?&r?Bj!$`?Hw?Ic!$`?Ii?JT!$`?J`?L{!$`~!'RP;=`<%l!$`~!'XP![!]!%v~!'aO!P~~!'fO!O~P!'kT%RP$x$y!'f$y$z!'f%P%Q!'f$Kh$Ki!'f$Kl$Kt!'f",
1683
1902
  tokenizers: [smileyToken, blockComment, podToken, heredocToken, methodDotToken, nameToken, versionToken, regexToken, quoteToken, termToken, 0, 1],
1684
1903
  topRules: {"Program":[0,30],"Regex":[1,191],"Heredoc":[2,192],"StringLiteral":[3,193]},
1685
- specialized: [{term: 225, get: (value) => spec_identifier[value] || -1},{term: 228, get: (value) => spec_capIdentifier[value] || -1}],
1686
- tokenPrec: 3556
1904
+ specialized: [{term: 226, get: (value) => spec_identifier[value] || -1},{term: 229, get: (value) => spec_capIdentifier[value] || -1}],
1905
+ tokenPrec: 3559
1687
1906
  });
1688
1907
 
1689
1908
  // The keywords of the grammar, with the tag each is highlighted with.
@@ -1812,8 +2031,8 @@ class Gatherer {
1812
2031
  this.declaration(child);
1813
2032
  else if (child.firstChild)
1814
2033
  this.content(child);
1815
- // The name of a constant with a sigil is a variable after the
1816
- // declaration node: constant $LIMIT = 3
2034
+ // A constant that is declared with a backslash has its name after
2035
+ // the declaration node: constant \limit = 3
1817
2036
  declaring = name == "ConstantDeclaration" && child.lastChild.name == "constant";
1818
2037
  }
1819
2038
  }
@@ -2380,7 +2599,7 @@ const baseLanguage = LRLanguage.define({
2380
2599
  Parens: delimitedIndent({ closing: ")" }),
2381
2600
  Brackets: delimitedIndent({ closing: "]" }),
2382
2601
  // The lines of these are text, which keeps its indentation.
2383
- "StringLiteral Heredoc Pod BlockComment": () => null
2602
+ "StringLiteral Heredoc Pod BlockComment DocComment": () => null
2384
2603
  }),
2385
2604
  foldNodeProp.add({
2386
2605
  "Block Parens Brackets": foldInside,