codemirror-lang-raku 0.2.0 → 0.4.0

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
@@ -5,13 +5,13 @@ import { tags, styleTags } from '@lezer/highlight';
5
5
  import { Prec, EditorState } from '@codemirror/state';
6
6
 
7
7
  // This file was generated by lezer-generator. You probably shouldn't edit it.
8
- const smiley = 199,
9
- noSmiley = 200,
8
+ const smiley = 201,
9
+ noSmiley = 202,
10
10
  BlockComment = 1,
11
11
  podStart = 2,
12
- podEnd = 201,
12
+ podEnd = 203,
13
13
  podEndDirective = 3,
14
- podText = 202,
14
+ podText = 204,
15
15
  PodDirective = 4,
16
16
  PodHeading = 5,
17
17
  PodStrong = 6,
@@ -21,17 +21,18 @@ const smiley = 199,
21
21
  PodFormat = 10,
22
22
  rawHeredoc = 11,
23
23
  interpolatingHeredoc = 12,
24
- heredocStart = 203,
24
+ heredocStart = 205,
25
25
  methodDot = 13,
26
26
  MethodName = 14,
27
- declaredName = 204,
28
- declaredMethodName = 205,
27
+ declaredName = 206,
28
+ declaredMethodName = 207,
29
+ declaredVariable = 208,
29
30
  Version = 15,
30
- regexStart = 206,
31
- regexBodyEnd = 207,
32
- regexLitOpen = 208,
33
- regexLitClose = 209,
34
- regexText = 210,
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 = 199,
39
40
  regexComment = 20,
40
41
  regexBlockComment = 21,
41
42
  regexCapture = 22,
42
- quoteContent = 211,
43
- quoteNestOpen = 212,
44
- quoteNestClose = 213,
45
- quoteEnd = 214,
46
- rawString = 215,
47
- quoteStart = 216,
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 = 217,
52
+ plainName = 220,
52
53
  wordOperator = 26,
53
- multiName = 218,
54
+ multiName = 221,
54
55
  operatorVariable = 27,
55
56
  LineComment = 28,
56
57
  DocComment = 29,
@@ -72,25 +73,26 @@ const smiley = 199,
72
73
  TypeName = 80,
73
74
  Number = 81,
74
75
  quotedString = 82,
75
- Interpolation = 83,
76
- PairKey = 84,
77
- multi = 95,
78
- proto = 96,
79
- only = 97,
80
- self = 164,
81
- True = 165,
82
- False = 166,
83
- Nil = 167,
84
- Operator = 186,
85
- Regex = 190,
86
- Heredoc = 191,
87
- StringLiteral = 192;
76
+ NestedDelimiters = 83,
77
+ Interpolation = 84,
78
+ PairKey = 85,
79
+ multi = 96,
80
+ proto = 97,
81
+ only = 98,
82
+ self = 165,
83
+ True = 166,
84
+ False = 167,
85
+ Nil = 168,
86
+ Operator = 187,
87
+ Regex = 191,
88
+ Heredoc = 192,
89
+ StringLiteral = 193;
88
90
 
89
91
  // Opening bracket -> closing bracket, for the delimiters of quotes and
90
92
  // embedded comments. Raku accepts any Unicode bracket pair; this lists
91
93
  // the ones that are likely to be typed.
92
94
  const brackets$1 = {};
93
- for (let pair of ["()", "[]", "{}", "<>", "«»", "「」", "『』", "()", "[]", "{}", "【】", "〈〉", "《》", "〔〕"])
95
+ for (let pair of ["()", "[]", "{}", "<>", "«»", "「」", "「」", "『』", "()", "[]", "{}", "【】", "〈〉", "《》", "〔〕"])
94
96
  brackets$1[pair.charCodeAt(0)] = pair.charCodeAt(1);
95
97
  function isAsciiLetter(ch) { return ch >= 97 /* Ch.a */ && ch <= 122 /* Ch.z */ || ch >= 65 /* Ch.A */ && ch <= 90 /* Ch.Z */; }
96
98
  function isDigit(ch) { return ch >= 48 /* Ch._0 */ && ch <= 57 /* Ch._9 */; }
@@ -154,9 +156,7 @@ function word(input, from, to) {
154
156
  }
155
157
  // A quote that is being read piece by piece because it interpolates.
156
158
  class Quote {
157
- constructor(parent, open, close, count,
158
- // How many nested opening delimiters are unclosed.
159
- depth, interpolates,
159
+ constructor(parent, open, close, count, interpolates,
160
160
  // Whether a backslash that does not start an escape still
161
161
  // takes the delimiter after it out of play: q:c[a \] b]
162
162
  escapes) {
@@ -164,22 +164,18 @@ class Quote {
164
164
  this.open = open;
165
165
  this.close = close;
166
166
  this.count = count;
167
- this.depth = depth;
168
167
  this.interpolates = interpolates;
169
168
  this.escapes = escapes;
170
169
  let hash = parent ? parent.hash : 7;
171
- for (let part of [open, count, depth, interpolates, escapes ? 1 : 0])
170
+ for (let part of [open, count, interpolates, escapes ? 1 : 0])
172
171
  hash = (hash * 31 + part) | 0;
173
172
  this.hash = hash;
174
173
  }
175
- withDepth(depth) {
176
- return new Quote(this.parent, this.open, this.close, this.count, depth, this.interpolates, this.escapes);
177
- }
178
174
  }
179
175
  const noHeredocs = [];
180
176
  // The quote that the text of a heredoc is read as. It has no
181
177
  // delimiters, and ends where the text does.
182
- const heredocQuote = new Quote(null, -1, -1, 1, 0, 63 /* Interpolate.All */, true);
178
+ const heredocQuote = new Quote(null, -1, -1, 1, 63 /* Interpolate.All */, true);
183
179
  // The body of a regex declaration, or the inside of a regex literal,
184
180
  // that is being read piece by piece.
185
181
  class RegexBody {
@@ -272,11 +268,11 @@ for (let term of [VariableName, AttributeName, SpecialVariable, operatorVariable
272
268
  regexText, CharacterClass, Assertion, regexQuote, regexOperator, regexComment,
273
269
  regexBlockComment, regexCapture])
274
270
  termModes.set(term, 1 /* Mode.AfterTerm */);
275
- 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,
276
272
  methodRoutineName, multiName, multiRoutineName, RegexName, EnumName, SubsetName, ConstantName])
277
273
  termModes.set(term, 2 /* Mode.AfterName */);
278
274
  // The `}` of "{...}" in a string does not take a subscript.
279
- for (let term of [quoteContent, Interpolation])
275
+ for (let term of [quoteContent, quoteNestOpen, quoteNestClose, NestedDelimiters, Interpolation])
280
276
  termModes.set(term, 0 /* Mode.Term */);
281
277
  for (let term of [multi, proto, only])
282
278
  termModes.set(term, 4 /* Mode.AfterMulti */);
@@ -286,6 +282,10 @@ function modeAfterOperator(first, second, third, after) {
286
282
  // A lone `*` is as often the whatever star as a multiplication.
287
283
  if (first == 42 /* Ch.Star */ && !isOperatorChar(second))
288
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 */;
289
289
  // Postfix increment and decrement leave the term complete.
290
290
  if ((first == 43 /* Ch.Plus */ || first == 45 /* Ch.Hyphen */) && second == first && !isOperatorChar(third) &&
291
291
  (after == 1 /* Mode.AfterTerm */ || after == 3 /* Mode.AfterBlock */))
@@ -367,15 +367,16 @@ function hasNewline(input, from, to) {
367
367
  }
368
368
  // The heredocs that are open after a reused node, of which the input is
369
369
  // at the start. As when tokens are shifted, a line break between tokens
370
- // and the text of a heredoc close the ones before them.
371
- function heredocsAfter(node, input, before) {
370
+ // and the text of a heredoc close the ones before them. `inQuote` tells
371
+ // that the node is a run of pieces of a quote.
372
+ function heredocsAfter(node, input, before, inQuote) {
372
373
  // Most reused nodes are single tokens.
373
374
  if (!node.children.length && !stringTerms.has(node.type.id) && !heredocTerms.has(node.type.id))
374
375
  return before;
375
376
  let cursor = node.cursor(), found = [], closedAt = -1;
376
377
  // Goes over the node at the cursor from its end, and tells whether
377
378
  // the heredocs before some point in it are closed.
378
- function scan() {
379
+ function scan(text = false) {
379
380
  let type = cursor.type.id, { from, to } = cursor;
380
381
  if (heredocTerms.has(type)) {
381
382
  closedAt = to;
@@ -394,7 +395,7 @@ function heredocsAfter(node, input, before) {
394
395
  if (!cursor.lastChild())
395
396
  return false;
396
397
  // Between the pieces of a string lies its text, not whitespace.
397
- let gaps = !isString;
398
+ let gaps = !isString && !text && type != NestedDelimiters;
398
399
  for (let gapEnd = to;;) {
399
400
  if (gaps && hasNewline(input, cursor.to, gapEnd)) {
400
401
  closedAt = gapEnd;
@@ -412,7 +413,8 @@ function heredocsAfter(node, input, before) {
412
413
  cursor.parent();
413
414
  return closedAt >= 0;
414
415
  }
415
- scan();
416
+ // A piece on its own, such as an Interpolation, is a named node.
417
+ scan(inQuote && node.type.isAnonymous);
416
418
  if (!found.length && closedAt < 0)
417
419
  return before;
418
420
  let after = found.filter(opener => opener.pos >= closedAt).sort((a, b) => a.pos - b.pos).map(opener => opener.heredoc);
@@ -477,17 +479,9 @@ const trackContext = new ContextTracker({
477
479
  let opening = wordListOpening(input, 0) || readOpening(input);
478
480
  if (!opening)
479
481
  return context;
480
- let quote = new Quote(context.quote, opening.open, opening.close, opening.count, 0, opening.interpolates, opening.escapes);
482
+ let quote = new Quote(context.quote, opening.open, opening.close, opening.count, opening.interpolates, opening.escapes);
481
483
  return context.withQuote(0 /* Mode.Term */, quote, withHeredocAt(context.heredocs, input, 0));
482
484
  }
483
- case quoteNestOpen:
484
- case quoteNestClose: {
485
- let quote = context.quote;
486
- if (!quote)
487
- return context;
488
- let depth = quote.depth + (term == quoteNestOpen ? 1 : -1);
489
- return context.withQuote(0 /* Mode.Term */, quote.withDepth(depth));
490
- }
491
485
  case quoteEnd:
492
486
  return context.withQuote(1 /* Mode.AfterTerm */, context.quote && context.quote.parent);
493
487
  }
@@ -511,8 +505,13 @@ const trackContext = new ContextTracker({
511
505
  return term == Identifier || term == Interpolation ? context.withMode(modeAfter(term, input, 0, context.mode))
512
506
  : context;
513
507
  },
514
- reuse(context, node, _stack, input) {
515
- context = context.withHeredocs(heredocsAfter(node, input, context.heredocs));
508
+ // A node that is reused leaves the quote and the regex of the context
509
+ // as they are: the grammar pairs the delimiters that nest in a quote
510
+ // (NestedDelimiters) and the braces of a block, so a node closes what
511
+ // it opens.
512
+ reuse(context, node, stack, input) {
513
+ let inQuote = context.quote != null && inQuoteText(stack);
514
+ context = context.withHeredocs(heredocsAfter(node, input, context.heredocs, inQuote));
516
515
  // The node's positions count from its start, where the input is.
517
516
  let last = lastToken$1(node.topNode);
518
517
  // What comes before a trailing `++` in a reused node is a term.
@@ -540,16 +539,24 @@ const blockComment = new ExternalTokenizer(input => {
540
539
  let end = embeddedCommentEnd(input, 0);
541
540
  if (!end)
542
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;
543
545
  if (end < 0)
544
546
  skipToEnd(input);
545
547
  else
546
548
  input.advance(end);
547
- input.acceptToken(BlockComment);
549
+ input.acceptToken(term);
548
550
  });
549
551
  // The offset after the embedded comment that starts at offset `at`.
550
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.
551
557
  function embeddedCommentEnd(input, at) {
552
- 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 */)
553
560
  return 0;
554
561
  let open = input.peek(at + 2), close = brackets$1[open];
555
562
  if (close == null)
@@ -557,7 +564,8 @@ function embeddedCommentEnd(input, at) {
557
564
  let count = 1;
558
565
  while (input.peek(at + 2 + count) == open)
559
566
  count++;
560
- 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;
561
569
  }
562
570
  function isBlank(ch) { return ch == 32 /* Ch.Space */ || ch == 9 /* Ch.Tab */ || ch == 13 /* Ch.Return */; }
563
571
  // The offset of the first character at or after `pos` that is not a blank.
@@ -790,7 +798,9 @@ function quoteCharOpening(open, close, at, interpolates, escapes = true) {
790
798
  // The delimiters, other than brackets, that are accepted after a quote word.
791
799
  function isQuoteDelimiter(ch) {
792
800
  return ch == 47 /* Ch.Slash */ || ch == 33 /* Ch.Bang */ || ch == 124 /* Ch.Pipe */ || ch == 126 /* Ch.Tilde */ || ch == 94 /* Ch.Caret */ ||
793
- 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;
794
804
  }
795
805
  // Reads the start of a quote at offset `at`: a quote character, or a
796
806
  // quote word (q, qq, m, s, ...) with its adverbs and its delimiter.
@@ -805,8 +815,16 @@ function readOpening(input, at = 0) {
805
815
  return quoteCharOpening(next, 0x201d, at, 63 /* Interpolate.All */);
806
816
  if (next == 0x2018 /* ‘ */)
807
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);
808
824
  if (next == 0x300c /* 「 */)
809
825
  return quoteCharOpening(next, 0x300d, at, 0, false);
826
+ if (next == 0xff62 /* 「 */)
827
+ return quoteCharOpening(next, 0xff63, at, 0, false);
810
828
  if (!isAsciiLetter(next))
811
829
  return null;
812
830
  let pos = at + 1;
@@ -885,14 +903,14 @@ function readOpening(input, at = 0) {
885
903
  // The offset after the delimiter that closes a quote whose content
886
904
  // starts at `pos`, or -1 when it is not closed.
887
905
  function rawEnd(input, pos, opening) {
888
- let { open, close, count } = opening;
906
+ let { open, close, count } = opening, other = otherClose(open);
889
907
  for (let depth = 1;;) {
890
908
  let ch = input.peek(pos);
891
909
  if (ch < 0)
892
910
  return -1;
893
911
  if (ch == 92 /* Ch.Backslash */ && opening.escapes)
894
912
  pos += 2;
895
- else if (ch == close && repeats(input, pos, close, count)) {
913
+ else if (ch == close && repeats(input, pos, close, count) || ch == other) {
896
914
  pos += count;
897
915
  if (--depth == 0)
898
916
  return pos;
@@ -905,26 +923,111 @@ function rawEnd(input, pos, opening) {
905
923
  pos++;
906
924
  }
907
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; }
908
935
  // The offset after a quoted string that starts at `pos`, or -1.
909
936
  function quotedEnd(input, pos) {
910
- let quote = input.peek(pos);
937
+ let open = input.peek(pos), close = quoteClose(open), other = otherClose(open);
911
938
  for (pos++;;) {
912
939
  let ch = input.peek(pos);
913
940
  if (ch < 0 || ch == 10 /* Ch.Newline */)
914
941
  return -1;
915
- if (ch == 92 /* Ch.Backslash */)
942
+ // Nothing is escaped in 「...」.
943
+ if (ch == 92 /* Ch.Backslash */ && open != 0xff62)
916
944
  pos += 2;
917
- else if (ch == quote)
945
+ else if (ch == close || ch == other)
918
946
  return pos + 1;
919
947
  else
920
948
  pos++;
921
949
  }
922
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
+ }
923
1025
  // The offset of the delimiter that closes a regex whose content starts
924
1026
  // at `pos`, or -1. Delimiters do not count inside quotes, character
925
- // classes, comments and code blocks.
926
- function regexEnd(input, { start: pos, open, close, count }) {
927
- 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;;) {
928
1031
  let ch = input.peek(pos);
929
1032
  if (ch < 0)
930
1033
  return -1;
@@ -940,10 +1043,25 @@ function regexEnd(input, { start: pos, open, close, count }) {
940
1043
  pos += count;
941
1044
  depth++;
942
1045
  }
943
- else if (ch == 39 /* Ch.Apostrophe */ || ch == 34 /* Ch.DoubleQuote */) {
1046
+ else if (quoteClose(ch)) {
944
1047
  let end = quotedEnd(input, pos);
945
1048
  pos = end < 0 ? pos + 1 : end;
946
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
+ }
947
1065
  else if (ch == 60 /* Ch.Less */ && (input.peek(pos + 1) == 91 /* Ch.BracketOpen */ ||
948
1066
  (input.peek(pos + 1) == 45 /* Ch.Hyphen */ || input.peek(pos + 1) == 43 /* Ch.Plus */) && input.peek(pos + 2) == 91 /* Ch.BracketOpen */)) {
949
1067
  // <[...]>, <-[...]>, and combinations: <+[a..z]-[aeiou]>
@@ -984,7 +1102,7 @@ function regexEnd(input, { start: pos, open, close, count }) {
984
1102
  pos++;
985
1103
  }
986
1104
  else if (ch == 123 /* Ch.BraceOpen */ && close != 125 /* Ch.BraceClose */) {
987
- 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);
988
1106
  pos = end < 0 ? pos + 1 : end + 1;
989
1107
  }
990
1108
  else {
@@ -992,6 +1110,21 @@ function regexEnd(input, { start: pos, open, close, count }) {
992
1110
  }
993
1111
  }
994
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
+ }
995
1128
  // The offset after a regex or substitution, given its opening, or -1.
996
1129
  function regexTokenEnd(input, opening) {
997
1130
  let end = regexEnd(input, opening);
@@ -999,8 +1132,12 @@ function regexTokenEnd(input, opening) {
999
1132
  return -1;
1000
1133
  end += opening.count;
1001
1134
  // s/a/b/ has a second part. s{a} = 'b' does not.
1002
- if (opening.kind != "regex" && opening.open == opening.close)
1003
- 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
+ }
1004
1141
  return end;
1005
1142
  }
1006
1143
  // The opening of a bare regex: /a/
@@ -1104,6 +1241,8 @@ const declarators$1 = /^(sub|method|submethod|token|rule|regex)$/;
1104
1241
  function startsDeclarator(name) {
1105
1242
  return ["sub", "method", "submethod", "token", "rule", "regex"].some(declarator => declarator.startsWith(name));
1106
1243
  }
1244
+ // What stands between the parentheses of a set operator.
1245
+ const setOperators = /^(<=?|>=?|<\+|>\+|==|[|&\-^+.]|elem|cont)$/;
1107
1246
  const operatorCategory = /^(infix|prefix|postfix|circumfix|postcircumfix|term)$/;
1108
1247
  function isWordOperator(name) {
1109
1248
  return name == "x" || name == "xx" || name == "min" || name == "max" || name == "Z" || name == "X";
@@ -1119,6 +1258,16 @@ const termToken = new ExternalTokenizer((input, stack) => {
1119
1258
  return;
1120
1259
  }
1121
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
+ }
1122
1271
  if (isIdentifierStart(next)) {
1123
1272
  // The Z, X and R meta operators: Z+, X~, R-, Z=>
1124
1273
  if (mode == 1 /* Mode.AfterTerm */ && (next == 90 /* Ch.Z */ || next == 88 /* Ch.X */ || next == 82 /* Ch.R */) &&
@@ -1161,7 +1310,25 @@ const termToken = new ExternalTokenizer((input, stack) => {
1161
1310
  // space before it, it is a variable: `my Array[Int] %h`.
1162
1311
  if (mode == 1 /* Mode.AfterTerm */ && isIdentifierStart(input.peek(1)) && !isSpace(input.peek(-1)))
1163
1312
  return input.acceptToken(wordOperator, 1);
1164
- // 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:<+>
1165
1332
  if (next == 38 /* Ch.Amp */) {
1166
1333
  let end = nameEnd(input, 1);
1167
1334
  if (end > 0 && operatorCategory.test(word(input, 1, end))) {
@@ -1234,17 +1401,25 @@ function hasPostfix(input, end) {
1234
1401
  let methodEnd = nameEnd(input, end + 1);
1235
1402
  return methodEnd > 0 && input.peek(methodEnd) == 40 /* Ch.ParenOpen */;
1236
1403
  }
1404
+ // Whether the parser is between the pieces of a quote, as opposed to
1405
+ // in the code of a block in it.
1406
+ function inQuoteText(stack) { return stack.canShift(quoteContent); }
1407
+ // Whether the parser is, in a quote, right after a variable or after a
1408
+ // subscript or a call on one: where the grammar takes a quotePostfix.
1409
+ // This is asked of the parser and not of the mode, which is not known
1410
+ // to this precision after a reused node that ends in text of the quote.
1411
+ function afterQuotedVariable(stack) { return stack.canShift(rawString); }
1237
1412
  // The pieces of a quote that interpolates.
1238
1413
  const quoteToken = new ExternalTokenizer((input, stack) => {
1239
- if (!stack.canShift(quoteEnd))
1414
+ if (!inQuoteText(stack))
1240
1415
  return;
1241
- let { quote, mode } = context(stack);
1416
+ let { quote } = context(stack);
1242
1417
  if (!quote)
1243
1418
  return;
1244
- let { open, close, count, interpolates } = quote, nests = open != close;
1419
+ let { open, close, count, interpolates } = quote, nests = open != close, other = otherClose(open);
1245
1420
  // After a variable, a subscript or a call continues the interpolation.
1246
1421
  // `[` and `(` are left to the grammar's own tokens.
1247
- if (mode == 1 /* Mode.AfterTerm */) {
1422
+ if (afterQuotedVariable(stack)) {
1248
1423
  if (input.next == 91 /* Ch.BracketOpen */ || input.next == 40 /* Ch.ParenOpen */)
1249
1424
  return;
1250
1425
  let end = subscriptEnd(input);
@@ -1259,12 +1434,13 @@ const quoteToken = new ExternalTokenizer((input, stack) => {
1259
1434
  let next = input.next;
1260
1435
  if (next < 0)
1261
1436
  break;
1262
- let atClose = next == close && repeats(input, 0, close, count);
1437
+ let atClose = next == close && repeats(input, 0, close, count) || next == other;
1263
1438
  if (atClose || nests && next == open && repeats(input, 0, open, count)) {
1264
1439
  if (input.pos > start)
1265
1440
  break;
1266
1441
  input.advance(count);
1267
- return input.acceptToken(!atClose ? quoteNestOpen : quote.depth ? quoteNestClose : quoteEnd);
1442
+ // Inside a nested pair, a closing delimiter closes that pair.
1443
+ return input.acceptToken(!atClose ? quoteNestOpen : stack.canShift(quoteNestClose) ? quoteNestClose : quoteEnd);
1268
1444
  }
1269
1445
  if (next == 92 /* Ch.Backslash */) {
1270
1446
  if (interpolates & 32 /* Interpolate.Backslash */)
@@ -1364,14 +1540,21 @@ function isRegexOperator(ch) {
1364
1540
  // When it is not closed on its line, this is the negated offset of the
1365
1541
  // end of the text that was gone over to find that out.
1366
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));
1367
1545
  for (let pos = 1, depth = 1;;) {
1368
1546
  let ch = input.peek(pos);
1369
1547
  if (ch < 0 || ch == 10 /* Ch.Newline */)
1370
1548
  return -pos;
1371
- 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 */) {
1372
1555
  pos += input.peek(pos + 1) == 10 /* Ch.Newline */ || input.peek(pos + 1) < 0 ? 1 : 2;
1373
1556
  }
1374
- else if (ch == 39 /* Ch.Apostrophe */ || ch == 34 /* Ch.DoubleQuote */) {
1557
+ else if (quoteClose(ch)) {
1375
1558
  let end = quotedEnd(input, pos);
1376
1559
  pos = end < 0 ? pos + 1 : end;
1377
1560
  }
@@ -1465,7 +1648,7 @@ const regexToken = new ExternalTokenizer((input, stack) => {
1465
1648
  skipLine(input);
1466
1649
  return input.acceptToken(regexComment);
1467
1650
  }
1468
- if (next == 39 /* Ch.Apostrophe */ || next == 34 /* Ch.DoubleQuote */) {
1651
+ if (quoteClose(next)) {
1469
1652
  let end = quotedEnd(input, 0);
1470
1653
  if (end > 0 && end <= limit)
1471
1654
  return input.acceptToken(regexQuote, end);
@@ -1531,7 +1714,7 @@ const regexToken = new ExternalTokenizer((input, stack) => {
1531
1714
  input.advance();
1532
1715
  let ch = input.next;
1533
1716
  if (ch < 0 || input.pos == literalEnd ||
1534
- 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) ||
1535
1718
  ch == 60 /* Ch.Less */ || ch == 62 /* Ch.Greater */ || ch == 171 /* Ch.GuillemetOpen */ || ch == 187 /* Ch.GuillemetClose */ ||
1536
1719
  ch == 41 /* Ch.ParenClose */ && input.peek(1) == 62 /* Ch.Greater */ ||
1537
1720
  ch == 123 /* Ch.BraceOpen */ || ch == 125 /* Ch.BraceClose */ || ch == 35 /* Ch.Hash */ || ch == 36 /* Ch.Dollar */ ||
@@ -1553,9 +1736,8 @@ const methodDotToken = new ExternalTokenizer((input, stack) => {
1553
1736
  next = input.peek(++size);
1554
1737
  if (!isIdentifierStart(next))
1555
1738
  return;
1556
- let { quote, mode } = context(stack);
1557
- if (quote && stack.canShift(quoteEnd) &&
1558
- (mode != 1 /* Mode.AfterTerm */ || input.peek(nameEnd(input, size)) != 40 /* Ch.ParenOpen */))
1739
+ if (context(stack).quote && inQuoteText(stack) &&
1740
+ (!afterQuotedVariable(stack) || input.peek(nameEnd(input, size)) != 40 /* Ch.ParenOpen */))
1559
1741
  return;
1560
1742
  input.acceptToken(methodDot, size);
1561
1743
  });
@@ -1580,6 +1762,26 @@ function categoryEnd(input, nameStart, pos) {
1580
1762
  let close = first == 60 /* Ch.Less */ ? 62 /* Ch.Greater */ : first == 171 /* Ch.GuillemetOpen */ ? 187 /* Ch.GuillemetClose */ : -1;
1581
1763
  if (close < 0)
1582
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
+ }
1583
1785
  // The two halves of a circumfix are separated by one space.
1584
1786
  let spaces = /circumfix$/.test(word(input, nameStart, pos)) ? 1 : 0;
1585
1787
  for (let i = open + 1;; i++) {
@@ -1595,8 +1797,17 @@ function categoryEnd(input, nameStart, pos) {
1595
1797
  // specialized identifiers, and specialization does not look at the
1596
1798
  // parse state, so these positions get tokens of their own.
1597
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
+ }
1598
1809
  // Only a method declaration takes a mark: `method !private`, `method ^meta`.
1599
- 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;
1600
1811
  let end = nameEnd(input, mark);
1601
1812
  if (end < 0)
1602
1813
  return;
@@ -1605,7 +1816,17 @@ const nameToken = new ExternalTokenizer((input, stack) => {
1605
1816
  input.acceptToken(MethodName, end);
1606
1817
  return;
1607
1818
  }
1819
+ let named = end;
1608
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
+ }
1609
1830
  if (!mark && stack.canShift(declaredName))
1610
1831
  input.acceptToken(declaredName, end);
1611
1832
  else if (stack.canShift(declaredMethodName))
@@ -1661,27 +1882,27 @@ const versionToken = new ExternalTokenizer((input, stack) => {
1661
1882
  });
1662
1883
 
1663
1884
  // This file was generated by lezer-generator. You probably shouldn't edit it.
1664
- const spec_identifier = {__proto__:null,class:80, role:82, grammar:84, module:86, package:88, sub:102, method:106, submethod:108, token:116, rule:118, regex:120, enum:140, subset:146, constant:152, my:170, our:172, has:174, state:176, temp:178, let:180, anon:182, augment:184, supersede:186, unit:188, multi:190, proto:192, only:194, if:196, elsif:198, else:200, unless:202, with:204, orwith:206, without:208, for:210, while:212, until:214, loop:216, repeat:218, given:220, when:222, default:224, do:226, gather:228, take:230, try:232, return:234, next:236, last:238, redo:240, proceed:242, succeed:244, react:246, whenever:248, supply:250, emit:252, start:254, use:256, need:258, import:260, require:262, no:264, is:266, does:268, of:270, returns:272, handles:274, where:276, will:278, trusts:280, hides:282, and:284, or:286, not:288, xor:290, so:292, andthen:294, orelse:296, notandthen:298, div:300, mod:302, gcd:304, lcm:306, eq:308, ne:310, lt:312, gt:314, le:316, ge:318, cmp:320, leg:322, eqv:324, but:326, self:328};
1665
- const spec_capIdentifier = {__proto__:null,True:330, False:332, Nil:334, BEGIN:336, CHECK:338, INIT:340, END:342, ENTER:344, LEAVE:346, KEEP:348, UNDO:350, FIRST:352, NEXT:354, LAST:356, PRE:358, POST:360, CATCH:362, CONTROL:364, QUIT:366, CLOSE:368, DOC:370};
1885
+ const spec_identifier = {__proto__:null,class:80, role:82, grammar:84, module:86, package:88, sub:102, method:106, submethod:108, token:116, rule:118, regex:120, enum:140, subset:146, constant:152, my:172, our:174, has:176, state:178, temp:180, let:182, anon:184, augment:186, supersede:188, unit:190, multi:192, proto:194, only:196, if:198, elsif:200, else:202, unless:204, with:206, orwith:208, without:210, for:212, while:214, until:216, loop:218, repeat:220, given:222, when:224, default:226, do:228, gather:230, take:232, try:234, return:236, next:238, last:240, redo:242, proceed:244, succeed:246, react:248, whenever:250, supply:252, emit:254, start:256, use:258, need:260, import:262, require:264, no:266, is:268, does:270, of:272, returns:274, handles:276, where:278, will:280, trusts:282, hides:284, and:286, or:288, not:290, xor:292, so:294, andthen:296, orelse:298, notandthen:300, div:302, mod:304, gcd:306, lcm:308, eq:310, ne:312, lt:314, gt:316, le:318, ge:320, cmp:322, leg:324, eqv:326, but:328, self:330};
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};
1666
1887
  const parser$1 = LRParser.deserialize({
1667
1888
  version: 14,
1668
- states: ".WQfQDdOOO*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'#EQO7SO!0jO'#EQOOQ.W'#HS'#HSOOQ.W'#HR'#HROOQ.W'#Ge'#GeQfQDdOOO7ZQEUO'#DTO7bQEUO'#D`O7iQEUO'#D`OARQEUO'#DgOA]QEUO'#DsOKQQEUO'#DvO!&uQEUO'#DyOOQ.W'#HZ'#HZO!0jO!!^OOO!1hO!0jOOOOOS'#Gf'#GfO!1oOSO,59gOOQ.W,59g,59gOOQ.W,59k,59kO!1yQDdO,59kOOQ.W,59n,59nO!2QQDdO,59nOOQ.W,59x,59xO!2XQDdO,59xOOQ.W'#Gg'#GgO!;qQDdO'#HUOOQ.W'#HU'#HUOOQ.W,59z,59zOOQ.W,5:h,5:hOOQ.W,5:j,5:jO!;xQDdO'#EROOO2Q'#HX'#HXOOO2Q'#Gi'#GiO!<PO!0jO,5:lOOQ.W,5:l,5:lOOQ.W-E:c-E:cOOQ.W'#DZ'#DZOOQ.W,59o,59oO,fQDdO,59oOOQ.W'#Db'#DbO,fQDdO,59zOOQ.W'#De'#DeO!<WQDdO,5:ROOQ.W'#Dk'#DkO!<_Q:[O'#DlOOQ.W,5:R,5:RO!<WQDdO,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!<gQDdO'#DrOOO#t'#HV'#HVOOO#t'#Gh'#GhO!0jO!!^OOQOOOOOO!1hO!0jOOOOOS-E:d-E:dOOQ.W1G/R1G/ROOQ.W1G/V1G/VOOQ.W1G/Y1G/YOOQ.W1G/d1G/dOOQ.W-E:e-E:eOOQ.W,5=p,5=pOOO2Q,5:m,5:mO!<nQDdO,5:mOOO2Q-E:g-E:gOOQ.W1G0W1G0WOOQ.W1G/Z1G/ZOOQ.W1G/f1G/fOOQ.W1G/m1G/mO!=pO!!^O'#DmOOQ.W,5:W,5:WO!=wQ7fO,5:WO!=|QDdO1G/mOOO#t,5:^,5:^O!>TQDdO,5:^OOO#t-E:f-E:fOOO2Q1G0X1G0XO!>[O!!^O,5:XOOQY,5:X,5:XOOQ.W1G/r1G/rOOQ.W7+%X7+%XOOO#t1G/x1G/xOOQY1G/s1G/s",
1669
- stateData: "!>o~O%tOSlOSmOSPOSZOS[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!v_O!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$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%Q_O%R_O%S_O%T_O%o]O%p^O%qZO%rWO%wZO%z[O%|_O~O%hkO~O%clO~O%plO~OSmOTmOUmOVmOWmOXmOYmO%bmO~ORoO%aoO~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!v_O!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$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%Q_O%R_O%S_O%T_O%o]O%p^O%qZO%rWO%wZO%z[O%|_O~O^zO~O%_{O%`{O~O]YOrTOuUO!P|O!b}O!c}O!d}O!e}O%k}O%l}O%m}O%o}O%|}O~O%n!QO~P6XO%d!SO~P,fO%d!VO~P,fO%e!XO~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!v_O!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$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%Q_O%R_O%S_O%T_O%o]O%p^O%qZO%rWO%wZO%z[O%|_O~O!R!]O%d!ZO~P7pO%d!_OQ!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!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$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%^!gX%o!gX%p!gX%q!gX%r!gX%w!gX%z!gX%|!gXq!gXt!gX!O!gX~O%d!aOQ!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!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$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%^!jX%o!jX%p!jX%q!jX%r!jX%w!jX%z!jX%|!jXq!jXt!jX!O!jX~O%d!cOQ!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!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$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%^!mX%o!mX%p!mX%q!mX%r!mX%w!mX%z!mX%|!mXq!mXt!mX!O!mX~O`!fOa!fOb!fOc!fOd!fOe!fOf!fO!P!eO!b!fO!c!fO!d!fO!e!fO%i!iO%j!fO~O%n!iO~P6XOR!lO%a!lO~P+ZOq!mO~PfOt!nO~PfO!O!oO~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!v_O!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$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%Q_O%R_O%S_O%T_O%o]O%p^O%qZO%rWO%wZO%z[O%|_O~O!R!qO~P!2`O!O!rO~PfO%n!uO~P6XO!R!xO~P7pO!O!zO%f!yO~O!O!}O~PfO!O#QO~PfO`!fOa!fOb!fOc!fOd!fOe!fOf!fO!P!eO!b!fO!c!fO!d!fO!e!fO%j!fO~O%g#SO~P!<uO!O#TO~O!R#UO~P7pO!O#VO~PfO%g#WO~P!<uOml!d!e!cp!v%Q%|%S%T~",
1670
- goto: ",X&OPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPP&PPPP&jPP&j&PPPPPP'ZPP'^P&PP'wPP'z'}&PPPP(h(k(uPPPP(x&PP)O&PP)R&PP)U&j&P&PP&P'TPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPP)X)s)y*^*hPPPPPPPPPPPPPPPPPPPPPPP*r+QP+m+{P,RP&P!P_OTUVXbcdefqsuw|!U!W!Y!^!e!s!|#O!O_OTUVXbcdefqsuw|!U!W!Y!^!e!s!|#OX}^l!P!jR!Uch`OTUVbqsu|!e!s#O[xXcde!U!WR!qwR!WdR!We!PXOTUVXbcdefqsuw|!U!W!Y!^!e!s!|#OR!^fQ!]fS!x!Y!^R#U!|R!{![X!fk!h!y#RR!`gR!bhR!diQbOQqTQsUQuV[!Rbqsu!s#OQ!s|R#O!eQnSR!kn[wXcde!U!WQ!YfU!pw!Y!|R!|!^Q!hkS#P!h#RR#R!yQ!P^Q!jlT!t!P!jiaOTUVbqsu|!e!s#Oh`OTUVbqsu|!e!s#OgvXcdefw!U!W!Y!^!|UyXdeQ!TcQ!v!UR!w!WX!gk!h!y#RX!O^l!P!j",
1671
- 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 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",
1672
- maxTerm: 229,
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",
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",
1893
+ maxTerm: 233,
1673
1894
  context: trackContext,
1674
1895
  nodeProps: [
1675
1896
  ["openedBy", 33,"(",36,"[",46,"{"],
1676
1897
  ["closedBy", 34,")",37,"]",47,"}"]
1677
1898
  ],
1678
1899
  skippedNodes: [0,1,11,12,28,29],
1679
- repeatNodeCount: 5,
1680
- 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%t~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%QPqr%{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%|~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%QPqr-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%QP!_!`7QP7VO%QP~7[a%QP!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%QPqr-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%R~~:lQ%T~!O!P:r!_!`7QP:wQ%QP!O!P:}#Q#R7QP;SP%QP#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%S~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!v~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%|~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%z~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%QPOqMdqrMirzMdz{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%QPqr%{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%w~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~",
1900
+ repeatNodeCount: 6,
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",
1681
1902
  tokenizers: [smileyToken, blockComment, podToken, heredocToken, methodDotToken, nameToken, versionToken, regexToken, quoteToken, termToken, 0, 1],
1682
- topRules: {"Program":[0,30],"Regex":[1,190],"Heredoc":[2,191],"StringLiteral":[3,192]},
1683
- specialized: [{term: 223, get: (value) => spec_identifier[value] || -1},{term: 226, get: (value) => spec_capIdentifier[value] || -1}],
1684
- tokenPrec: 3469
1903
+ topRules: {"Program":[0,30],"Regex":[1,191],"Heredoc":[2,192],"StringLiteral":[3,193]},
1904
+ specialized: [{term: 226, get: (value) => spec_identifier[value] || -1},{term: 229, get: (value) => spec_capIdentifier[value] || -1}],
1905
+ tokenPrec: 3559
1685
1906
  });
1686
1907
 
1687
1908
  // The keywords of the grammar, with the tag each is highlighted with.
@@ -1810,8 +2031,8 @@ class Gatherer {
1810
2031
  this.declaration(child);
1811
2032
  else if (child.firstChild)
1812
2033
  this.content(child);
1813
- // The name of a constant with a sigil is a variable after the
1814
- // 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
1815
2036
  declaring = name == "ConstantDeclaration" && child.lastChild.name == "constant";
1816
2037
  }
1817
2038
  }
@@ -2378,7 +2599,7 @@ const baseLanguage = LRLanguage.define({
2378
2599
  Parens: delimitedIndent({ closing: ")" }),
2379
2600
  Brackets: delimitedIndent({ closing: "]" }),
2380
2601
  // The lines of these are text, which keeps its indentation.
2381
- "StringLiteral Heredoc Pod BlockComment": () => null
2602
+ "StringLiteral Heredoc Pod BlockComment DocComment": () => null
2382
2603
  }),
2383
2604
  foldNodeProp.add({
2384
2605
  "Block Parens Brackets": foldInside,
@@ -2388,7 +2609,10 @@ const baseLanguage = LRLanguage.define({
2388
2609
  // A heredoc starts with the line break before its first line.
2389
2610
  Heredoc(tree) { return { from: tree.from, to: tree.to }; }
2390
2611
  }),
2391
- styleTags(Object.assign(Object.assign({}, keywordTags), { "True False": tags.bool, Nil: tags.null, Identifier: tags.function(tags.variableName), TypeName: tags.typeName, PackageName: tags.definition(tags.className), "EnumName SubsetName": tags.definition(tags.typeName), ConstantName: tags.definition(tags.constant(tags.variableName)), "RoutineName RegexName": tags.function(tags.definition(tags.variableName)), MethodName: tags.function(tags.propertyName), VariableName: tags.variableName, AttributeName: tags.propertyName, SpecialVariable: tags.special(tags.variableName), PairKey: tags.attributeName, Number: tags.number, Version: tags.literal, "StringLiteral Heredoc": tags.string, Regex: tags.regexp, CharacterClass: tags.character, Assertion: tags.function(tags.variableName), "Pod PodFormat": tags.docComment, PodDirective: tags.meta,
2612
+ styleTags(Object.assign(Object.assign({}, keywordTags), { "True False": tags.bool, Nil: tags.null, Identifier: tags.function(tags.variableName), TypeName: tags.typeName, PackageName: tags.definition(tags.className), "EnumName SubsetName": tags.definition(tags.typeName), ConstantName: tags.definition(tags.constant(tags.variableName)), "RoutineName RegexName": tags.function(tags.definition(tags.variableName)), MethodName: tags.function(tags.propertyName), VariableName: tags.variableName, AttributeName: tags.propertyName, SpecialVariable: tags.special(tags.variableName), PairKey: tags.attributeName, Number: tags.number, Version: tags.literal,
2613
+ // A pair of delimiters in a quote is text of it, and a tag
2614
+ // does not reach the text in a child node.
2615
+ "StringLiteral Heredoc NestedDelimiters": tags.string, Regex: tags.regexp, CharacterClass: tags.character, Assertion: tags.function(tags.variableName), "Pod PodFormat": tags.docComment, PodDirective: tags.meta,
2392
2616
  // These are still part of a comment, and are styled as one where
2393
2617
  // a theme has no style for the second tag.
2394
2618
  PodHeading: [tags.docComment, tags.heading], PodStrong: [tags.docComment, tags.strong], PodEmphasis: [tags.docComment, tags.emphasis], PodCode: [tags.docComment, tags.monospace], PodLink: [tags.docComment, tags.link], Escape: tags.escape, "Interpolation/{ Interpolation/}": tags.special(tags.brace), LineComment: tags.lineComment, BlockComment: tags.blockComment, DocComment: tags.docComment, Operator: tags.operator, ".": tags.derefOperator, ", ;": tags.separator, ":": tags.punctuation, "( )": tags.paren, "[ ]": tags.squareBracket, "{ }": tags.brace }))