From fca3fc0566a202b8ed772cb1c6709f60a7bbf21e Mon Sep 17 00:00:00 2001 From: aboyko Date: Tue, 10 Sep 2024 22:00:20 -0400 Subject: [PATCH] Property place holder support inside SPEL --- .../commons/jpql/generate-parsers.sh | 1 + .../jpql/grammars/PropertyPlaceHolder.g4 | 74 ++ .../commons/jpql/grammars/SpelLexer.g4 | 6 +- .../commons/jpql/grammars/SpelParser.g4 | 6 + .../PropertyPlaceHolderBaseListener.java | 124 +++ .../placeholder/PropertyPlaceHolderLexer.java | 154 +++ .../PropertyPlaceHolderListener.java | 80 ++ .../PropertyPlaceHolderParser.java | 652 +++++++++++++ .../ide/vscode/parser/spel/SpelLexer.java | 915 +++++++++--------- .../ide/vscode/parser/spel/SpelParser.java | 762 ++++++++------- .../parser/spel/SpelParserBaseListener.java | 12 + .../parser/spel/SpelParserListener.java | 10 + .../ide/vscode/boot/java/SpelProblemType.java | 3 +- .../java/data/jpa/queries/AntlrUtils.java | 35 + .../data/jpa/queries/MySqlSemanticTokens.java | 20 +- .../jpa/queries/PostgreSqlSemanticTokens.java | 6 +- .../PropertyPlaceHolderSemanticTokens.java | 161 +++ .../vscode/boot/java/spel/SpelReconciler.java | 47 + .../boot/java/spel/SpelSemanticTokens.java | 30 +- .../src/main/resources/problem-types.json | 6 + ...PropertyPlaceHolderSemanticTokensTest.java | 59 ++ .../java/spel/SpelSemanticTokensTest.java | 12 + .../ValueSpelExpressionValidationTest.java | 21 +- .../vscode-spring-boot/package.json | 14 +- 24 files changed, 2385 insertions(+), 825 deletions(-) create mode 100644 headless-services/commons/jpql/grammars/PropertyPlaceHolder.g4 create mode 100644 headless-services/commons/jpql/src/main/java/org/springframework/ide/vscode/parser/placeholder/PropertyPlaceHolderBaseListener.java create mode 100644 headless-services/commons/jpql/src/main/java/org/springframework/ide/vscode/parser/placeholder/PropertyPlaceHolderLexer.java create mode 100644 headless-services/commons/jpql/src/main/java/org/springframework/ide/vscode/parser/placeholder/PropertyPlaceHolderListener.java create mode 100644 headless-services/commons/jpql/src/main/java/org/springframework/ide/vscode/parser/placeholder/PropertyPlaceHolderParser.java create mode 100644 headless-services/spring-boot-language-server/src/main/java/org/springframework/ide/vscode/boot/java/data/jpa/queries/AntlrUtils.java create mode 100644 headless-services/spring-boot-language-server/src/main/java/org/springframework/ide/vscode/boot/java/spel/PropertyPlaceHolderSemanticTokens.java create mode 100644 headless-services/spring-boot-language-server/src/test/java/org/springframework/ide/vscode/boot/java/spel/PropertyPlaceHolderSemanticTokensTest.java diff --git a/headless-services/commons/jpql/generate-parsers.sh b/headless-services/commons/jpql/generate-parsers.sh index 2ee29a5417..7db9f5286b 100755 --- a/headless-services/commons/jpql/generate-parsers.sh +++ b/headless-services/commons/jpql/generate-parsers.sh @@ -12,4 +12,5 @@ java -jar ${workdir}/antlr-${ANTLR_VERSION}.jar MySqlLexer.g4 MySqlParser.g4 -o java -jar ${workdir}/antlr-${ANTLR_VERSION}.jar SpelLexer.g4 SpelParser.g4 -o ${workdir}/src/main/java/org/springframework/ide/vscode/parser/spel -package org.springframework.ide.vscode.parser.spel java -jar ${workdir}/antlr-${ANTLR_VERSION}.jar PostgreSqlLexer.g4 PostgreSqlParser.g4 -o ${workdir}/src/main/java/org/springframework/ide/vscode/parser/postgresql -package org.springframework.ide.vscode.parser.postgresql java -jar ${workdir}/antlr-${ANTLR_VERSION}.jar CronLexer.g4 CronParser.g4 -o ${workdir}/src/main/java/org/springframework/ide/vscode/parser/cron -package org.springframework.ide.vscode.parser.cron +java -jar ${workdir}/antlr-${ANTLR_VERSION}.jar PropertyPlaceHolder.g4 -o ${workdir}/src/main/java/org/springframework/ide/vscode/parser/placeholder -package org.springframework.ide.vscode.parser.placeholder diff --git a/headless-services/commons/jpql/grammars/PropertyPlaceHolder.g4 b/headless-services/commons/jpql/grammars/PropertyPlaceHolder.g4 new file mode 100644 index 0000000000..0fc4549d96 --- /dev/null +++ b/headless-services/commons/jpql/grammars/PropertyPlaceHolder.g4 @@ -0,0 +1,74 @@ +/******************************************************************************* + * Copyright (c) 2024 Broadcom, Inc. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * https://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Broadcom, Inc. - initial API and implementation + *******************************************************************************/ + +/** + * Based on the answer to this Stack Overflow question: + * https://stackoverflow.com/questions/6132529/antlr-parsing-java-properties + */ + +grammar PropertyPlaceHolder; + +start + : line* EOF + ; + +line + : Space* keyDefaultValuePair Space* EOF + ; + +keyDefaultValuePair + : key + | key defaultValue + ; + +defaultValue + : Colon value + ; + +key + : identifier (Dot identifier)* + ; + +identifier + : Identifier+ + ; + +value + : (Identifier | Exclamation | Number | Space | Backslash Backslash | Backslash LineBreak | Equals | Colon | Dot)* + ; + +Backslash : '\\'; +Colon : ':'; +Equals : '='; +Exclamation: '!'; +Number : '#'; +Dot : '.'; + +LineBreak + : '\r'? '\n' + | '\r' + ; + +Space + : ' ' + | '\t' + | '\f' + | LineBreak + ; + +Identifier + : IdentifierChar+ + ; + +fragment IdentifierChar + : ~(' ' | ':' | '=' | '\r' | '\n' | '.') + | Backslash (Colon | Equals) + ; diff --git a/headless-services/commons/jpql/grammars/SpelLexer.g4 b/headless-services/commons/jpql/grammars/SpelLexer.g4 index dc9d89903b..7b2fd9644b 100644 --- a/headless-services/commons/jpql/grammars/SpelLexer.g4 +++ b/headless-services/commons/jpql/grammars/SpelLexer.g4 @@ -141,6 +141,10 @@ DOUBLE_QUOTED_STRING : '"' ( '""' | ~["\n] )* '"' ; +PROPERTY_PLACE_HOLDER + : '${' (.)*? '}' + ; + fragment INTEGER_TYPE_SUFFIX : ( 'L' | 'l' ); fragment HEX_DIGIT : [0-9A-Fa-f]; fragment DECIMAL_DIGIT: [0-9]; @@ -184,4 +188,4 @@ TEMPLATE_TEXT BACKTICK_IN_TEMPLATE : '`' -> type(BACKTICK), popMode - ; \ No newline at end of file + ; diff --git a/headless-services/commons/jpql/grammars/SpelParser.g4 b/headless-services/commons/jpql/grammars/SpelParser.g4 index 314bbe2a7d..f14c895f2b 100644 --- a/headless-services/commons/jpql/grammars/SpelParser.g4 +++ b/headless-services/commons/jpql/grammars/SpelParser.g4 @@ -59,6 +59,7 @@ node nonDottedNode : (LSQUARE spelExpr RSQUARE) | inputParameter + | propertyPlaceHolder ; dottedNode @@ -107,6 +108,7 @@ startNode | selection | inlineListOrMap | inputParameter + | propertyPlaceHolder ; @@ -178,3 +180,7 @@ inputParameter : (LSQUARE INTEGER_LITERAL RSQUARE) ; +propertyPlaceHolder + : PROPERTY_PLACE_HOLDER + ; + diff --git a/headless-services/commons/jpql/src/main/java/org/springframework/ide/vscode/parser/placeholder/PropertyPlaceHolderBaseListener.java b/headless-services/commons/jpql/src/main/java/org/springframework/ide/vscode/parser/placeholder/PropertyPlaceHolderBaseListener.java new file mode 100644 index 0000000000..c5f41f054b --- /dev/null +++ b/headless-services/commons/jpql/src/main/java/org/springframework/ide/vscode/parser/placeholder/PropertyPlaceHolderBaseListener.java @@ -0,0 +1,124 @@ +// Generated from PropertyPlaceHolder.g4 by ANTLR 4.13.1 +package org.springframework.ide.vscode.parser.placeholder; + +import org.antlr.v4.runtime.ParserRuleContext; +import org.antlr.v4.runtime.tree.ErrorNode; +import org.antlr.v4.runtime.tree.TerminalNode; + +/** + * This class provides an empty implementation of {@link PropertyPlaceHolderListener}, + * which can be extended to create a listener which only needs to handle a subset + * of the available methods. + */ +@SuppressWarnings("CheckReturnValue") +public class PropertyPlaceHolderBaseListener implements PropertyPlaceHolderListener { + /** + * {@inheritDoc} + * + *

The default implementation does nothing.

+ */ + @Override public void enterStart(PropertyPlaceHolderParser.StartContext ctx) { } + /** + * {@inheritDoc} + * + *

The default implementation does nothing.

+ */ + @Override public void exitStart(PropertyPlaceHolderParser.StartContext ctx) { } + /** + * {@inheritDoc} + * + *

The default implementation does nothing.

+ */ + @Override public void enterLine(PropertyPlaceHolderParser.LineContext ctx) { } + /** + * {@inheritDoc} + * + *

The default implementation does nothing.

+ */ + @Override public void exitLine(PropertyPlaceHolderParser.LineContext ctx) { } + /** + * {@inheritDoc} + * + *

The default implementation does nothing.

+ */ + @Override public void enterKeyDefaultValuePair(PropertyPlaceHolderParser.KeyDefaultValuePairContext ctx) { } + /** + * {@inheritDoc} + * + *

The default implementation does nothing.

+ */ + @Override public void exitKeyDefaultValuePair(PropertyPlaceHolderParser.KeyDefaultValuePairContext ctx) { } + /** + * {@inheritDoc} + * + *

The default implementation does nothing.

+ */ + @Override public void enterDefaultValue(PropertyPlaceHolderParser.DefaultValueContext ctx) { } + /** + * {@inheritDoc} + * + *

The default implementation does nothing.

+ */ + @Override public void exitDefaultValue(PropertyPlaceHolderParser.DefaultValueContext ctx) { } + /** + * {@inheritDoc} + * + *

The default implementation does nothing.

+ */ + @Override public void enterKey(PropertyPlaceHolderParser.KeyContext ctx) { } + /** + * {@inheritDoc} + * + *

The default implementation does nothing.

+ */ + @Override public void exitKey(PropertyPlaceHolderParser.KeyContext ctx) { } + /** + * {@inheritDoc} + * + *

The default implementation does nothing.

+ */ + @Override public void enterIdentifier(PropertyPlaceHolderParser.IdentifierContext ctx) { } + /** + * {@inheritDoc} + * + *

The default implementation does nothing.

+ */ + @Override public void exitIdentifier(PropertyPlaceHolderParser.IdentifierContext ctx) { } + /** + * {@inheritDoc} + * + *

The default implementation does nothing.

+ */ + @Override public void enterValue(PropertyPlaceHolderParser.ValueContext ctx) { } + /** + * {@inheritDoc} + * + *

The default implementation does nothing.

+ */ + @Override public void exitValue(PropertyPlaceHolderParser.ValueContext ctx) { } + + /** + * {@inheritDoc} + * + *

The default implementation does nothing.

+ */ + @Override public void enterEveryRule(ParserRuleContext ctx) { } + /** + * {@inheritDoc} + * + *

The default implementation does nothing.

+ */ + @Override public void exitEveryRule(ParserRuleContext ctx) { } + /** + * {@inheritDoc} + * + *

The default implementation does nothing.

+ */ + @Override public void visitTerminal(TerminalNode node) { } + /** + * {@inheritDoc} + * + *

The default implementation does nothing.

+ */ + @Override public void visitErrorNode(ErrorNode node) { } +} \ No newline at end of file diff --git a/headless-services/commons/jpql/src/main/java/org/springframework/ide/vscode/parser/placeholder/PropertyPlaceHolderLexer.java b/headless-services/commons/jpql/src/main/java/org/springframework/ide/vscode/parser/placeholder/PropertyPlaceHolderLexer.java new file mode 100644 index 0000000000..31f9a2b9b5 --- /dev/null +++ b/headless-services/commons/jpql/src/main/java/org/springframework/ide/vscode/parser/placeholder/PropertyPlaceHolderLexer.java @@ -0,0 +1,154 @@ +// Generated from PropertyPlaceHolder.g4 by ANTLR 4.13.1 +package org.springframework.ide.vscode.parser.placeholder; +import org.antlr.v4.runtime.Lexer; +import org.antlr.v4.runtime.CharStream; +import org.antlr.v4.runtime.Token; +import org.antlr.v4.runtime.TokenStream; +import org.antlr.v4.runtime.*; +import org.antlr.v4.runtime.atn.*; +import org.antlr.v4.runtime.dfa.DFA; +import org.antlr.v4.runtime.misc.*; + +@SuppressWarnings({"all", "warnings", "unchecked", "unused", "cast", "CheckReturnValue", "this-escape"}) +public class PropertyPlaceHolderLexer extends Lexer { + static { RuntimeMetaData.checkVersion("4.13.1", RuntimeMetaData.VERSION); } + + protected static final DFA[] _decisionToDFA; + protected static final PredictionContextCache _sharedContextCache = + new PredictionContextCache(); + public static final int + Backslash=1, Colon=2, Equals=3, Exclamation=4, Number=5, Dot=6, LineBreak=7, + Space=8, Identifier=9; + public static String[] channelNames = { + "DEFAULT_TOKEN_CHANNEL", "HIDDEN" + }; + + public static String[] modeNames = { + "DEFAULT_MODE" + }; + + private static String[] makeRuleNames() { + return new String[] { + "Backslash", "Colon", "Equals", "Exclamation", "Number", "Dot", "LineBreak", + "Space", "Identifier", "IdentifierChar" + }; + } + public static final String[] ruleNames = makeRuleNames(); + + private static String[] makeLiteralNames() { + return new String[] { + null, "'\\'", "':'", "'='", "'!'", "'#'", "'.'" + }; + } + private static final String[] _LITERAL_NAMES = makeLiteralNames(); + private static String[] makeSymbolicNames() { + return new String[] { + null, "Backslash", "Colon", "Equals", "Exclamation", "Number", "Dot", + "LineBreak", "Space", "Identifier" + }; + } + private static final String[] _SYMBOLIC_NAMES = makeSymbolicNames(); + public static final Vocabulary VOCABULARY = new VocabularyImpl(_LITERAL_NAMES, _SYMBOLIC_NAMES); + + /** + * @deprecated Use {@link #VOCABULARY} instead. + */ + @Deprecated + public static final String[] tokenNames; + static { + tokenNames = new String[_SYMBOLIC_NAMES.length]; + for (int i = 0; i < tokenNames.length; i++) { + tokenNames[i] = VOCABULARY.getLiteralName(i); + if (tokenNames[i] == null) { + tokenNames[i] = VOCABULARY.getSymbolicName(i); + } + + if (tokenNames[i] == null) { + tokenNames[i] = ""; + } + } + } + + @Override + @Deprecated + public String[] getTokenNames() { + return tokenNames; + } + + @Override + + public Vocabulary getVocabulary() { + return VOCABULARY; + } + + + public PropertyPlaceHolderLexer(CharStream input) { + super(input); + _interp = new LexerATNSimulator(this,_ATN,_decisionToDFA,_sharedContextCache); + } + + @Override + public String getGrammarFileName() { return "PropertyPlaceHolder.g4"; } + + @Override + public String[] getRuleNames() { return ruleNames; } + + @Override + public String getSerializedATN() { return _serializedATN; } + + @Override + public String[] getChannelNames() { return channelNames; } + + @Override + public String[] getModeNames() { return modeNames; } + + @Override + public ATN getATN() { return _ATN; } + + public static final String _serializedATN = + "\u0004\u0000\t9\u0006\uffff\uffff\u0002\u0000\u0007\u0000\u0002\u0001"+ + "\u0007\u0001\u0002\u0002\u0007\u0002\u0002\u0003\u0007\u0003\u0002\u0004"+ + "\u0007\u0004\u0002\u0005\u0007\u0005\u0002\u0006\u0007\u0006\u0002\u0007"+ + "\u0007\u0007\u0002\b\u0007\b\u0002\t\u0007\t\u0001\u0000\u0001\u0000\u0001"+ + "\u0001\u0001\u0001\u0001\u0002\u0001\u0002\u0001\u0003\u0001\u0003\u0001"+ + "\u0004\u0001\u0004\u0001\u0005\u0001\u0005\u0001\u0006\u0003\u0006#\b"+ + "\u0006\u0001\u0006\u0001\u0006\u0003\u0006\'\b\u0006\u0001\u0007\u0001"+ + "\u0007\u0003\u0007+\b\u0007\u0001\b\u0004\b.\b\b\u000b\b\f\b/\u0001\t"+ + "\u0001\t\u0001\t\u0001\t\u0003\t6\b\t\u0003\t8\b\t\u0000\u0000\n\u0001"+ + "\u0001\u0003\u0002\u0005\u0003\u0007\u0004\t\u0005\u000b\u0006\r\u0007"+ + "\u000f\b\u0011\t\u0013\u0000\u0001\u0000\u0002\u0003\u0000\t\t\f\f \u0006"+ + "\u0000\n\n\r\r ..::===\u0000\u0001\u0001\u0000\u0000\u0000\u0000\u0003"+ + "\u0001\u0000\u0000\u0000\u0000\u0005\u0001\u0000\u0000\u0000\u0000\u0007"+ + "\u0001\u0000\u0000\u0000\u0000\t\u0001\u0000\u0000\u0000\u0000\u000b\u0001"+ + "\u0000\u0000\u0000\u0000\r\u0001\u0000\u0000\u0000\u0000\u000f\u0001\u0000"+ + "\u0000\u0000\u0000\u0011\u0001\u0000\u0000\u0000\u0001\u0015\u0001\u0000"+ + "\u0000\u0000\u0003\u0017\u0001\u0000\u0000\u0000\u0005\u0019\u0001\u0000"+ + "\u0000\u0000\u0007\u001b\u0001\u0000\u0000\u0000\t\u001d\u0001\u0000\u0000"+ + "\u0000\u000b\u001f\u0001\u0000\u0000\u0000\r&\u0001\u0000\u0000\u0000"+ + "\u000f*\u0001\u0000\u0000\u0000\u0011-\u0001\u0000\u0000\u0000\u00137"+ + "\u0001\u0000\u0000\u0000\u0015\u0016\u0005\\\u0000\u0000\u0016\u0002\u0001"+ + "\u0000\u0000\u0000\u0017\u0018\u0005:\u0000\u0000\u0018\u0004\u0001\u0000"+ + "\u0000\u0000\u0019\u001a\u0005=\u0000\u0000\u001a\u0006\u0001\u0000\u0000"+ + "\u0000\u001b\u001c\u0005!\u0000\u0000\u001c\b\u0001\u0000\u0000\u0000"+ + "\u001d\u001e\u0005#\u0000\u0000\u001e\n\u0001\u0000\u0000\u0000\u001f"+ + " \u0005.\u0000\u0000 \f\u0001\u0000\u0000\u0000!#\u0005\r\u0000\u0000"+ + "\"!\u0001\u0000\u0000\u0000\"#\u0001\u0000\u0000\u0000#$\u0001\u0000\u0000"+ + "\u0000$\'\u0005\n\u0000\u0000%\'\u0005\r\u0000\u0000&\"\u0001\u0000\u0000"+ + "\u0000&%\u0001\u0000\u0000\u0000\'\u000e\u0001\u0000\u0000\u0000(+\u0007"+ + "\u0000\u0000\u0000)+\u0003\r\u0006\u0000*(\u0001\u0000\u0000\u0000*)\u0001"+ + "\u0000\u0000\u0000+\u0010\u0001\u0000\u0000\u0000,.\u0003\u0013\t\u0000"+ + "-,\u0001\u0000\u0000\u0000./\u0001\u0000\u0000\u0000/-\u0001\u0000\u0000"+ + "\u0000/0\u0001\u0000\u0000\u00000\u0012\u0001\u0000\u0000\u000018\b\u0001"+ + "\u0000\u000025\u0003\u0001\u0000\u000036\u0003\u0003\u0001\u000046\u0003"+ + "\u0005\u0002\u000053\u0001\u0000\u0000\u000054\u0001\u0000\u0000\u0000"+ + "68\u0001\u0000\u0000\u000071\u0001\u0000\u0000\u000072\u0001\u0000\u0000"+ + "\u00008\u0014\u0001\u0000\u0000\u0000\u0007\u0000\"&*/57\u0000"; + public static final ATN _ATN = + new ATNDeserializer().deserialize(_serializedATN.toCharArray()); + static { + _decisionToDFA = new DFA[_ATN.getNumberOfDecisions()]; + for (int i = 0; i < _ATN.getNumberOfDecisions(); i++) { + _decisionToDFA[i] = new DFA(_ATN.getDecisionState(i), i); + } + } +} \ No newline at end of file diff --git a/headless-services/commons/jpql/src/main/java/org/springframework/ide/vscode/parser/placeholder/PropertyPlaceHolderListener.java b/headless-services/commons/jpql/src/main/java/org/springframework/ide/vscode/parser/placeholder/PropertyPlaceHolderListener.java new file mode 100644 index 0000000000..07ef7f4173 --- /dev/null +++ b/headless-services/commons/jpql/src/main/java/org/springframework/ide/vscode/parser/placeholder/PropertyPlaceHolderListener.java @@ -0,0 +1,80 @@ +// Generated from PropertyPlaceHolder.g4 by ANTLR 4.13.1 +package org.springframework.ide.vscode.parser.placeholder; +import org.antlr.v4.runtime.tree.ParseTreeListener; + +/** + * This interface defines a complete listener for a parse tree produced by + * {@link PropertyPlaceHolderParser}. + */ +public interface PropertyPlaceHolderListener extends ParseTreeListener { + /** + * Enter a parse tree produced by {@link PropertyPlaceHolderParser#start}. + * @param ctx the parse tree + */ + void enterStart(PropertyPlaceHolderParser.StartContext ctx); + /** + * Exit a parse tree produced by {@link PropertyPlaceHolderParser#start}. + * @param ctx the parse tree + */ + void exitStart(PropertyPlaceHolderParser.StartContext ctx); + /** + * Enter a parse tree produced by {@link PropertyPlaceHolderParser#line}. + * @param ctx the parse tree + */ + void enterLine(PropertyPlaceHolderParser.LineContext ctx); + /** + * Exit a parse tree produced by {@link PropertyPlaceHolderParser#line}. + * @param ctx the parse tree + */ + void exitLine(PropertyPlaceHolderParser.LineContext ctx); + /** + * Enter a parse tree produced by {@link PropertyPlaceHolderParser#keyDefaultValuePair}. + * @param ctx the parse tree + */ + void enterKeyDefaultValuePair(PropertyPlaceHolderParser.KeyDefaultValuePairContext ctx); + /** + * Exit a parse tree produced by {@link PropertyPlaceHolderParser#keyDefaultValuePair}. + * @param ctx the parse tree + */ + void exitKeyDefaultValuePair(PropertyPlaceHolderParser.KeyDefaultValuePairContext ctx); + /** + * Enter a parse tree produced by {@link PropertyPlaceHolderParser#defaultValue}. + * @param ctx the parse tree + */ + void enterDefaultValue(PropertyPlaceHolderParser.DefaultValueContext ctx); + /** + * Exit a parse tree produced by {@link PropertyPlaceHolderParser#defaultValue}. + * @param ctx the parse tree + */ + void exitDefaultValue(PropertyPlaceHolderParser.DefaultValueContext ctx); + /** + * Enter a parse tree produced by {@link PropertyPlaceHolderParser#key}. + * @param ctx the parse tree + */ + void enterKey(PropertyPlaceHolderParser.KeyContext ctx); + /** + * Exit a parse tree produced by {@link PropertyPlaceHolderParser#key}. + * @param ctx the parse tree + */ + void exitKey(PropertyPlaceHolderParser.KeyContext ctx); + /** + * Enter a parse tree produced by {@link PropertyPlaceHolderParser#identifier}. + * @param ctx the parse tree + */ + void enterIdentifier(PropertyPlaceHolderParser.IdentifierContext ctx); + /** + * Exit a parse tree produced by {@link PropertyPlaceHolderParser#identifier}. + * @param ctx the parse tree + */ + void exitIdentifier(PropertyPlaceHolderParser.IdentifierContext ctx); + /** + * Enter a parse tree produced by {@link PropertyPlaceHolderParser#value}. + * @param ctx the parse tree + */ + void enterValue(PropertyPlaceHolderParser.ValueContext ctx); + /** + * Exit a parse tree produced by {@link PropertyPlaceHolderParser#value}. + * @param ctx the parse tree + */ + void exitValue(PropertyPlaceHolderParser.ValueContext ctx); +} \ No newline at end of file diff --git a/headless-services/commons/jpql/src/main/java/org/springframework/ide/vscode/parser/placeholder/PropertyPlaceHolderParser.java b/headless-services/commons/jpql/src/main/java/org/springframework/ide/vscode/parser/placeholder/PropertyPlaceHolderParser.java new file mode 100644 index 0000000000..f2fccb495b --- /dev/null +++ b/headless-services/commons/jpql/src/main/java/org/springframework/ide/vscode/parser/placeholder/PropertyPlaceHolderParser.java @@ -0,0 +1,652 @@ +// Generated from PropertyPlaceHolder.g4 by ANTLR 4.13.1 +package org.springframework.ide.vscode.parser.placeholder; +import org.antlr.v4.runtime.atn.*; +import org.antlr.v4.runtime.dfa.DFA; +import org.antlr.v4.runtime.*; +import org.antlr.v4.runtime.misc.*; +import org.antlr.v4.runtime.tree.*; +import java.util.List; +import java.util.Iterator; +import java.util.ArrayList; + +@SuppressWarnings({"all", "warnings", "unchecked", "unused", "cast", "CheckReturnValue"}) +public class PropertyPlaceHolderParser extends Parser { + static { RuntimeMetaData.checkVersion("4.13.1", RuntimeMetaData.VERSION); } + + protected static final DFA[] _decisionToDFA; + protected static final PredictionContextCache _sharedContextCache = + new PredictionContextCache(); + public static final int + Backslash=1, Colon=2, Equals=3, Exclamation=4, Number=5, Dot=6, LineBreak=7, + Space=8, Identifier=9; + public static final int + RULE_start = 0, RULE_line = 1, RULE_keyDefaultValuePair = 2, RULE_defaultValue = 3, + RULE_key = 4, RULE_identifier = 5, RULE_value = 6; + private static String[] makeRuleNames() { + return new String[] { + "start", "line", "keyDefaultValuePair", "defaultValue", "key", "identifier", + "value" + }; + } + public static final String[] ruleNames = makeRuleNames(); + + private static String[] makeLiteralNames() { + return new String[] { + null, "'\\'", "':'", "'='", "'!'", "'#'", "'.'" + }; + } + private static final String[] _LITERAL_NAMES = makeLiteralNames(); + private static String[] makeSymbolicNames() { + return new String[] { + null, "Backslash", "Colon", "Equals", "Exclamation", "Number", "Dot", + "LineBreak", "Space", "Identifier" + }; + } + private static final String[] _SYMBOLIC_NAMES = makeSymbolicNames(); + public static final Vocabulary VOCABULARY = new VocabularyImpl(_LITERAL_NAMES, _SYMBOLIC_NAMES); + + /** + * @deprecated Use {@link #VOCABULARY} instead. + */ + @Deprecated + public static final String[] tokenNames; + static { + tokenNames = new String[_SYMBOLIC_NAMES.length]; + for (int i = 0; i < tokenNames.length; i++) { + tokenNames[i] = VOCABULARY.getLiteralName(i); + if (tokenNames[i] == null) { + tokenNames[i] = VOCABULARY.getSymbolicName(i); + } + + if (tokenNames[i] == null) { + tokenNames[i] = ""; + } + } + } + + @Override + @Deprecated + public String[] getTokenNames() { + return tokenNames; + } + + @Override + + public Vocabulary getVocabulary() { + return VOCABULARY; + } + + @Override + public String getGrammarFileName() { return "PropertyPlaceHolder.g4"; } + + @Override + public String[] getRuleNames() { return ruleNames; } + + @Override + public String getSerializedATN() { return _serializedATN; } + + @Override + public ATN getATN() { return _ATN; } + + public PropertyPlaceHolderParser(TokenStream input) { + super(input); + _interp = new ParserATNSimulator(this,_ATN,_decisionToDFA,_sharedContextCache); + } + + @SuppressWarnings("CheckReturnValue") + public static class StartContext extends ParserRuleContext { + public TerminalNode EOF() { return getToken(PropertyPlaceHolderParser.EOF, 0); } + public List line() { + return getRuleContexts(LineContext.class); + } + public LineContext line(int i) { + return getRuleContext(LineContext.class,i); + } + public StartContext(ParserRuleContext parent, int invokingState) { + super(parent, invokingState); + } + @Override public int getRuleIndex() { return RULE_start; } + @Override + public void enterRule(ParseTreeListener listener) { + if ( listener instanceof PropertyPlaceHolderListener ) ((PropertyPlaceHolderListener)listener).enterStart(this); + } + @Override + public void exitRule(ParseTreeListener listener) { + if ( listener instanceof PropertyPlaceHolderListener ) ((PropertyPlaceHolderListener)listener).exitStart(this); + } + } + + public final StartContext start() throws RecognitionException { + StartContext _localctx = new StartContext(_ctx, getState()); + enterRule(_localctx, 0, RULE_start); + int _la; + try { + enterOuterAlt(_localctx, 1); + { + setState(17); + _errHandler.sync(this); + _la = _input.LA(1); + while (_la==Space || _la==Identifier) { + { + { + setState(14); + line(); + } + } + setState(19); + _errHandler.sync(this); + _la = _input.LA(1); + } + setState(20); + match(EOF); + } + } + catch (RecognitionException re) { + _localctx.exception = re; + _errHandler.reportError(this, re); + _errHandler.recover(this, re); + } + finally { + exitRule(); + } + return _localctx; + } + + @SuppressWarnings("CheckReturnValue") + public static class LineContext extends ParserRuleContext { + public KeyDefaultValuePairContext keyDefaultValuePair() { + return getRuleContext(KeyDefaultValuePairContext.class,0); + } + public TerminalNode EOF() { return getToken(PropertyPlaceHolderParser.EOF, 0); } + public List Space() { return getTokens(PropertyPlaceHolderParser.Space); } + public TerminalNode Space(int i) { + return getToken(PropertyPlaceHolderParser.Space, i); + } + public LineContext(ParserRuleContext parent, int invokingState) { + super(parent, invokingState); + } + @Override public int getRuleIndex() { return RULE_line; } + @Override + public void enterRule(ParseTreeListener listener) { + if ( listener instanceof PropertyPlaceHolderListener ) ((PropertyPlaceHolderListener)listener).enterLine(this); + } + @Override + public void exitRule(ParseTreeListener listener) { + if ( listener instanceof PropertyPlaceHolderListener ) ((PropertyPlaceHolderListener)listener).exitLine(this); + } + } + + public final LineContext line() throws RecognitionException { + LineContext _localctx = new LineContext(_ctx, getState()); + enterRule(_localctx, 2, RULE_line); + int _la; + try { + enterOuterAlt(_localctx, 1); + { + setState(25); + _errHandler.sync(this); + _la = _input.LA(1); + while (_la==Space) { + { + { + setState(22); + match(Space); + } + } + setState(27); + _errHandler.sync(this); + _la = _input.LA(1); + } + setState(28); + keyDefaultValuePair(); + setState(32); + _errHandler.sync(this); + _la = _input.LA(1); + while (_la==Space) { + { + { + setState(29); + match(Space); + } + } + setState(34); + _errHandler.sync(this); + _la = _input.LA(1); + } + setState(35); + match(EOF); + } + } + catch (RecognitionException re) { + _localctx.exception = re; + _errHandler.reportError(this, re); + _errHandler.recover(this, re); + } + finally { + exitRule(); + } + return _localctx; + } + + @SuppressWarnings("CheckReturnValue") + public static class KeyDefaultValuePairContext extends ParserRuleContext { + public KeyContext key() { + return getRuleContext(KeyContext.class,0); + } + public DefaultValueContext defaultValue() { + return getRuleContext(DefaultValueContext.class,0); + } + public KeyDefaultValuePairContext(ParserRuleContext parent, int invokingState) { + super(parent, invokingState); + } + @Override public int getRuleIndex() { return RULE_keyDefaultValuePair; } + @Override + public void enterRule(ParseTreeListener listener) { + if ( listener instanceof PropertyPlaceHolderListener ) ((PropertyPlaceHolderListener)listener).enterKeyDefaultValuePair(this); + } + @Override + public void exitRule(ParseTreeListener listener) { + if ( listener instanceof PropertyPlaceHolderListener ) ((PropertyPlaceHolderListener)listener).exitKeyDefaultValuePair(this); + } + } + + public final KeyDefaultValuePairContext keyDefaultValuePair() throws RecognitionException { + KeyDefaultValuePairContext _localctx = new KeyDefaultValuePairContext(_ctx, getState()); + enterRule(_localctx, 4, RULE_keyDefaultValuePair); + try { + setState(41); + _errHandler.sync(this); + switch ( getInterpreter().adaptivePredict(_input,3,_ctx) ) { + case 1: + enterOuterAlt(_localctx, 1); + { + setState(37); + key(); + } + break; + case 2: + enterOuterAlt(_localctx, 2); + { + setState(38); + key(); + setState(39); + defaultValue(); + } + break; + } + } + catch (RecognitionException re) { + _localctx.exception = re; + _errHandler.reportError(this, re); + _errHandler.recover(this, re); + } + finally { + exitRule(); + } + return _localctx; + } + + @SuppressWarnings("CheckReturnValue") + public static class DefaultValueContext extends ParserRuleContext { + public TerminalNode Colon() { return getToken(PropertyPlaceHolderParser.Colon, 0); } + public ValueContext value() { + return getRuleContext(ValueContext.class,0); + } + public DefaultValueContext(ParserRuleContext parent, int invokingState) { + super(parent, invokingState); + } + @Override public int getRuleIndex() { return RULE_defaultValue; } + @Override + public void enterRule(ParseTreeListener listener) { + if ( listener instanceof PropertyPlaceHolderListener ) ((PropertyPlaceHolderListener)listener).enterDefaultValue(this); + } + @Override + public void exitRule(ParseTreeListener listener) { + if ( listener instanceof PropertyPlaceHolderListener ) ((PropertyPlaceHolderListener)listener).exitDefaultValue(this); + } + } + + public final DefaultValueContext defaultValue() throws RecognitionException { + DefaultValueContext _localctx = new DefaultValueContext(_ctx, getState()); + enterRule(_localctx, 6, RULE_defaultValue); + try { + enterOuterAlt(_localctx, 1); + { + setState(43); + match(Colon); + setState(44); + value(); + } + } + catch (RecognitionException re) { + _localctx.exception = re; + _errHandler.reportError(this, re); + _errHandler.recover(this, re); + } + finally { + exitRule(); + } + return _localctx; + } + + @SuppressWarnings("CheckReturnValue") + public static class KeyContext extends ParserRuleContext { + public List identifier() { + return getRuleContexts(IdentifierContext.class); + } + public IdentifierContext identifier(int i) { + return getRuleContext(IdentifierContext.class,i); + } + public List Dot() { return getTokens(PropertyPlaceHolderParser.Dot); } + public TerminalNode Dot(int i) { + return getToken(PropertyPlaceHolderParser.Dot, i); + } + public KeyContext(ParserRuleContext parent, int invokingState) { + super(parent, invokingState); + } + @Override public int getRuleIndex() { return RULE_key; } + @Override + public void enterRule(ParseTreeListener listener) { + if ( listener instanceof PropertyPlaceHolderListener ) ((PropertyPlaceHolderListener)listener).enterKey(this); + } + @Override + public void exitRule(ParseTreeListener listener) { + if ( listener instanceof PropertyPlaceHolderListener ) ((PropertyPlaceHolderListener)listener).exitKey(this); + } + } + + public final KeyContext key() throws RecognitionException { + KeyContext _localctx = new KeyContext(_ctx, getState()); + enterRule(_localctx, 8, RULE_key); + int _la; + try { + enterOuterAlt(_localctx, 1); + { + setState(46); + identifier(); + setState(51); + _errHandler.sync(this); + _la = _input.LA(1); + while (_la==Dot) { + { + { + setState(47); + match(Dot); + setState(48); + identifier(); + } + } + setState(53); + _errHandler.sync(this); + _la = _input.LA(1); + } + } + } + catch (RecognitionException re) { + _localctx.exception = re; + _errHandler.reportError(this, re); + _errHandler.recover(this, re); + } + finally { + exitRule(); + } + return _localctx; + } + + @SuppressWarnings("CheckReturnValue") + public static class IdentifierContext extends ParserRuleContext { + public List Identifier() { return getTokens(PropertyPlaceHolderParser.Identifier); } + public TerminalNode Identifier(int i) { + return getToken(PropertyPlaceHolderParser.Identifier, i); + } + public IdentifierContext(ParserRuleContext parent, int invokingState) { + super(parent, invokingState); + } + @Override public int getRuleIndex() { return RULE_identifier; } + @Override + public void enterRule(ParseTreeListener listener) { + if ( listener instanceof PropertyPlaceHolderListener ) ((PropertyPlaceHolderListener)listener).enterIdentifier(this); + } + @Override + public void exitRule(ParseTreeListener listener) { + if ( listener instanceof PropertyPlaceHolderListener ) ((PropertyPlaceHolderListener)listener).exitIdentifier(this); + } + } + + public final IdentifierContext identifier() throws RecognitionException { + IdentifierContext _localctx = new IdentifierContext(_ctx, getState()); + enterRule(_localctx, 10, RULE_identifier); + int _la; + try { + enterOuterAlt(_localctx, 1); + { + setState(55); + _errHandler.sync(this); + _la = _input.LA(1); + do { + { + { + setState(54); + match(Identifier); + } + } + setState(57); + _errHandler.sync(this); + _la = _input.LA(1); + } while ( _la==Identifier ); + } + } + catch (RecognitionException re) { + _localctx.exception = re; + _errHandler.reportError(this, re); + _errHandler.recover(this, re); + } + finally { + exitRule(); + } + return _localctx; + } + + @SuppressWarnings("CheckReturnValue") + public static class ValueContext extends ParserRuleContext { + public List Identifier() { return getTokens(PropertyPlaceHolderParser.Identifier); } + public TerminalNode Identifier(int i) { + return getToken(PropertyPlaceHolderParser.Identifier, i); + } + public List Exclamation() { return getTokens(PropertyPlaceHolderParser.Exclamation); } + public TerminalNode Exclamation(int i) { + return getToken(PropertyPlaceHolderParser.Exclamation, i); + } + public List Number() { return getTokens(PropertyPlaceHolderParser.Number); } + public TerminalNode Number(int i) { + return getToken(PropertyPlaceHolderParser.Number, i); + } + public List Space() { return getTokens(PropertyPlaceHolderParser.Space); } + public TerminalNode Space(int i) { + return getToken(PropertyPlaceHolderParser.Space, i); + } + public List Backslash() { return getTokens(PropertyPlaceHolderParser.Backslash); } + public TerminalNode Backslash(int i) { + return getToken(PropertyPlaceHolderParser.Backslash, i); + } + public List LineBreak() { return getTokens(PropertyPlaceHolderParser.LineBreak); } + public TerminalNode LineBreak(int i) { + return getToken(PropertyPlaceHolderParser.LineBreak, i); + } + public List Equals() { return getTokens(PropertyPlaceHolderParser.Equals); } + public TerminalNode Equals(int i) { + return getToken(PropertyPlaceHolderParser.Equals, i); + } + public List Colon() { return getTokens(PropertyPlaceHolderParser.Colon); } + public TerminalNode Colon(int i) { + return getToken(PropertyPlaceHolderParser.Colon, i); + } + public List Dot() { return getTokens(PropertyPlaceHolderParser.Dot); } + public TerminalNode Dot(int i) { + return getToken(PropertyPlaceHolderParser.Dot, i); + } + public ValueContext(ParserRuleContext parent, int invokingState) { + super(parent, invokingState); + } + @Override public int getRuleIndex() { return RULE_value; } + @Override + public void enterRule(ParseTreeListener listener) { + if ( listener instanceof PropertyPlaceHolderListener ) ((PropertyPlaceHolderListener)listener).enterValue(this); + } + @Override + public void exitRule(ParseTreeListener listener) { + if ( listener instanceof PropertyPlaceHolderListener ) ((PropertyPlaceHolderListener)listener).exitValue(this); + } + } + + public final ValueContext value() throws RecognitionException { + ValueContext _localctx = new ValueContext(_ctx, getState()); + enterRule(_localctx, 12, RULE_value); + try { + int _alt; + enterOuterAlt(_localctx, 1); + { + setState(72); + _errHandler.sync(this); + _alt = getInterpreter().adaptivePredict(_input,7,_ctx); + while ( _alt!=2 && _alt!=org.antlr.v4.runtime.atn.ATN.INVALID_ALT_NUMBER ) { + if ( _alt==1 ) { + { + setState(70); + _errHandler.sync(this); + switch ( getInterpreter().adaptivePredict(_input,6,_ctx) ) { + case 1: + { + setState(59); + match(Identifier); + } + break; + case 2: + { + setState(60); + match(Exclamation); + } + break; + case 3: + { + setState(61); + match(Number); + } + break; + case 4: + { + setState(62); + match(Space); + } + break; + case 5: + { + setState(63); + match(Backslash); + setState(64); + match(Backslash); + } + break; + case 6: + { + setState(65); + match(Backslash); + setState(66); + match(LineBreak); + } + break; + case 7: + { + setState(67); + match(Equals); + } + break; + case 8: + { + setState(68); + match(Colon); + } + break; + case 9: + { + setState(69); + match(Dot); + } + break; + } + } + } + setState(74); + _errHandler.sync(this); + _alt = getInterpreter().adaptivePredict(_input,7,_ctx); + } + } + } + catch (RecognitionException re) { + _localctx.exception = re; + _errHandler.reportError(this, re); + _errHandler.recover(this, re); + } + finally { + exitRule(); + } + return _localctx; + } + + public static final String _serializedATN = + "\u0004\u0001\tL\u0002\u0000\u0007\u0000\u0002\u0001\u0007\u0001\u0002"+ + "\u0002\u0007\u0002\u0002\u0003\u0007\u0003\u0002\u0004\u0007\u0004\u0002"+ + "\u0005\u0007\u0005\u0002\u0006\u0007\u0006\u0001\u0000\u0005\u0000\u0010"+ + "\b\u0000\n\u0000\f\u0000\u0013\t\u0000\u0001\u0000\u0001\u0000\u0001\u0001"+ + "\u0005\u0001\u0018\b\u0001\n\u0001\f\u0001\u001b\t\u0001\u0001\u0001\u0001"+ + "\u0001\u0005\u0001\u001f\b\u0001\n\u0001\f\u0001\"\t\u0001\u0001\u0001"+ + "\u0001\u0001\u0001\u0002\u0001\u0002\u0001\u0002\u0001\u0002\u0003\u0002"+ + "*\b\u0002\u0001\u0003\u0001\u0003\u0001\u0003\u0001\u0004\u0001\u0004"+ + "\u0001\u0004\u0005\u00042\b\u0004\n\u0004\f\u00045\t\u0004\u0001\u0005"+ + "\u0004\u00058\b\u0005\u000b\u0005\f\u00059\u0001\u0006\u0001\u0006\u0001"+ + "\u0006\u0001\u0006\u0001\u0006\u0001\u0006\u0001\u0006\u0001\u0006\u0001"+ + "\u0006\u0001\u0006\u0001\u0006\u0005\u0006G\b\u0006\n\u0006\f\u0006J\t"+ + "\u0006\u0001\u0006\u0000\u0000\u0007\u0000\u0002\u0004\u0006\b\n\f\u0000"+ + "\u0000S\u0000\u0011\u0001\u0000\u0000\u0000\u0002\u0019\u0001\u0000\u0000"+ + "\u0000\u0004)\u0001\u0000\u0000\u0000\u0006+\u0001\u0000\u0000\u0000\b"+ + ".\u0001\u0000\u0000\u0000\n7\u0001\u0000\u0000\u0000\fH\u0001\u0000\u0000"+ + "\u0000\u000e\u0010\u0003\u0002\u0001\u0000\u000f\u000e\u0001\u0000\u0000"+ + "\u0000\u0010\u0013\u0001\u0000\u0000\u0000\u0011\u000f\u0001\u0000\u0000"+ + "\u0000\u0011\u0012\u0001\u0000\u0000\u0000\u0012\u0014\u0001\u0000\u0000"+ + "\u0000\u0013\u0011\u0001\u0000\u0000\u0000\u0014\u0015\u0005\u0000\u0000"+ + "\u0001\u0015\u0001\u0001\u0000\u0000\u0000\u0016\u0018\u0005\b\u0000\u0000"+ + "\u0017\u0016\u0001\u0000\u0000\u0000\u0018\u001b\u0001\u0000\u0000\u0000"+ + "\u0019\u0017\u0001\u0000\u0000\u0000\u0019\u001a\u0001\u0000\u0000\u0000"+ + "\u001a\u001c\u0001\u0000\u0000\u0000\u001b\u0019\u0001\u0000\u0000\u0000"+ + "\u001c \u0003\u0004\u0002\u0000\u001d\u001f\u0005\b\u0000\u0000\u001e"+ + "\u001d\u0001\u0000\u0000\u0000\u001f\"\u0001\u0000\u0000\u0000 \u001e"+ + "\u0001\u0000\u0000\u0000 !\u0001\u0000\u0000\u0000!#\u0001\u0000\u0000"+ + "\u0000\" \u0001\u0000\u0000\u0000#$\u0005\u0000\u0000\u0001$\u0003\u0001"+ + "\u0000\u0000\u0000%*\u0003\b\u0004\u0000&\'\u0003\b\u0004\u0000\'(\u0003"+ + "\u0006\u0003\u0000(*\u0001\u0000\u0000\u0000)%\u0001\u0000\u0000\u0000"+ + ")&\u0001\u0000\u0000\u0000*\u0005\u0001\u0000\u0000\u0000+,\u0005\u0002"+ + "\u0000\u0000,-\u0003\f\u0006\u0000-\u0007\u0001\u0000\u0000\u0000.3\u0003"+ + "\n\u0005\u0000/0\u0005\u0006\u0000\u000002\u0003\n\u0005\u00001/\u0001"+ + "\u0000\u0000\u000025\u0001\u0000\u0000\u000031\u0001\u0000\u0000\u0000"+ + "34\u0001\u0000\u0000\u00004\t\u0001\u0000\u0000\u000053\u0001\u0000\u0000"+ + "\u000068\u0005\t\u0000\u000076\u0001\u0000\u0000\u000089\u0001\u0000\u0000"+ + "\u000097\u0001\u0000\u0000\u00009:\u0001\u0000\u0000\u0000:\u000b\u0001"+ + "\u0000\u0000\u0000;G\u0005\t\u0000\u0000G\u0005\b\u0000\u0000?@\u0005\u0001\u0000\u0000@G\u0005"+ + "\u0001\u0000\u0000AB\u0005\u0001\u0000\u0000BG\u0005\u0007\u0000\u0000"+ + "CG\u0005\u0003\u0000\u0000DG\u0005\u0002\u0000\u0000EG\u0005\u0006\u0000"+ + "\u0000F;\u0001\u0000\u0000\u0000F<\u0001\u0000\u0000\u0000F=\u0001\u0000"+ + "\u0000\u0000F>\u0001\u0000\u0000\u0000F?\u0001\u0000\u0000\u0000FA\u0001"+ + "\u0000\u0000\u0000FC\u0001\u0000\u0000\u0000FD\u0001\u0000\u0000\u0000"+ + "FE\u0001\u0000\u0000\u0000GJ\u0001\u0000\u0000\u0000HF\u0001\u0000\u0000"+ + "\u0000HI\u0001\u0000\u0000\u0000I\r\u0001\u0000\u0000\u0000JH\u0001\u0000"+ + "\u0000\u0000\b\u0011\u0019 )39FH"; + public static final ATN _ATN = + new ATNDeserializer().deserialize(_serializedATN.toCharArray()); + static { + _decisionToDFA = new DFA[_ATN.getNumberOfDecisions()]; + for (int i = 0; i < _ATN.getNumberOfDecisions(); i++) { + _decisionToDFA[i] = new DFA(_ATN.getDecisionState(i), i); + } + } +} \ No newline at end of file diff --git a/headless-services/commons/jpql/src/main/java/org/springframework/ide/vscode/parser/spel/SpelLexer.java b/headless-services/commons/jpql/src/main/java/org/springframework/ide/vscode/parser/spel/SpelLexer.java index c555d3067a..261a130ef9 100644 --- a/headless-services/commons/jpql/src/main/java/org/springframework/ide/vscode/parser/spel/SpelLexer.java +++ b/headless-services/commons/jpql/src/main/java/org/springframework/ide/vscode/parser/spel/SpelLexer.java @@ -38,8 +38,8 @@ public class SpelLexer extends Lexer { FALSE=44, NEW=45, NULL=46, T=47, MATCHES=48, GT_KEYWORD=49, GE_KEYWORD=50, LE_KEYWORD=51, LT_KEYWORD=52, EQ_KEYWORD=53, NE_KEYWORD=54, IDENTIFIER=55, REAL_LITERAL=56, INTEGER_LITERAL=57, STRING_LITERAL=58, SINGLE_QUOTED_STRING=59, - DOUBLE_QUOTED_STRING=60, ESCAPED_BACKTICK=61, SPEL_IN_TEMPLATE_STRING_OPEN=62, - TEMPLATE_TEXT=63; + DOUBLE_QUOTED_STRING=60, PROPERTY_PLACE_HOLDER=61, ESCAPED_BACKTICK=62, + SPEL_IN_TEMPLATE_STRING_OPEN=63, TEMPLATE_TEXT=64; public static final int IN_TEMPLATE_STRING=1; public static String[] channelNames = { @@ -60,10 +60,10 @@ private static String[] makeRuleNames() { "LT", "LCURLY", "RCURLY", "BACKTICK", "OR", "AND", "TRUE", "FALSE", "NEW", "NULL", "T", "MATCHES", "GT_KEYWORD", "GE_KEYWORD", "LE_KEYWORD", "LT_KEYWORD", "EQ_KEYWORD", "NE_KEYWORD", "IDENTIFIER", "REAL_LITERAL", "INTEGER_LITERAL", - "STRING_LITERAL", "SINGLE_QUOTED_STRING", "DOUBLE_QUOTED_STRING", "INTEGER_TYPE_SUFFIX", - "HEX_DIGIT", "DECIMAL_DIGIT", "EXPONENT_PART", "SIGN", "REAL_TYPE_SUFFIX", - "ALPHABETIC", "DIGIT", "ESCAPED_BACKTICK", "SPEL_IN_TEMPLATE_STRING_OPEN", - "TEMPLATE_TEXT", "BACKTICK_IN_TEMPLATE" + "STRING_LITERAL", "SINGLE_QUOTED_STRING", "DOUBLE_QUOTED_STRING", "PROPERTY_PLACE_HOLDER", + "INTEGER_TYPE_SUFFIX", "HEX_DIGIT", "DECIMAL_DIGIT", "EXPONENT_PART", + "SIGN", "REAL_TYPE_SUFFIX", "ALPHABETIC", "DIGIT", "ESCAPED_BACKTICK", + "SPEL_IN_TEMPLATE_STRING_OPEN", "TEMPLATE_TEXT", "BACKTICK_IN_TEMPLATE" }; } public static final String[] ruleNames = makeRuleNames(); @@ -76,7 +76,7 @@ private static String[] makeLiteralNames() { "'?:'", "'?.'", "'?'", "'$['", "'>='", "'>'", "'<='", "'<'", null, null, null, "'or'", "'and'", "'true'", "'false'", "'new'", "'null'", "'T'", "'matches'", "'gt'", "'ge'", "'le'", "'lt'", "'eq'", "'ne'", null, null, - null, null, null, null, "'``'" + null, null, null, null, null, "'``'" }; } private static final String[] _LITERAL_NAMES = makeLiteralNames(); @@ -90,8 +90,8 @@ private static String[] makeSymbolicNames() { "LCURLY", "RCURLY", "BACKTICK", "OR", "AND", "TRUE", "FALSE", "NEW", "NULL", "T", "MATCHES", "GT_KEYWORD", "GE_KEYWORD", "LE_KEYWORD", "LT_KEYWORD", "EQ_KEYWORD", "NE_KEYWORD", "IDENTIFIER", "REAL_LITERAL", "INTEGER_LITERAL", - "STRING_LITERAL", "SINGLE_QUOTED_STRING", "DOUBLE_QUOTED_STRING", "ESCAPED_BACKTICK", - "SPEL_IN_TEMPLATE_STRING_OPEN", "TEMPLATE_TEXT" + "STRING_LITERAL", "SINGLE_QUOTED_STRING", "DOUBLE_QUOTED_STRING", "PROPERTY_PLACE_HOLDER", + "ESCAPED_BACKTICK", "SPEL_IN_TEMPLATE_STRING_OPEN", "TEMPLATE_TEXT" }; } private static final String[] _SYMBOLIC_NAMES = makeSymbolicNames(); @@ -164,7 +164,7 @@ public void action(RuleContext _localctx, int ruleIndex, int actionIndex) { case 39: RCURLY_action((RuleContext)_localctx, actionIndex); break; - case 70: + case 71: SPEL_IN_TEMPLATE_STRING_OPEN_action((RuleContext)_localctx, actionIndex); break; } @@ -196,7 +196,7 @@ private void SPEL_IN_TEMPLATE_STRING_OPEN_action(RuleContext _localctx, int acti } public static final String _serializedATN = - "\u0004\u0000?\u01d2\u0006\uffff\uffff\u0006\uffff\uffff\u0002\u0000\u0007"+ + "\u0004\u0000@\u01df\u0006\uffff\uffff\u0006\uffff\uffff\u0002\u0000\u0007"+ "\u0000\u0002\u0001\u0007\u0001\u0002\u0002\u0007\u0002\u0002\u0003\u0007"+ "\u0003\u0002\u0004\u0007\u0004\u0002\u0005\u0007\u0005\u0002\u0006\u0007"+ "\u0006\u0002\u0007\u0007\u0007\u0002\b\u0007\b\u0002\t\u0007\t\u0002\n"+ @@ -215,448 +215,457 @@ private void SPEL_IN_TEMPLATE_STRING_OPEN_action(RuleContext _localctx, int acti "9\u00079\u0002:\u0007:\u0002;\u0007;\u0002<\u0007<\u0002=\u0007=\u0002"+ ">\u0007>\u0002?\u0007?\u0002@\u0007@\u0002A\u0007A\u0002B\u0007B\u0002"+ "C\u0007C\u0002D\u0007D\u0002E\u0007E\u0002F\u0007F\u0002G\u0007G\u0002"+ - "H\u0007H\u0001\u0000\u0001\u0000\u0001\u0001\u0001\u0001\u0001\u0001\u0003"+ - "\u0001\u009a\b\u0001\u0001\u0002\u0004\u0002\u009d\b\u0002\u000b\u0002"+ - "\f\u0002\u009e\u0001\u0002\u0001\u0002\u0001\u0003\u0001\u0003\u0001\u0003"+ - "\u0001\u0004\u0001\u0004\u0001\u0005\u0001\u0005\u0001\u0005\u0001\u0006"+ - "\u0001\u0006\u0001\u0007\u0001\u0007\u0001\b\u0001\b\u0001\t\u0001\t\u0001"+ - "\n\u0001\n\u0001\u000b\u0001\u000b\u0001\f\u0001\f\u0001\r\u0001\r\u0001"+ - "\u000e\u0001\u000e\u0001\u000f\u0001\u000f\u0001\u0010\u0001\u0010\u0001"+ - "\u0011\u0001\u0011\u0001\u0012\u0001\u0012\u0001\u0013\u0001\u0013\u0001"+ - "\u0013\u0001\u0014\u0001\u0014\u0001\u0015\u0001\u0015\u0001\u0015\u0001"+ - "\u0016\u0001\u0016\u0001\u0016\u0001\u0017\u0001\u0017\u0001\u0018\u0001"+ - "\u0018\u0001\u0018\u0001\u0019\u0001\u0019\u0001\u001a\u0001\u001a\u0001"+ - "\u001a\u0001\u001b\u0001\u001b\u0001\u001c\u0001\u001c\u0001\u001c\u0001"+ - "\u001d\u0001\u001d\u0001\u001d\u0001\u001e\u0001\u001e\u0001\u001e\u0001"+ - "\u001f\u0001\u001f\u0001\u001f\u0001 \u0001 \u0001!\u0001!\u0001!\u0001"+ - "\"\u0001\"\u0001\"\u0001#\u0001#\u0001$\u0001$\u0001$\u0001%\u0001%\u0001"+ - "&\u0001&\u0001&\u0001&\u0001&\u0001\'\u0001\'\u0001\'\u0001\'\u0001\'"+ - "\u0001(\u0001(\u0001(\u0001(\u0001)\u0001)\u0001)\u0001*\u0001*\u0001"+ - "*\u0001*\u0001+\u0001+\u0001+\u0001+\u0001+\u0001,\u0001,\u0001,\u0001"+ - ",\u0001,\u0001,\u0001-\u0001-\u0001-\u0001-\u0001.\u0001.\u0001.\u0001"+ - ".\u0001.\u0001/\u0001/\u00010\u00010\u00010\u00010\u00010\u00010\u0001"+ - "0\u00010\u00011\u00011\u00011\u00012\u00012\u00012\u00013\u00013\u0001"+ - "3\u00014\u00014\u00014\u00015\u00015\u00015\u00016\u00016\u00016\u0001"+ - "7\u00017\u00037\u013e\b7\u00017\u00017\u00017\u00057\u0143\b7\n7\f7\u0146"+ - "\t7\u00018\u00018\u00048\u014a\b8\u000b8\f8\u014b\u00018\u00038\u014f"+ - "\b8\u00018\u00038\u0152\b8\u00018\u00048\u0155\b8\u000b8\f8\u0156\u0001"+ - "8\u00018\u00048\u015b\b8\u000b8\f8\u015c\u00018\u00038\u0160\b8\u0001"+ - "8\u00038\u0163\b8\u00018\u00048\u0166\b8\u000b8\f8\u0167\u00018\u0001"+ - "8\u00038\u016c\b8\u00018\u00048\u016f\b8\u000b8\f8\u0170\u00018\u0001"+ - "8\u00038\u0175\b8\u00019\u00049\u0178\b9\u000b9\f9\u0179\u00019\u0003"+ - "9\u017d\b9\u0001:\u0001:\u0003:\u0181\b:\u0001;\u0001;\u0001;\u0001;\u0005"+ - ";\u0187\b;\n;\f;\u018a\t;\u0001;\u0001;\u0001<\u0001<\u0001<\u0001<\u0005"+ - "<\u0192\b<\n<\f<\u0195\t<\u0001<\u0001<\u0001=\u0001=\u0001>\u0001>\u0001"+ - "?\u0001?\u0001@\u0001@\u0005@\u01a1\b@\n@\f@\u01a4\t@\u0001@\u0004@\u01a7"+ - "\b@\u000b@\f@\u01a8\u0001@\u0001@\u0005@\u01ad\b@\n@\f@\u01b0\t@\u0001"+ - "@\u0004@\u01b3\b@\u000b@\f@\u01b4\u0003@\u01b7\b@\u0001A\u0001A\u0001"+ - "B\u0001B\u0001C\u0003C\u01be\bC\u0001D\u0001D\u0001E\u0001E\u0001E\u0001"+ - "F\u0001F\u0001F\u0001F\u0001F\u0001F\u0001F\u0001G\u0001G\u0001H\u0001"+ - "H\u0001H\u0001H\u0001H\u0000\u0000I\u0002\u0001\u0004\u0000\u0006\u0002"+ - "\b\u0003\n\u0004\f\u0005\u000e\u0006\u0010\u0007\u0012\b\u0014\t\u0016"+ - "\n\u0018\u000b\u001a\f\u001c\r\u001e\u000e \u000f\"\u0010$\u0011&\u0012"+ - "(\u0013*\u0014,\u0015.\u00160\u00172\u00184\u00196\u001a8\u001b:\u001c"+ - "<\u001d>\u001e@\u001fB D!F\"H#J$L%N&P\'R(T)V*X+Z,\\-^.`/b0d1f2h3j4l5n"+ - "6p7r8t9v:x;z<|\u0000~\u0000\u0080\u0000\u0082\u0000\u0084\u0000\u0086"+ - "\u0000\u0088\u0000\u008a\u0000\u008c=\u008e>\u0090?\u0092\u0000\u0002"+ - "\u0000\u0001\f\u0003\u0000\n\n\r\r\u2028\u2029\u0003\u0000\t\n\r\r \u0002"+ - "\u0000$$__\u0002\u0000\n\n\'\'\u0002\u0000\n\n\"\"\u0002\u0000LLll\u0003"+ - "\u000009AFaf\u0001\u000009\u0002\u0000++--\u0004\u0000DDFFddff\u0293\u0000"+ - "AZaz\u00aa\u00aa\u00b5\u00b5\u00ba\u00ba\u00c0\u00d6\u00d8\u00f6\u00f8"+ - "\u02c1\u02c6\u02d1\u02e0\u02e4\u02ec\u02ec\u02ee\u02ee\u0370\u0374\u0376"+ - "\u0377\u037a\u037d\u037f\u037f\u0386\u0386\u0388\u038a\u038c\u038c\u038e"+ - "\u03a1\u03a3\u03f5\u03f7\u0481\u048a\u052f\u0531\u0556\u0559\u0559\u0560"+ - "\u0588\u05d0\u05ea\u05ef\u05f2\u0620\u064a\u066e\u066f\u0671\u06d3\u06d5"+ - "\u06d5\u06e5\u06e6\u06ee\u06ef\u06fa\u06fc\u06ff\u06ff\u0710\u0710\u0712"+ - "\u072f\u074d\u07a5\u07b1\u07b1\u07ca\u07ea\u07f4\u07f5\u07fa\u07fa\u0800"+ - "\u0815\u081a\u081a\u0824\u0824\u0828\u0828\u0840\u0858\u0860\u086a\u0870"+ - "\u0887\u0889\u088e\u08a0\u08c9\u0904\u0939\u093d\u093d\u0950\u0950\u0958"+ - "\u0961\u0971\u0980\u0985\u098c\u098f\u0990\u0993\u09a8\u09aa\u09b0\u09b2"+ - "\u09b2\u09b6\u09b9\u09bd\u09bd\u09ce\u09ce\u09dc\u09dd\u09df\u09e1\u09f0"+ - "\u09f1\u09fc\u09fc\u0a05\u0a0a\u0a0f\u0a10\u0a13\u0a28\u0a2a\u0a30\u0a32"+ - "\u0a33\u0a35\u0a36\u0a38\u0a39\u0a59\u0a5c\u0a5e\u0a5e\u0a72\u0a74\u0a85"+ - "\u0a8d\u0a8f\u0a91\u0a93\u0aa8\u0aaa\u0ab0\u0ab2\u0ab3\u0ab5\u0ab9\u0abd"+ - "\u0abd\u0ad0\u0ad0\u0ae0\u0ae1\u0af9\u0af9\u0b05\u0b0c\u0b0f\u0b10\u0b13"+ - "\u0b28\u0b2a\u0b30\u0b32\u0b33\u0b35\u0b39\u0b3d\u0b3d\u0b5c\u0b5d\u0b5f"+ - "\u0b61\u0b71\u0b71\u0b83\u0b83\u0b85\u0b8a\u0b8e\u0b90\u0b92\u0b95\u0b99"+ - "\u0b9a\u0b9c\u0b9c\u0b9e\u0b9f\u0ba3\u0ba4\u0ba8\u0baa\u0bae\u0bb9\u0bd0"+ - "\u0bd0\u0c05\u0c0c\u0c0e\u0c10\u0c12\u0c28\u0c2a\u0c39\u0c3d\u0c3d\u0c58"+ - "\u0c5a\u0c5d\u0c5d\u0c60\u0c61\u0c80\u0c80\u0c85\u0c8c\u0c8e\u0c90\u0c92"+ - "\u0ca8\u0caa\u0cb3\u0cb5\u0cb9\u0cbd\u0cbd\u0cdd\u0cde\u0ce0\u0ce1\u0cf1"+ - "\u0cf2\u0d04\u0d0c\u0d0e\u0d10\u0d12\u0d3a\u0d3d\u0d3d\u0d4e\u0d4e\u0d54"+ - "\u0d56\u0d5f\u0d61\u0d7a\u0d7f\u0d85\u0d96\u0d9a\u0db1\u0db3\u0dbb\u0dbd"+ - "\u0dbd\u0dc0\u0dc6\u0e01\u0e30\u0e32\u0e33\u0e40\u0e46\u0e81\u0e82\u0e84"+ - "\u0e84\u0e86\u0e8a\u0e8c\u0ea3\u0ea5\u0ea5\u0ea7\u0eb0\u0eb2\u0eb3\u0ebd"+ - "\u0ebd\u0ec0\u0ec4\u0ec6\u0ec6\u0edc\u0edf\u0f00\u0f00\u0f40\u0f47\u0f49"+ - "\u0f6c\u0f88\u0f8c\u1000\u102a\u103f\u103f\u1050\u1055\u105a\u105d\u1061"+ - "\u1061\u1065\u1066\u106e\u1070\u1075\u1081\u108e\u108e\u10a0\u10c5\u10c7"+ - "\u10c7\u10cd\u10cd\u10d0\u10fa\u10fc\u1248\u124a\u124d\u1250\u1256\u1258"+ - "\u1258\u125a\u125d\u1260\u1288\u128a\u128d\u1290\u12b0\u12b2\u12b5\u12b8"+ - "\u12be\u12c0\u12c0\u12c2\u12c5\u12c8\u12d6\u12d8\u1310\u1312\u1315\u1318"+ - "\u135a\u1380\u138f\u13a0\u13f5\u13f8\u13fd\u1401\u166c\u166f\u167f\u1681"+ - "\u169a\u16a0\u16ea\u16f1\u16f8\u1700\u1711\u171f\u1731\u1740\u1751\u1760"+ - "\u176c\u176e\u1770\u1780\u17b3\u17d7\u17d7\u17dc\u17dc\u1820\u1878\u1880"+ - "\u1884\u1887\u18a8\u18aa\u18aa\u18b0\u18f5\u1900\u191e\u1950\u196d\u1970"+ - "\u1974\u1980\u19ab\u19b0\u19c9\u1a00\u1a16\u1a20\u1a54\u1aa7\u1aa7\u1b05"+ - "\u1b33\u1b45\u1b4c\u1b83\u1ba0\u1bae\u1baf\u1bba\u1be5\u1c00\u1c23\u1c4d"+ - "\u1c4f\u1c5a\u1c7d\u1c80\u1c88\u1c90\u1cba\u1cbd\u1cbf\u1ce9\u1cec\u1cee"+ - "\u1cf3\u1cf5\u1cf6\u1cfa\u1cfa\u1d00\u1dbf\u1e00\u1f15\u1f18\u1f1d\u1f20"+ - "\u1f45\u1f48\u1f4d\u1f50\u1f57\u1f59\u1f59\u1f5b\u1f5b\u1f5d\u1f5d\u1f5f"+ - "\u1f7d\u1f80\u1fb4\u1fb6\u1fbc\u1fbe\u1fbe\u1fc2\u1fc4\u1fc6\u1fcc\u1fd0"+ - "\u1fd3\u1fd6\u1fdb\u1fe0\u1fec\u1ff2\u1ff4\u1ff6\u1ffc\u2071\u2071\u207f"+ - "\u207f\u2090\u209c\u2102\u2102\u2107\u2107\u210a\u2113\u2115\u2115\u2119"+ - "\u211d\u2124\u2124\u2126\u2126\u2128\u2128\u212a\u212d\u212f\u2139\u213c"+ - "\u213f\u2145\u2149\u214e\u214e\u2183\u2184\u2c00\u2ce4\u2ceb\u2cee\u2cf2"+ - "\u2cf3\u2d00\u2d25\u2d27\u2d27\u2d2d\u2d2d\u2d30\u2d67\u2d6f\u2d6f\u2d80"+ - "\u2d96\u2da0\u2da6\u2da8\u2dae\u2db0\u2db6\u2db8\u2dbe\u2dc0\u2dc6\u2dc8"+ - "\u2dce\u2dd0\u2dd6\u2dd8\u2dde\u2e2f\u2e2f\u3005\u3006\u3031\u3035\u303b"+ - "\u303c\u3041\u3096\u309d\u309f\u30a1\u30fa\u30fc\u30ff\u3105\u312f\u3131"+ - "\u318e\u31a0\u31bf\u31f0\u31ff\u3400\u4dbf\u4e00\u8000\ua48c\u8000\ua4d0"+ - "\u8000\ua4fd\u8000\ua500\u8000\ua60c\u8000\ua610\u8000\ua61f\u8000\ua62a"+ - "\u8000\ua62b\u8000\ua640\u8000\ua66e\u8000\ua67f\u8000\ua69d\u8000\ua6a0"+ - "\u8000\ua6e5\u8000\ua717\u8000\ua71f\u8000\ua722\u8000\ua788\u8000\ua78b"+ - "\u8000\ua7ca\u8000\ua7d0\u8000\ua7d1\u8000\ua7d3\u8000\ua7d3\u8000\ua7d5"+ - "\u8000\ua7d9\u8000\ua7f2\u8000\ua801\u8000\ua803\u8000\ua805\u8000\ua807"+ - "\u8000\ua80a\u8000\ua80c\u8000\ua822\u8000\ua840\u8000\ua873\u8000\ua882"+ - "\u8000\ua8b3\u8000\ua8f2\u8000\ua8f7\u8000\ua8fb\u8000\ua8fb\u8000\ua8fd"+ - "\u8000\ua8fe\u8000\ua90a\u8000\ua925\u8000\ua930\u8000\ua946\u8000\ua960"+ - "\u8000\ua97c\u8000\ua984\u8000\ua9b2\u8000\ua9cf\u8000\ua9cf\u8000\ua9e0"+ - "\u8000\ua9e4\u8000\ua9e6\u8000\ua9ef\u8000\ua9fa\u8000\ua9fe\u8000\uaa00"+ - "\u8000\uaa28\u8000\uaa40\u8000\uaa42\u8000\uaa44\u8000\uaa4b\u8000\uaa60"+ - "\u8000\uaa76\u8000\uaa7a\u8000\uaa7a\u8000\uaa7e\u8000\uaaaf\u8000\uaab1"+ - "\u8000\uaab1\u8000\uaab5\u8000\uaab6\u8000\uaab9\u8000\uaabd\u8000\uaac0"+ - "\u8000\uaac0\u8000\uaac2\u8000\uaac2\u8000\uaadb\u8000\uaadd\u8000\uaae0"+ - "\u8000\uaaea\u8000\uaaf2\u8000\uaaf4\u8000\uab01\u8000\uab06\u8000\uab09"+ - "\u8000\uab0e\u8000\uab11\u8000\uab16\u8000\uab20\u8000\uab26\u8000\uab28"+ - "\u8000\uab2e\u8000\uab30\u8000\uab5a\u8000\uab5c\u8000\uab69\u8000\uab70"+ - "\u8000\uabe2\u8000\uac00\u8000\ud7a3\u8000\ud7b0\u8000\ud7c6\u8000\ud7cb"+ - "\u8000\ud7fb\u8000\uf900\u8000\ufa6d\u8000\ufa70\u8000\ufad9\u8000\ufb00"+ - "\u8000\ufb06\u8000\ufb13\u8000\ufb17\u8000\ufb1d\u8000\ufb1d\u8000\ufb1f"+ - "\u8000\ufb28\u8000\ufb2a\u8000\ufb36\u8000\ufb38\u8000\ufb3c\u8000\ufb3e"+ - "\u8000\ufb3e\u8000\ufb40\u8000\ufb41\u8000\ufb43\u8000\ufb44\u8000\ufb46"+ - "\u8000\ufbb1\u8000\ufbd3\u8000\ufd3d\u8000\ufd50\u8000\ufd8f\u8000\ufd92"+ - "\u8000\ufdc7\u8000\ufdf0\u8000\ufdfb\u8000\ufe70\u8000\ufe74\u8000\ufe76"+ - "\u8000\ufefc\u8000\uff21\u8000\uff3a\u8000\uff41\u8000\uff5a\u8000\uff66"+ - "\u8000\uffbe\u8000\uffc2\u8000\uffc7\u8000\uffca\u8000\uffcf\u8000\uffd2"+ - "\u8000\uffd7\u8000\uffda\u8000\uffdc\u8001\u0000\u8001\u000b\u8001\r\u8001"+ - "&\u8001(\u8001:\u8001<\u8001=\u8001?\u8001M\u8001P\u8001]\u8001\u0080"+ - "\u8001\u00fa\u8001\u0280\u8001\u029c\u8001\u02a0\u8001\u02d0\u8001\u0300"+ - "\u8001\u031f\u8001\u032d\u8001\u0340\u8001\u0342\u8001\u0349\u8001\u0350"+ - "\u8001\u0375\u8001\u0380\u8001\u039d\u8001\u03a0\u8001\u03c3\u8001\u03c8"+ - "\u8001\u03cf\u8001\u0400\u8001\u049d\u8001\u04b0\u8001\u04d3\u8001\u04d8"+ - "\u8001\u04fb\u8001\u0500\u8001\u0527\u8001\u0530\u8001\u0563\u8001\u0570"+ - "\u8001\u057a\u8001\u057c\u8001\u058a\u8001\u058c\u8001\u0592\u8001\u0594"+ - "\u8001\u0595\u8001\u0597\u8001\u05a1\u8001\u05a3\u8001\u05b1\u8001\u05b3"+ - "\u8001\u05b9\u8001\u05bb\u8001\u05bc\u8001\u0600\u8001\u0736\u8001\u0740"+ - "\u8001\u0755\u8001\u0760\u8001\u0767\u8001\u0780\u8001\u0785\u8001\u0787"+ - "\u8001\u07b0\u8001\u07b2\u8001\u07ba\u8001\u0800\u8001\u0805\u8001\u0808"+ - "\u8001\u0808\u8001\u080a\u8001\u0835\u8001\u0837\u8001\u0838\u8001\u083c"+ - "\u8001\u083c\u8001\u083f\u8001\u0855\u8001\u0860\u8001\u0876\u8001\u0880"+ - "\u8001\u089e\u8001\u08e0\u8001\u08f2\u8001\u08f4\u8001\u08f5\u8001\u0900"+ - "\u8001\u0915\u8001\u0920\u8001\u0939\u8001\u0980\u8001\u09b7\u8001\u09be"+ - "\u8001\u09bf\u8001\u0a00\u8001\u0a00\u8001\u0a10\u8001\u0a13\u8001\u0a15"+ - "\u8001\u0a17\u8001\u0a19\u8001\u0a35\u8001\u0a60\u8001\u0a7c\u8001\u0a80"+ - "\u8001\u0a9c\u8001\u0ac0\u8001\u0ac7\u8001\u0ac9\u8001\u0ae4\u8001\u0b00"+ - "\u8001\u0b35\u8001\u0b40\u8001\u0b55\u8001\u0b60\u8001\u0b72\u8001\u0b80"+ - "\u8001\u0b91\u8001\u0c00\u8001\u0c48\u8001\u0c80\u8001\u0cb2\u8001\u0cc0"+ - "\u8001\u0cf2\u8001\u0d00\u8001\u0d23\u8001\u0e80\u8001\u0ea9\u8001\u0eb0"+ - "\u8001\u0eb1\u8001\u0f00\u8001\u0f1c\u8001\u0f27\u8001\u0f27\u8001\u0f30"+ - "\u8001\u0f45\u8001\u0f70\u8001\u0f81\u8001\u0fb0\u8001\u0fc4\u8001\u0fe0"+ - "\u8001\u0ff6\u8001\u1003\u8001\u1037\u8001\u1071\u8001\u1072\u8001\u1075"+ - "\u8001\u1075\u8001\u1083\u8001\u10af\u8001\u10d0\u8001\u10e8\u8001\u1103"+ - "\u8001\u1126\u8001\u1144\u8001\u1144\u8001\u1147\u8001\u1147\u8001\u1150"+ - "\u8001\u1172\u8001\u1176\u8001\u1176\u8001\u1183\u8001\u11b2\u8001\u11c1"+ - "\u8001\u11c4\u8001\u11da\u8001\u11da\u8001\u11dc\u8001\u11dc\u8001\u1200"+ - "\u8001\u1211\u8001\u1213\u8001\u122b\u8001\u123f\u8001\u1240\u8001\u1280"+ - "\u8001\u1286\u8001\u1288\u8001\u1288\u8001\u128a\u8001\u128d\u8001\u128f"+ - "\u8001\u129d\u8001\u129f\u8001\u12a8\u8001\u12b0\u8001\u12de\u8001\u1305"+ - "\u8001\u130c\u8001\u130f\u8001\u1310\u8001\u1313\u8001\u1328\u8001\u132a"+ - "\u8001\u1330\u8001\u1332\u8001\u1333\u8001\u1335\u8001\u1339\u8001\u133d"+ - "\u8001\u133d\u8001\u1350\u8001\u1350\u8001\u135d\u8001\u1361\u8001\u1400"+ - "\u8001\u1434\u8001\u1447\u8001\u144a\u8001\u145f\u8001\u1461\u8001\u1480"+ - "\u8001\u14af\u8001\u14c4\u8001\u14c5\u8001\u14c7\u8001\u14c7\u8001\u1580"+ - "\u8001\u15ae\u8001\u15d8\u8001\u15db\u8001\u1600\u8001\u162f\u8001\u1644"+ - "\u8001\u1644\u8001\u1680\u8001\u16aa\u8001\u16b8\u8001\u16b8\u8001\u1700"+ - "\u8001\u171a\u8001\u1740\u8001\u1746\u8001\u1800\u8001\u182b\u8001\u18a0"+ - "\u8001\u18df\u8001\u18ff\u8001\u1906\u8001\u1909\u8001\u1909\u8001\u190c"+ - "\u8001\u1913\u8001\u1915\u8001\u1916\u8001\u1918\u8001\u192f\u8001\u193f"+ - "\u8001\u193f\u8001\u1941\u8001\u1941\u8001\u19a0\u8001\u19a7\u8001\u19aa"+ - "\u8001\u19d0\u8001\u19e1\u8001\u19e1\u8001\u19e3\u8001\u19e3\u8001\u1a00"+ - "\u8001\u1a00\u8001\u1a0b\u8001\u1a32\u8001\u1a3a\u8001\u1a3a\u8001\u1a50"+ - "\u8001\u1a50\u8001\u1a5c\u8001\u1a89\u8001\u1a9d\u8001\u1a9d\u8001\u1ab0"+ - "\u8001\u1af8\u8001\u1c00\u8001\u1c08\u8001\u1c0a\u8001\u1c2e\u8001\u1c40"+ - "\u8001\u1c40\u8001\u1c72\u8001\u1c8f\u8001\u1d00\u8001\u1d06\u8001\u1d08"+ - "\u8001\u1d09\u8001\u1d0b\u8001\u1d30\u8001\u1d46\u8001\u1d46\u8001\u1d60"+ - "\u8001\u1d65\u8001\u1d67\u8001\u1d68\u8001\u1d6a\u8001\u1d89\u8001\u1d98"+ - "\u8001\u1d98\u8001\u1ee0\u8001\u1ef2\u8001\u1f02\u8001\u1f02\u8001\u1f04"+ - "\u8001\u1f10\u8001\u1f12\u8001\u1f33\u8001\u1fb0\u8001\u1fb0\u8001\u2000"+ - "\u8001\u2399\u8001\u2480\u8001\u2543\u8001\u2f90\u8001\u2ff0\u8001\u3000"+ - "\u8001\u342f\u8001\u3441\u8001\u3446\u8001\u4400\u8001\u4646\u8001\u6800"+ - "\u8001\u6a38\u8001\u6a40\u8001\u6a5e\u8001\u6a70\u8001\u6abe\u8001\u6ad0"+ - "\u8001\u6aed\u8001\u6b00\u8001\u6b2f\u8001\u6b40\u8001\u6b43\u8001\u6b63"+ - "\u8001\u6b77\u8001\u6b7d\u8001\u6b8f\u8001\u6e40\u8001\u6e7f\u8001\u6f00"+ - "\u8001\u6f4a\u8001\u6f50\u8001\u6f50\u8001\u6f93\u8001\u6f9f\u8001\u6fe0"+ - "\u8001\u6fe1\u8001\u6fe3\u8001\u6fe3\u8001\u7000\u8001\u87f7\u8001\u8800"+ - "\u8001\u8cd5\u8001\u8d00\u8001\u8d08\u8001\uaff0\u8001\uaff3\u8001\uaff5"+ - "\u8001\uaffb\u8001\uaffd\u8001\uaffe\u8001\ub000\u8001\ub122\u8001\ub132"+ - "\u8001\ub132\u8001\ub150\u8001\ub152\u8001\ub155\u8001\ub155\u8001\ub164"+ - "\u8001\ub167\u8001\ub170\u8001\ub2fb\u8001\ubc00\u8001\ubc6a\u8001\ubc70"+ - "\u8001\ubc7c\u8001\ubc80\u8001\ubc88\u8001\ubc90\u8001\ubc99\u8001\ud400"+ - "\u8001\ud454\u8001\ud456\u8001\ud49c\u8001\ud49e\u8001\ud49f\u8001\ud4a2"+ - "\u8001\ud4a2\u8001\ud4a5\u8001\ud4a6\u8001\ud4a9\u8001\ud4ac\u8001\ud4ae"+ - "\u8001\ud4b9\u8001\ud4bb\u8001\ud4bb\u8001\ud4bd\u8001\ud4c3\u8001\ud4c5"+ - "\u8001\ud505\u8001\ud507\u8001\ud50a\u8001\ud50d\u8001\ud514\u8001\ud516"+ - "\u8001\ud51c\u8001\ud51e\u8001\ud539\u8001\ud53b\u8001\ud53e\u8001\ud540"+ - "\u8001\ud544\u8001\ud546\u8001\ud546\u8001\ud54a\u8001\ud550\u8001\ud552"+ - "\u8001\ud6a5\u8001\ud6a8\u8001\ud6c0\u8001\ud6c2\u8001\ud6da\u8001\ud6dc"+ - "\u8001\ud6fa\u8001\ud6fc\u8001\ud714\u8001\ud716\u8001\ud734\u8001\ud736"+ - "\u8001\ud74e\u8001\ud750\u8001\ud76e\u8001\ud770\u8001\ud788\u8001\ud78a"+ - "\u8001\ud7a8\u8001\ud7aa\u8001\ud7c2\u8001\ud7c4\u8001\ud7cb\u8001\udf00"+ - "\u8001\udf1e\u8001\udf25\u8001\udf2a\u8001\ue030\u8001\ue06d\u8001\ue100"+ - "\u8001\ue12c\u8001\ue137\u8001\ue13d\u8001\ue14e\u8001\ue14e\u8001\ue290"+ - "\u8001\ue2ad\u8001\ue2c0\u8001\ue2eb\u8001\ue4d0\u8001\ue4eb\u8001\ue7e0"+ - "\u8001\ue7e6\u8001\ue7e8\u8001\ue7eb\u8001\ue7ed\u8001\ue7ee\u8001\ue7f0"+ - "\u8001\ue7fe\u8001\ue800\u8001\ue8c4\u8001\ue900\u8001\ue943\u8001\ue94b"+ - "\u8001\ue94b\u8001\uee00\u8001\uee03\u8001\uee05\u8001\uee1f\u8001\uee21"+ - "\u8001\uee22\u8001\uee24\u8001\uee24\u8001\uee27\u8001\uee27\u8001\uee29"+ - "\u8001\uee32\u8001\uee34\u8001\uee37\u8001\uee39\u8001\uee39\u8001\uee3b"+ - "\u8001\uee3b\u8001\uee42\u8001\uee42\u8001\uee47\u8001\uee47\u8001\uee49"+ - "\u8001\uee49\u8001\uee4b\u8001\uee4b\u8001\uee4d\u8001\uee4f\u8001\uee51"+ - "\u8001\uee52\u8001\uee54\u8001\uee54\u8001\uee57\u8001\uee57\u8001\uee59"+ - "\u8001\uee59\u8001\uee5b\u8001\uee5b\u8001\uee5d\u8001\uee5d\u8001\uee5f"+ - "\u8001\uee5f\u8001\uee61\u8001\uee62\u8001\uee64\u8001\uee64\u8001\uee67"+ - "\u8001\uee6a\u8001\uee6c\u8001\uee72\u8001\uee74\u8001\uee77\u8001\uee79"+ - "\u8001\uee7c\u8001\uee7e\u8001\uee7e\u8001\uee80\u8001\uee89\u8001\uee8b"+ - "\u8001\uee9b\u8001\ueea1\u8001\ueea3\u8001\ueea5\u8001\ueea9\u8001\ueeab"+ - "\u8001\ueebb\u8002\u0000\u8002\ua6df\u8002\ua700\u8002\ub739\u8002\ub740"+ - "\u8002\ub81d\u8002\ub820\u8002\ucea1\u8002\uceb0\u8002\uebe0\u8002\uf800"+ - "\u8002\ufa1d\u8003\u0000\u8003\u134a\u8003\u1350\u8003\u23af\u0002\u0000"+ - "\n\n``\u01e6\u0000\u0002\u0001\u0000\u0000\u0000\u0000\u0006\u0001\u0000"+ - "\u0000\u0000\u0000\b\u0001\u0000\u0000\u0000\u0000\n\u0001\u0000\u0000"+ - "\u0000\u0000\f\u0001\u0000\u0000\u0000\u0000\u000e\u0001\u0000\u0000\u0000"+ - "\u0000\u0010\u0001\u0000\u0000\u0000\u0000\u0012\u0001\u0000\u0000\u0000"+ - "\u0000\u0014\u0001\u0000\u0000\u0000\u0000\u0016\u0001\u0000\u0000\u0000"+ - "\u0000\u0018\u0001\u0000\u0000\u0000\u0000\u001a\u0001\u0000\u0000\u0000"+ - "\u0000\u001c\u0001\u0000\u0000\u0000\u0000\u001e\u0001\u0000\u0000\u0000"+ - "\u0000 \u0001\u0000\u0000\u0000\u0000\"\u0001\u0000\u0000\u0000\u0000"+ - "$\u0001\u0000\u0000\u0000\u0000&\u0001\u0000\u0000\u0000\u0000(\u0001"+ - "\u0000\u0000\u0000\u0000*\u0001\u0000\u0000\u0000\u0000,\u0001\u0000\u0000"+ - "\u0000\u0000.\u0001\u0000\u0000\u0000\u00000\u0001\u0000\u0000\u0000\u0000"+ - "2\u0001\u0000\u0000\u0000\u00004\u0001\u0000\u0000\u0000\u00006\u0001"+ - "\u0000\u0000\u0000\u00008\u0001\u0000\u0000\u0000\u0000:\u0001\u0000\u0000"+ - "\u0000\u0000<\u0001\u0000\u0000\u0000\u0000>\u0001\u0000\u0000\u0000\u0000"+ - "@\u0001\u0000\u0000\u0000\u0000B\u0001\u0000\u0000\u0000\u0000D\u0001"+ - "\u0000\u0000\u0000\u0000F\u0001\u0000\u0000\u0000\u0000H\u0001\u0000\u0000"+ - "\u0000\u0000J\u0001\u0000\u0000\u0000\u0000L\u0001\u0000\u0000\u0000\u0000"+ - "N\u0001\u0000\u0000\u0000\u0000P\u0001\u0000\u0000\u0000\u0000R\u0001"+ - "\u0000\u0000\u0000\u0000T\u0001\u0000\u0000\u0000\u0000V\u0001\u0000\u0000"+ - "\u0000\u0000X\u0001\u0000\u0000\u0000\u0000Z\u0001\u0000\u0000\u0000\u0000"+ - "\\\u0001\u0000\u0000\u0000\u0000^\u0001\u0000\u0000\u0000\u0000`\u0001"+ - "\u0000\u0000\u0000\u0000b\u0001\u0000\u0000\u0000\u0000d\u0001\u0000\u0000"+ - "\u0000\u0000f\u0001\u0000\u0000\u0000\u0000h\u0001\u0000\u0000\u0000\u0000"+ - "j\u0001\u0000\u0000\u0000\u0000l\u0001\u0000\u0000\u0000\u0000n\u0001"+ - "\u0000\u0000\u0000\u0000p\u0001\u0000\u0000\u0000\u0000r\u0001\u0000\u0000"+ - "\u0000\u0000t\u0001\u0000\u0000\u0000\u0000v\u0001\u0000\u0000\u0000\u0000"+ - "x\u0001\u0000\u0000\u0000\u0000z\u0001\u0000\u0000\u0000\u0001\u008c\u0001"+ - "\u0000\u0000\u0000\u0001\u008e\u0001\u0000\u0000\u0000\u0001\u0090\u0001"+ - "\u0000\u0000\u0000\u0001\u0092\u0001\u0000\u0000\u0000\u0002\u0094\u0001"+ - "\u0000\u0000\u0000\u0004\u0099\u0001\u0000\u0000\u0000\u0006\u009c\u0001"+ - "\u0000\u0000\u0000\b\u00a2\u0001\u0000\u0000\u0000\n\u00a5\u0001\u0000"+ - "\u0000\u0000\f\u00a7\u0001\u0000\u0000\u0000\u000e\u00aa\u0001\u0000\u0000"+ - "\u0000\u0010\u00ac\u0001\u0000\u0000\u0000\u0012\u00ae\u0001\u0000\u0000"+ - "\u0000\u0014\u00b0\u0001\u0000\u0000\u0000\u0016\u00b2\u0001\u0000\u0000"+ - "\u0000\u0018\u00b4\u0001\u0000\u0000\u0000\u001a\u00b6\u0001\u0000\u0000"+ - "\u0000\u001c\u00b8\u0001\u0000\u0000\u0000\u001e\u00ba\u0001\u0000\u0000"+ - "\u0000 \u00bc\u0001\u0000\u0000\u0000\"\u00be\u0001\u0000\u0000\u0000"+ - "$\u00c0\u0001\u0000\u0000\u0000&\u00c2\u0001\u0000\u0000\u0000(\u00c4"+ - "\u0001\u0000\u0000\u0000*\u00c7\u0001\u0000\u0000\u0000,\u00c9\u0001\u0000"+ - "\u0000\u0000.\u00cc\u0001\u0000\u0000\u00000\u00cf\u0001\u0000\u0000\u0000"+ - "2\u00d1\u0001\u0000\u0000\u00004\u00d4\u0001\u0000\u0000\u00006\u00d6"+ - "\u0001\u0000\u0000\u00008\u00d9\u0001\u0000\u0000\u0000:\u00db\u0001\u0000"+ - "\u0000\u0000<\u00de\u0001\u0000\u0000\u0000>\u00e1\u0001\u0000\u0000\u0000"+ - "@\u00e4\u0001\u0000\u0000\u0000B\u00e7\u0001\u0000\u0000\u0000D\u00e9"+ - "\u0001\u0000\u0000\u0000F\u00ec\u0001\u0000\u0000\u0000H\u00ef\u0001\u0000"+ - "\u0000\u0000J\u00f1\u0001\u0000\u0000\u0000L\u00f4\u0001\u0000\u0000\u0000"+ - "N\u00f6\u0001\u0000\u0000\u0000P\u00fb\u0001\u0000\u0000\u0000R\u0100"+ - "\u0001\u0000\u0000\u0000T\u0104\u0001\u0000\u0000\u0000V\u0107\u0001\u0000"+ - "\u0000\u0000X\u010b\u0001\u0000\u0000\u0000Z\u0110\u0001\u0000\u0000\u0000"+ - "\\\u0116\u0001\u0000\u0000\u0000^\u011a\u0001\u0000\u0000\u0000`\u011f"+ - "\u0001\u0000\u0000\u0000b\u0121\u0001\u0000\u0000\u0000d\u0129\u0001\u0000"+ - "\u0000\u0000f\u012c\u0001\u0000\u0000\u0000h\u012f\u0001\u0000\u0000\u0000"+ - "j\u0132\u0001\u0000\u0000\u0000l\u0135\u0001\u0000\u0000\u0000n\u0138"+ - "\u0001\u0000\u0000\u0000p\u013d\u0001\u0000\u0000\u0000r\u0174\u0001\u0000"+ - "\u0000\u0000t\u0177\u0001\u0000\u0000\u0000v\u0180\u0001\u0000\u0000\u0000"+ - "x\u0182\u0001\u0000\u0000\u0000z\u018d\u0001\u0000\u0000\u0000|\u0198"+ - "\u0001\u0000\u0000\u0000~\u019a\u0001\u0000\u0000\u0000\u0080\u019c\u0001"+ - "\u0000\u0000\u0000\u0082\u01b6\u0001\u0000\u0000\u0000\u0084\u01b8\u0001"+ - "\u0000\u0000\u0000\u0086\u01ba\u0001\u0000\u0000\u0000\u0088\u01bd\u0001"+ - "\u0000\u0000\u0000\u008a\u01bf\u0001\u0000\u0000\u0000\u008c\u01c1\u0001"+ - "\u0000\u0000\u0000\u008e\u01c4\u0001\u0000\u0000\u0000\u0090\u01cb\u0001"+ - "\u0000\u0000\u0000\u0092\u01cd\u0001\u0000\u0000\u0000\u0094\u0095\u0005"+ - ";\u0000\u0000\u0095\u0003\u0001\u0000\u0000\u0000\u0096\u0097\u0005\r"+ - "\u0000\u0000\u0097\u009a\u0005\n\u0000\u0000\u0098\u009a\u0007\u0000\u0000"+ - "\u0000\u0099\u0096\u0001\u0000\u0000\u0000\u0099\u0098\u0001\u0000\u0000"+ - "\u0000\u009a\u0005\u0001\u0000\u0000\u0000\u009b\u009d\u0007\u0001\u0000"+ - "\u0000\u009c\u009b\u0001\u0000\u0000\u0000\u009d\u009e\u0001\u0000\u0000"+ - "\u0000\u009e\u009c\u0001\u0000\u0000\u0000\u009e\u009f\u0001\u0000\u0000"+ - "\u0000\u009f\u00a0\u0001\u0000\u0000\u0000\u00a0\u00a1\u0006\u0002\u0000"+ - "\u0000\u00a1\u0007\u0001\u0000\u0000\u0000\u00a2\u00a3\u0005+\u0000\u0000"+ - "\u00a3\u00a4\u0005+\u0000\u0000\u00a4\t\u0001\u0000\u0000\u0000\u00a5"+ - "\u00a6\u0005+\u0000\u0000\u00a6\u000b\u0001\u0000\u0000\u0000\u00a7\u00a8"+ - "\u0005-\u0000\u0000\u00a8\u00a9\u0005-\u0000\u0000\u00a9\r\u0001\u0000"+ - "\u0000\u0000\u00aa\u00ab\u0005-\u0000\u0000\u00ab\u000f\u0001\u0000\u0000"+ - "\u0000\u00ac\u00ad\u0005:\u0000\u0000\u00ad\u0011\u0001\u0000\u0000\u0000"+ - "\u00ae\u00af\u0005.\u0000\u0000\u00af\u0013\u0001\u0000\u0000\u0000\u00b0"+ - "\u00b1\u0005,\u0000\u0000\u00b1\u0015\u0001\u0000\u0000\u0000\u00b2\u00b3"+ - "\u0005*\u0000\u0000\u00b3\u0017\u0001\u0000\u0000\u0000\u00b4\u00b5\u0005"+ - "/\u0000\u0000\u00b5\u0019\u0001\u0000\u0000\u0000\u00b6\u00b7\u0005%\u0000"+ - "\u0000\u00b7\u001b\u0001\u0000\u0000\u0000\u00b8\u00b9\u0005(\u0000\u0000"+ - "\u00b9\u001d\u0001\u0000\u0000\u0000\u00ba\u00bb\u0005)\u0000\u0000\u00bb"+ - "\u001f\u0001\u0000\u0000\u0000\u00bc\u00bd\u0005[\u0000\u0000\u00bd!\u0001"+ - "\u0000\u0000\u0000\u00be\u00bf\u0005]\u0000\u0000\u00bf#\u0001\u0000\u0000"+ - "\u0000\u00c0\u00c1\u0005#\u0000\u0000\u00c1%\u0001\u0000\u0000\u0000\u00c2"+ - "\u00c3\u0005@\u0000\u0000\u00c3\'\u0001\u0000\u0000\u0000\u00c4\u00c5"+ - "\u0005^\u0000\u0000\u00c5\u00c6\u0005[\u0000\u0000\u00c6)\u0001\u0000"+ - "\u0000\u0000\u00c7\u00c8\u0005^\u0000\u0000\u00c8+\u0001\u0000\u0000\u0000"+ - "\u00c9\u00ca\u0005!\u0000\u0000\u00ca\u00cb\u0005=\u0000\u0000\u00cb-"+ - "\u0001\u0000\u0000\u0000\u00cc\u00cd\u0005!\u0000\u0000\u00cd\u00ce\u0005"+ - "[\u0000\u0000\u00ce/\u0001\u0000\u0000\u0000\u00cf\u00d0\u0005!\u0000"+ - "\u0000\u00d01\u0001\u0000\u0000\u0000\u00d1\u00d2\u0005=\u0000\u0000\u00d2"+ - "\u00d3\u0005=\u0000\u0000\u00d33\u0001\u0000\u0000\u0000\u00d4\u00d5\u0005"+ - "=\u0000\u0000\u00d55\u0001\u0000\u0000\u0000\u00d6\u00d7\u0005&\u0000"+ - "\u0000\u00d7\u00d8\u0005&\u0000\u0000\u00d87\u0001\u0000\u0000\u0000\u00d9"+ - "\u00da\u0005&\u0000\u0000\u00da9\u0001\u0000\u0000\u0000\u00db\u00dc\u0005"+ - "|\u0000\u0000\u00dc\u00dd\u0005|\u0000\u0000\u00dd;\u0001\u0000\u0000"+ - "\u0000\u00de\u00df\u0005?\u0000\u0000\u00df\u00e0\u0005[\u0000\u0000\u00e0"+ - "=\u0001\u0000\u0000\u0000\u00e1\u00e2\u0005?\u0000\u0000\u00e2\u00e3\u0005"+ - ":\u0000\u0000\u00e3?\u0001\u0000\u0000\u0000\u00e4\u00e5\u0005?\u0000"+ - "\u0000\u00e5\u00e6\u0005.\u0000\u0000\u00e6A\u0001\u0000\u0000\u0000\u00e7"+ - "\u00e8\u0005?\u0000\u0000\u00e8C\u0001\u0000\u0000\u0000\u00e9\u00ea\u0005"+ - "$\u0000\u0000\u00ea\u00eb\u0005[\u0000\u0000\u00ebE\u0001\u0000\u0000"+ - "\u0000\u00ec\u00ed\u0005>\u0000\u0000\u00ed\u00ee\u0005=\u0000\u0000\u00ee"+ - "G\u0001\u0000\u0000\u0000\u00ef\u00f0\u0005>\u0000\u0000\u00f0I\u0001"+ - "\u0000\u0000\u0000\u00f1\u00f2\u0005<\u0000\u0000\u00f2\u00f3\u0005=\u0000"+ - "\u0000\u00f3K\u0001\u0000\u0000\u0000\u00f4\u00f5\u0005<\u0000\u0000\u00f5"+ - "M\u0001\u0000\u0000\u0000\u00f6\u00f7\u0005{\u0000\u0000\u00f7\u00f8\u0006"+ - "&\u0001\u0000\u00f8\u00f9\u0001\u0000\u0000\u0000\u00f9\u00fa\u0006&\u0002"+ - "\u0000\u00faO\u0001\u0000\u0000\u0000\u00fb\u00fc\u0005}\u0000\u0000\u00fc"+ - "\u00fd\u0006\'\u0003\u0000\u00fd\u00fe\u0001\u0000\u0000\u0000\u00fe\u00ff"+ - "\u0006\'\u0004\u0000\u00ffQ\u0001\u0000\u0000\u0000\u0100\u0101\u0005"+ - "`\u0000\u0000\u0101\u0102\u0001\u0000\u0000\u0000\u0102\u0103\u0006(\u0005"+ - "\u0000\u0103S\u0001\u0000\u0000\u0000\u0104\u0105\u0005o\u0000\u0000\u0105"+ - "\u0106\u0005r\u0000\u0000\u0106U\u0001\u0000\u0000\u0000\u0107\u0108\u0005"+ - "a\u0000\u0000\u0108\u0109\u0005n\u0000\u0000\u0109\u010a\u0005d\u0000"+ - "\u0000\u010aW\u0001\u0000\u0000\u0000\u010b\u010c\u0005t\u0000\u0000\u010c"+ - "\u010d\u0005r\u0000\u0000\u010d\u010e\u0005u\u0000\u0000\u010e\u010f\u0005"+ - "e\u0000\u0000\u010fY\u0001\u0000\u0000\u0000\u0110\u0111\u0005f\u0000"+ - "\u0000\u0111\u0112\u0005a\u0000\u0000\u0112\u0113\u0005l\u0000\u0000\u0113"+ - "\u0114\u0005s\u0000\u0000\u0114\u0115\u0005e\u0000\u0000\u0115[\u0001"+ - "\u0000\u0000\u0000\u0116\u0117\u0005n\u0000\u0000\u0117\u0118\u0005e\u0000"+ - "\u0000\u0118\u0119\u0005w\u0000\u0000\u0119]\u0001\u0000\u0000\u0000\u011a"+ - "\u011b\u0005n\u0000\u0000\u011b\u011c\u0005u\u0000\u0000\u011c\u011d\u0005"+ - "l\u0000\u0000\u011d\u011e\u0005l\u0000\u0000\u011e_\u0001\u0000\u0000"+ - "\u0000\u011f\u0120\u0005T\u0000\u0000\u0120a\u0001\u0000\u0000\u0000\u0121"+ - "\u0122\u0005m\u0000\u0000\u0122\u0123\u0005a\u0000\u0000\u0123\u0124\u0005"+ - "t\u0000\u0000\u0124\u0125\u0005c\u0000\u0000\u0125\u0126\u0005h\u0000"+ - "\u0000\u0126\u0127\u0005e\u0000\u0000\u0127\u0128\u0005s\u0000\u0000\u0128"+ - "c\u0001\u0000\u0000\u0000\u0129\u012a\u0005g\u0000\u0000\u012a\u012b\u0005"+ - "t\u0000\u0000\u012be\u0001\u0000\u0000\u0000\u012c\u012d\u0005g\u0000"+ - "\u0000\u012d\u012e\u0005e\u0000\u0000\u012eg\u0001\u0000\u0000\u0000\u012f"+ - "\u0130\u0005l\u0000\u0000\u0130\u0131\u0005e\u0000\u0000\u0131i\u0001"+ - "\u0000\u0000\u0000\u0132\u0133\u0005l\u0000\u0000\u0133\u0134\u0005t\u0000"+ - "\u0000\u0134k\u0001\u0000\u0000\u0000\u0135\u0136\u0005e\u0000\u0000\u0136"+ - "\u0137\u0005q\u0000\u0000\u0137m\u0001\u0000\u0000\u0000\u0138\u0139\u0005"+ - "n\u0000\u0000\u0139\u013a\u0005e\u0000\u0000\u013ao\u0001\u0000\u0000"+ - "\u0000\u013b\u013e\u0003\u0088C\u0000\u013c\u013e\u0005_\u0000\u0000\u013d"+ - "\u013b\u0001\u0000\u0000\u0000\u013d\u013c\u0001\u0000\u0000\u0000\u013e"+ - "\u0144\u0001\u0000\u0000\u0000\u013f\u0143\u0003\u0088C\u0000\u0140\u0143"+ - "\u0003\u008aD\u0000\u0141\u0143\u0007\u0002\u0000\u0000\u0142\u013f\u0001"+ - "\u0000\u0000\u0000\u0142\u0140\u0001\u0000\u0000\u0000\u0142\u0141\u0001"+ - "\u0000\u0000\u0000\u0143\u0146\u0001\u0000\u0000\u0000\u0144\u0142\u0001"+ - "\u0000\u0000\u0000\u0144\u0145\u0001\u0000\u0000\u0000\u0145q\u0001\u0000"+ - "\u0000\u0000\u0146\u0144\u0001\u0000\u0000\u0000\u0147\u0149\u0005.\u0000"+ - "\u0000\u0148\u014a\u0003\u0080?\u0000\u0149\u0148\u0001\u0000\u0000\u0000"+ - "\u014a\u014b\u0001\u0000\u0000\u0000\u014b\u0149\u0001\u0000\u0000\u0000"+ - "\u014b\u014c\u0001\u0000\u0000\u0000\u014c\u014e\u0001\u0000\u0000\u0000"+ - "\u014d\u014f\u0003\u0082@\u0000\u014e\u014d\u0001\u0000\u0000\u0000\u014e"+ - "\u014f\u0001\u0000\u0000\u0000\u014f\u0151\u0001\u0000\u0000\u0000\u0150"+ - "\u0152\u0003\u0086B\u0000\u0151\u0150\u0001\u0000\u0000\u0000\u0151\u0152"+ - "\u0001\u0000\u0000\u0000\u0152\u0175\u0001\u0000\u0000\u0000\u0153\u0155"+ - "\u0003\u0080?\u0000\u0154\u0153\u0001\u0000\u0000\u0000\u0155\u0156\u0001"+ - "\u0000\u0000\u0000\u0156\u0154\u0001\u0000\u0000\u0000\u0156\u0157\u0001"+ - "\u0000\u0000\u0000\u0157\u0158\u0001\u0000\u0000\u0000\u0158\u015a\u0005"+ - ".\u0000\u0000\u0159\u015b\u0003\u0080?\u0000\u015a\u0159\u0001\u0000\u0000"+ - "\u0000\u015b\u015c\u0001\u0000\u0000\u0000\u015c\u015a\u0001\u0000\u0000"+ - "\u0000\u015c\u015d\u0001\u0000\u0000\u0000\u015d\u015f\u0001\u0000\u0000"+ - "\u0000\u015e\u0160\u0003\u0082@\u0000\u015f\u015e\u0001\u0000\u0000\u0000"+ - "\u015f\u0160\u0001\u0000\u0000\u0000\u0160\u0162\u0001\u0000\u0000\u0000"+ - "\u0161\u0163\u0003\u0086B\u0000\u0162\u0161\u0001\u0000\u0000\u0000\u0162"+ - "\u0163\u0001\u0000\u0000\u0000\u0163\u0175\u0001\u0000\u0000\u0000\u0164"+ - "\u0166\u0003\u0080?\u0000\u0165\u0164\u0001\u0000\u0000\u0000\u0166\u0167"+ - "\u0001\u0000\u0000\u0000\u0167\u0165\u0001\u0000\u0000\u0000\u0167\u0168"+ - "\u0001\u0000\u0000\u0000\u0168\u0169\u0001\u0000\u0000\u0000\u0169\u016b"+ - "\u0003\u0082@\u0000\u016a\u016c\u0003\u0086B\u0000\u016b\u016a\u0001\u0000"+ - "\u0000\u0000\u016b\u016c\u0001\u0000\u0000\u0000\u016c\u0175\u0001\u0000"+ - "\u0000\u0000\u016d\u016f\u0003\u0080?\u0000\u016e\u016d\u0001\u0000\u0000"+ - "\u0000\u016f\u0170\u0001\u0000\u0000\u0000\u0170\u016e\u0001\u0000\u0000"+ - "\u0000\u0170\u0171\u0001\u0000\u0000\u0000\u0171\u0172\u0001\u0000\u0000"+ - "\u0000\u0172\u0173\u0003\u0086B\u0000\u0173\u0175\u0001\u0000\u0000\u0000"+ - "\u0174\u0147\u0001\u0000\u0000\u0000\u0174\u0154\u0001\u0000\u0000\u0000"+ - "\u0174\u0165\u0001\u0000\u0000\u0000\u0174\u016e\u0001\u0000\u0000\u0000"+ - "\u0175s\u0001\u0000\u0000\u0000\u0176\u0178\u0003\u0080?\u0000\u0177\u0176"+ - "\u0001\u0000\u0000\u0000\u0178\u0179\u0001\u0000\u0000\u0000\u0179\u0177"+ - "\u0001\u0000\u0000\u0000\u0179\u017a\u0001\u0000\u0000\u0000\u017a\u017c"+ - "\u0001\u0000\u0000\u0000\u017b\u017d\u0003|=\u0000\u017c\u017b\u0001\u0000"+ - "\u0000\u0000\u017c\u017d\u0001\u0000\u0000\u0000\u017du\u0001\u0000\u0000"+ - "\u0000\u017e\u0181\u0003x;\u0000\u017f\u0181\u0003z<\u0000\u0180\u017e"+ - "\u0001\u0000\u0000\u0000\u0180\u017f\u0001\u0000\u0000\u0000\u0181w\u0001"+ - "\u0000\u0000\u0000\u0182\u0188\u0005\'\u0000\u0000\u0183\u0184\u0005\'"+ - "\u0000\u0000\u0184\u0187\u0005\'\u0000\u0000\u0185\u0187\b\u0003\u0000"+ - "\u0000\u0186\u0183\u0001\u0000\u0000\u0000\u0186\u0185\u0001\u0000\u0000"+ - "\u0000\u0187\u018a\u0001\u0000\u0000\u0000\u0188\u0186\u0001\u0000\u0000"+ - "\u0000\u0188\u0189\u0001\u0000\u0000\u0000\u0189\u018b\u0001\u0000\u0000"+ - "\u0000\u018a\u0188\u0001\u0000\u0000\u0000\u018b\u018c\u0005\'\u0000\u0000"+ - "\u018cy\u0001\u0000\u0000\u0000\u018d\u0193\u0005\"\u0000\u0000\u018e"+ - "\u018f\u0005\"\u0000\u0000\u018f\u0192\u0005\"\u0000\u0000\u0190\u0192"+ - "\b\u0004\u0000\u0000\u0191\u018e\u0001\u0000\u0000\u0000\u0191\u0190\u0001"+ - "\u0000\u0000\u0000\u0192\u0195\u0001\u0000\u0000\u0000\u0193\u0191\u0001"+ - "\u0000\u0000\u0000\u0193\u0194\u0001\u0000\u0000\u0000\u0194\u0196\u0001"+ - "\u0000\u0000\u0000\u0195\u0193\u0001\u0000\u0000\u0000\u0196\u0197\u0005"+ - "\"\u0000\u0000\u0197{\u0001\u0000\u0000\u0000\u0198\u0199\u0007\u0005"+ - "\u0000\u0000\u0199}\u0001\u0000\u0000\u0000\u019a\u019b\u0007\u0006\u0000"+ - "\u0000\u019b\u007f\u0001\u0000\u0000\u0000\u019c\u019d\u0007\u0007\u0000"+ - "\u0000\u019d\u0081\u0001\u0000\u0000\u0000\u019e\u01a2\u0005e\u0000\u0000"+ - "\u019f\u01a1\u0003\u0084A\u0000\u01a0\u019f\u0001\u0000\u0000\u0000\u01a1"+ - "\u01a4\u0001\u0000\u0000\u0000\u01a2\u01a0\u0001\u0000\u0000\u0000\u01a2"+ - "\u01a3\u0001\u0000\u0000\u0000\u01a3\u01a6\u0001\u0000\u0000\u0000\u01a4"+ - "\u01a2\u0001\u0000\u0000\u0000\u01a5\u01a7\u0003\u0080?\u0000\u01a6\u01a5"+ - "\u0001\u0000\u0000\u0000\u01a7\u01a8\u0001\u0000\u0000\u0000\u01a8\u01a6"+ - "\u0001\u0000\u0000\u0000\u01a8\u01a9\u0001\u0000\u0000\u0000\u01a9\u01b7"+ - "\u0001\u0000\u0000\u0000\u01aa\u01ae\u0005E\u0000\u0000\u01ab\u01ad\u0003"+ - "\u0084A\u0000\u01ac\u01ab\u0001\u0000\u0000\u0000\u01ad\u01b0\u0001\u0000"+ - "\u0000\u0000\u01ae\u01ac\u0001\u0000\u0000\u0000\u01ae\u01af\u0001\u0000"+ - "\u0000\u0000\u01af\u01b2\u0001\u0000\u0000\u0000\u01b0\u01ae\u0001\u0000"+ - "\u0000\u0000\u01b1\u01b3\u0003\u0080?\u0000\u01b2\u01b1\u0001\u0000\u0000"+ - "\u0000\u01b3\u01b4\u0001\u0000\u0000\u0000\u01b4\u01b2\u0001\u0000\u0000"+ - "\u0000\u01b4\u01b5\u0001\u0000\u0000\u0000\u01b5\u01b7\u0001\u0000\u0000"+ - "\u0000\u01b6\u019e\u0001\u0000\u0000\u0000\u01b6\u01aa\u0001\u0000\u0000"+ - "\u0000\u01b7\u0083\u0001\u0000\u0000\u0000\u01b8\u01b9\u0007\b\u0000\u0000"+ - "\u01b9\u0085\u0001\u0000\u0000\u0000\u01ba\u01bb\u0007\t\u0000\u0000\u01bb"+ - "\u0087\u0001\u0000\u0000\u0000\u01bc\u01be\u0007\n\u0000\u0000\u01bd\u01bc"+ - "\u0001\u0000\u0000\u0000\u01be\u0089\u0001\u0000\u0000\u0000\u01bf\u01c0"+ - "\u0007\u0007\u0000\u0000\u01c0\u008b\u0001\u0000\u0000\u0000\u01c1\u01c2"+ - "\u0005`\u0000\u0000\u01c2\u01c3\u0005`\u0000\u0000\u01c3\u008d\u0001\u0000"+ - "\u0000\u0000\u01c4\u01c5\u0005#\u0000\u0000\u01c5\u01c6\u0005{\u0000\u0000"+ - "\u01c6\u01c7\u0001\u0000\u0000\u0000\u01c7\u01c8\u0006F\u0006\u0000\u01c8"+ - "\u01c9\u0001\u0000\u0000\u0000\u01c9\u01ca\u0006F\u0002\u0000\u01ca\u008f"+ - "\u0001\u0000\u0000\u0000\u01cb\u01cc\b\u000b\u0000\u0000\u01cc\u0091\u0001"+ - "\u0000\u0000\u0000\u01cd\u01ce\u0005`\u0000\u0000\u01ce\u01cf\u0001\u0000"+ - "\u0000\u0000\u01cf\u01d0\u0006H\u0007\u0000\u01d0\u01d1\u0006H\u0004\u0000"+ - "\u01d1\u0093\u0001\u0000\u0000\u0000\u001f\u0000\u0001\u0099\u009e\u013d"+ - "\u0142\u0144\u014b\u014e\u0151\u0156\u015c\u015f\u0162\u0167\u016b\u0170"+ - "\u0174\u0179\u017c\u0180\u0186\u0188\u0191\u0193\u01a2\u01a8\u01ae\u01b4"+ - "\u01b6\u01bd\b\u0000\u0001\u0000\u0001&\u0000\u0005\u0000\u0000\u0001"+ - "\'\u0001\u0004\u0000\u0000\u0005\u0001\u0000\u0001F\u0002\u0007(\u0000"; + "H\u0007H\u0002I\u0007I\u0001\u0000\u0001\u0000\u0001\u0001\u0001\u0001"+ + "\u0001\u0001\u0003\u0001\u009c\b\u0001\u0001\u0002\u0004\u0002\u009f\b"+ + "\u0002\u000b\u0002\f\u0002\u00a0\u0001\u0002\u0001\u0002\u0001\u0003\u0001"+ + "\u0003\u0001\u0003\u0001\u0004\u0001\u0004\u0001\u0005\u0001\u0005\u0001"+ + "\u0005\u0001\u0006\u0001\u0006\u0001\u0007\u0001\u0007\u0001\b\u0001\b"+ + "\u0001\t\u0001\t\u0001\n\u0001\n\u0001\u000b\u0001\u000b\u0001\f\u0001"+ + "\f\u0001\r\u0001\r\u0001\u000e\u0001\u000e\u0001\u000f\u0001\u000f\u0001"+ + "\u0010\u0001\u0010\u0001\u0011\u0001\u0011\u0001\u0012\u0001\u0012\u0001"+ + "\u0013\u0001\u0013\u0001\u0013\u0001\u0014\u0001\u0014\u0001\u0015\u0001"+ + "\u0015\u0001\u0015\u0001\u0016\u0001\u0016\u0001\u0016\u0001\u0017\u0001"+ + "\u0017\u0001\u0018\u0001\u0018\u0001\u0018\u0001\u0019\u0001\u0019\u0001"+ + "\u001a\u0001\u001a\u0001\u001a\u0001\u001b\u0001\u001b\u0001\u001c\u0001"+ + "\u001c\u0001\u001c\u0001\u001d\u0001\u001d\u0001\u001d\u0001\u001e\u0001"+ + "\u001e\u0001\u001e\u0001\u001f\u0001\u001f\u0001\u001f\u0001 \u0001 \u0001"+ + "!\u0001!\u0001!\u0001\"\u0001\"\u0001\"\u0001#\u0001#\u0001$\u0001$\u0001"+ + "$\u0001%\u0001%\u0001&\u0001&\u0001&\u0001&\u0001&\u0001\'\u0001\'\u0001"+ + "\'\u0001\'\u0001\'\u0001(\u0001(\u0001(\u0001(\u0001)\u0001)\u0001)\u0001"+ + "*\u0001*\u0001*\u0001*\u0001+\u0001+\u0001+\u0001+\u0001+\u0001,\u0001"+ + ",\u0001,\u0001,\u0001,\u0001,\u0001-\u0001-\u0001-\u0001-\u0001.\u0001"+ + ".\u0001.\u0001.\u0001.\u0001/\u0001/\u00010\u00010\u00010\u00010\u0001"+ + "0\u00010\u00010\u00010\u00011\u00011\u00011\u00012\u00012\u00012\u0001"+ + "3\u00013\u00013\u00014\u00014\u00014\u00015\u00015\u00015\u00016\u0001"+ + "6\u00016\u00017\u00017\u00037\u0140\b7\u00017\u00017\u00017\u00057\u0145"+ + "\b7\n7\f7\u0148\t7\u00018\u00018\u00048\u014c\b8\u000b8\f8\u014d\u0001"+ + "8\u00038\u0151\b8\u00018\u00038\u0154\b8\u00018\u00048\u0157\b8\u000b"+ + "8\f8\u0158\u00018\u00018\u00048\u015d\b8\u000b8\f8\u015e\u00018\u0003"+ + "8\u0162\b8\u00018\u00038\u0165\b8\u00018\u00048\u0168\b8\u000b8\f8\u0169"+ + "\u00018\u00018\u00038\u016e\b8\u00018\u00048\u0171\b8\u000b8\f8\u0172"+ + "\u00018\u00018\u00038\u0177\b8\u00019\u00049\u017a\b9\u000b9\f9\u017b"+ + "\u00019\u00039\u017f\b9\u0001:\u0001:\u0003:\u0183\b:\u0001;\u0001;\u0001"+ + ";\u0001;\u0005;\u0189\b;\n;\f;\u018c\t;\u0001;\u0001;\u0001<\u0001<\u0001"+ + "<\u0001<\u0005<\u0194\b<\n<\f<\u0197\t<\u0001<\u0001<\u0001=\u0001=\u0001"+ + "=\u0001=\u0005=\u019f\b=\n=\f=\u01a2\t=\u0001=\u0001=\u0001>\u0001>\u0001"+ + "?\u0001?\u0001@\u0001@\u0001A\u0001A\u0005A\u01ae\bA\nA\fA\u01b1\tA\u0001"+ + "A\u0004A\u01b4\bA\u000bA\fA\u01b5\u0001A\u0001A\u0005A\u01ba\bA\nA\fA"+ + "\u01bd\tA\u0001A\u0004A\u01c0\bA\u000bA\fA\u01c1\u0003A\u01c4\bA\u0001"+ + "B\u0001B\u0001C\u0001C\u0001D\u0003D\u01cb\bD\u0001E\u0001E\u0001F\u0001"+ + "F\u0001F\u0001G\u0001G\u0001G\u0001G\u0001G\u0001G\u0001G\u0001H\u0001"+ + "H\u0001I\u0001I\u0001I\u0001I\u0001I\u0001\u01a0\u0000J\u0002\u0001\u0004"+ + "\u0000\u0006\u0002\b\u0003\n\u0004\f\u0005\u000e\u0006\u0010\u0007\u0012"+ + "\b\u0014\t\u0016\n\u0018\u000b\u001a\f\u001c\r\u001e\u000e \u000f\"\u0010"+ + "$\u0011&\u0012(\u0013*\u0014,\u0015.\u00160\u00172\u00184\u00196\u001a"+ + "8\u001b:\u001c<\u001d>\u001e@\u001fB D!F\"H#J$L%N&P\'R(T)V*X+Z,\\-^.`"+ + "/b0d1f2h3j4l5n6p7r8t9v:x;z<|=~\u0000\u0080\u0000\u0082\u0000\u0084\u0000"+ + "\u0086\u0000\u0088\u0000\u008a\u0000\u008c\u0000\u008e>\u0090?\u0092@"+ + "\u0094\u0000\u0002\u0000\u0001\f\u0003\u0000\n\n\r\r\u2028\u2029\u0003"+ + "\u0000\t\n\r\r \u0002\u0000$$__\u0002\u0000\n\n\'\'\u0002\u0000\n\n\""+ + "\"\u0002\u0000LLll\u0003\u000009AFaf\u0001\u000009\u0002\u0000++--\u0004"+ + "\u0000DDFFddff\u0293\u0000AZaz\u00aa\u00aa\u00b5\u00b5\u00ba\u00ba\u00c0"+ + "\u00d6\u00d8\u00f6\u00f8\u02c1\u02c6\u02d1\u02e0\u02e4\u02ec\u02ec\u02ee"+ + "\u02ee\u0370\u0374\u0376\u0377\u037a\u037d\u037f\u037f\u0386\u0386\u0388"+ + "\u038a\u038c\u038c\u038e\u03a1\u03a3\u03f5\u03f7\u0481\u048a\u052f\u0531"+ + "\u0556\u0559\u0559\u0560\u0588\u05d0\u05ea\u05ef\u05f2\u0620\u064a\u066e"+ + "\u066f\u0671\u06d3\u06d5\u06d5\u06e5\u06e6\u06ee\u06ef\u06fa\u06fc\u06ff"+ + "\u06ff\u0710\u0710\u0712\u072f\u074d\u07a5\u07b1\u07b1\u07ca\u07ea\u07f4"+ + "\u07f5\u07fa\u07fa\u0800\u0815\u081a\u081a\u0824\u0824\u0828\u0828\u0840"+ + "\u0858\u0860\u086a\u0870\u0887\u0889\u088e\u08a0\u08c9\u0904\u0939\u093d"+ + "\u093d\u0950\u0950\u0958\u0961\u0971\u0980\u0985\u098c\u098f\u0990\u0993"+ + "\u09a8\u09aa\u09b0\u09b2\u09b2\u09b6\u09b9\u09bd\u09bd\u09ce\u09ce\u09dc"+ + "\u09dd\u09df\u09e1\u09f0\u09f1\u09fc\u09fc\u0a05\u0a0a\u0a0f\u0a10\u0a13"+ + "\u0a28\u0a2a\u0a30\u0a32\u0a33\u0a35\u0a36\u0a38\u0a39\u0a59\u0a5c\u0a5e"+ + "\u0a5e\u0a72\u0a74\u0a85\u0a8d\u0a8f\u0a91\u0a93\u0aa8\u0aaa\u0ab0\u0ab2"+ + "\u0ab3\u0ab5\u0ab9\u0abd\u0abd\u0ad0\u0ad0\u0ae0\u0ae1\u0af9\u0af9\u0b05"+ + "\u0b0c\u0b0f\u0b10\u0b13\u0b28\u0b2a\u0b30\u0b32\u0b33\u0b35\u0b39\u0b3d"+ + "\u0b3d\u0b5c\u0b5d\u0b5f\u0b61\u0b71\u0b71\u0b83\u0b83\u0b85\u0b8a\u0b8e"+ + "\u0b90\u0b92\u0b95\u0b99\u0b9a\u0b9c\u0b9c\u0b9e\u0b9f\u0ba3\u0ba4\u0ba8"+ + "\u0baa\u0bae\u0bb9\u0bd0\u0bd0\u0c05\u0c0c\u0c0e\u0c10\u0c12\u0c28\u0c2a"+ + "\u0c39\u0c3d\u0c3d\u0c58\u0c5a\u0c5d\u0c5d\u0c60\u0c61\u0c80\u0c80\u0c85"+ + "\u0c8c\u0c8e\u0c90\u0c92\u0ca8\u0caa\u0cb3\u0cb5\u0cb9\u0cbd\u0cbd\u0cdd"+ + "\u0cde\u0ce0\u0ce1\u0cf1\u0cf2\u0d04\u0d0c\u0d0e\u0d10\u0d12\u0d3a\u0d3d"+ + "\u0d3d\u0d4e\u0d4e\u0d54\u0d56\u0d5f\u0d61\u0d7a\u0d7f\u0d85\u0d96\u0d9a"+ + "\u0db1\u0db3\u0dbb\u0dbd\u0dbd\u0dc0\u0dc6\u0e01\u0e30\u0e32\u0e33\u0e40"+ + "\u0e46\u0e81\u0e82\u0e84\u0e84\u0e86\u0e8a\u0e8c\u0ea3\u0ea5\u0ea5\u0ea7"+ + "\u0eb0\u0eb2\u0eb3\u0ebd\u0ebd\u0ec0\u0ec4\u0ec6\u0ec6\u0edc\u0edf\u0f00"+ + "\u0f00\u0f40\u0f47\u0f49\u0f6c\u0f88\u0f8c\u1000\u102a\u103f\u103f\u1050"+ + "\u1055\u105a\u105d\u1061\u1061\u1065\u1066\u106e\u1070\u1075\u1081\u108e"+ + "\u108e\u10a0\u10c5\u10c7\u10c7\u10cd\u10cd\u10d0\u10fa\u10fc\u1248\u124a"+ + "\u124d\u1250\u1256\u1258\u1258\u125a\u125d\u1260\u1288\u128a\u128d\u1290"+ + "\u12b0\u12b2\u12b5\u12b8\u12be\u12c0\u12c0\u12c2\u12c5\u12c8\u12d6\u12d8"+ + "\u1310\u1312\u1315\u1318\u135a\u1380\u138f\u13a0\u13f5\u13f8\u13fd\u1401"+ + "\u166c\u166f\u167f\u1681\u169a\u16a0\u16ea\u16f1\u16f8\u1700\u1711\u171f"+ + "\u1731\u1740\u1751\u1760\u176c\u176e\u1770\u1780\u17b3\u17d7\u17d7\u17dc"+ + "\u17dc\u1820\u1878\u1880\u1884\u1887\u18a8\u18aa\u18aa\u18b0\u18f5\u1900"+ + "\u191e\u1950\u196d\u1970\u1974\u1980\u19ab\u19b0\u19c9\u1a00\u1a16\u1a20"+ + "\u1a54\u1aa7\u1aa7\u1b05\u1b33\u1b45\u1b4c\u1b83\u1ba0\u1bae\u1baf\u1bba"+ + "\u1be5\u1c00\u1c23\u1c4d\u1c4f\u1c5a\u1c7d\u1c80\u1c88\u1c90\u1cba\u1cbd"+ + "\u1cbf\u1ce9\u1cec\u1cee\u1cf3\u1cf5\u1cf6\u1cfa\u1cfa\u1d00\u1dbf\u1e00"+ + "\u1f15\u1f18\u1f1d\u1f20\u1f45\u1f48\u1f4d\u1f50\u1f57\u1f59\u1f59\u1f5b"+ + "\u1f5b\u1f5d\u1f5d\u1f5f\u1f7d\u1f80\u1fb4\u1fb6\u1fbc\u1fbe\u1fbe\u1fc2"+ + "\u1fc4\u1fc6\u1fcc\u1fd0\u1fd3\u1fd6\u1fdb\u1fe0\u1fec\u1ff2\u1ff4\u1ff6"+ + "\u1ffc\u2071\u2071\u207f\u207f\u2090\u209c\u2102\u2102\u2107\u2107\u210a"+ + "\u2113\u2115\u2115\u2119\u211d\u2124\u2124\u2126\u2126\u2128\u2128\u212a"+ + "\u212d\u212f\u2139\u213c\u213f\u2145\u2149\u214e\u214e\u2183\u2184\u2c00"+ + "\u2ce4\u2ceb\u2cee\u2cf2\u2cf3\u2d00\u2d25\u2d27\u2d27\u2d2d\u2d2d\u2d30"+ + "\u2d67\u2d6f\u2d6f\u2d80\u2d96\u2da0\u2da6\u2da8\u2dae\u2db0\u2db6\u2db8"+ + "\u2dbe\u2dc0\u2dc6\u2dc8\u2dce\u2dd0\u2dd6\u2dd8\u2dde\u2e2f\u2e2f\u3005"+ + "\u3006\u3031\u3035\u303b\u303c\u3041\u3096\u309d\u309f\u30a1\u30fa\u30fc"+ + "\u30ff\u3105\u312f\u3131\u318e\u31a0\u31bf\u31f0\u31ff\u3400\u4dbf\u4e00"+ + "\u8000\ua48c\u8000\ua4d0\u8000\ua4fd\u8000\ua500\u8000\ua60c\u8000\ua610"+ + "\u8000\ua61f\u8000\ua62a\u8000\ua62b\u8000\ua640\u8000\ua66e\u8000\ua67f"+ + "\u8000\ua69d\u8000\ua6a0\u8000\ua6e5\u8000\ua717\u8000\ua71f\u8000\ua722"+ + "\u8000\ua788\u8000\ua78b\u8000\ua7ca\u8000\ua7d0\u8000\ua7d1\u8000\ua7d3"+ + "\u8000\ua7d3\u8000\ua7d5\u8000\ua7d9\u8000\ua7f2\u8000\ua801\u8000\ua803"+ + "\u8000\ua805\u8000\ua807\u8000\ua80a\u8000\ua80c\u8000\ua822\u8000\ua840"+ + "\u8000\ua873\u8000\ua882\u8000\ua8b3\u8000\ua8f2\u8000\ua8f7\u8000\ua8fb"+ + "\u8000\ua8fb\u8000\ua8fd\u8000\ua8fe\u8000\ua90a\u8000\ua925\u8000\ua930"+ + "\u8000\ua946\u8000\ua960\u8000\ua97c\u8000\ua984\u8000\ua9b2\u8000\ua9cf"+ + "\u8000\ua9cf\u8000\ua9e0\u8000\ua9e4\u8000\ua9e6\u8000\ua9ef\u8000\ua9fa"+ + "\u8000\ua9fe\u8000\uaa00\u8000\uaa28\u8000\uaa40\u8000\uaa42\u8000\uaa44"+ + "\u8000\uaa4b\u8000\uaa60\u8000\uaa76\u8000\uaa7a\u8000\uaa7a\u8000\uaa7e"+ + "\u8000\uaaaf\u8000\uaab1\u8000\uaab1\u8000\uaab5\u8000\uaab6\u8000\uaab9"+ + "\u8000\uaabd\u8000\uaac0\u8000\uaac0\u8000\uaac2\u8000\uaac2\u8000\uaadb"+ + "\u8000\uaadd\u8000\uaae0\u8000\uaaea\u8000\uaaf2\u8000\uaaf4\u8000\uab01"+ + "\u8000\uab06\u8000\uab09\u8000\uab0e\u8000\uab11\u8000\uab16\u8000\uab20"+ + "\u8000\uab26\u8000\uab28\u8000\uab2e\u8000\uab30\u8000\uab5a\u8000\uab5c"+ + "\u8000\uab69\u8000\uab70\u8000\uabe2\u8000\uac00\u8000\ud7a3\u8000\ud7b0"+ + "\u8000\ud7c6\u8000\ud7cb\u8000\ud7fb\u8000\uf900\u8000\ufa6d\u8000\ufa70"+ + "\u8000\ufad9\u8000\ufb00\u8000\ufb06\u8000\ufb13\u8000\ufb17\u8000\ufb1d"+ + "\u8000\ufb1d\u8000\ufb1f\u8000\ufb28\u8000\ufb2a\u8000\ufb36\u8000\ufb38"+ + "\u8000\ufb3c\u8000\ufb3e\u8000\ufb3e\u8000\ufb40\u8000\ufb41\u8000\ufb43"+ + "\u8000\ufb44\u8000\ufb46\u8000\ufbb1\u8000\ufbd3\u8000\ufd3d\u8000\ufd50"+ + "\u8000\ufd8f\u8000\ufd92\u8000\ufdc7\u8000\ufdf0\u8000\ufdfb\u8000\ufe70"+ + "\u8000\ufe74\u8000\ufe76\u8000\ufefc\u8000\uff21\u8000\uff3a\u8000\uff41"+ + "\u8000\uff5a\u8000\uff66\u8000\uffbe\u8000\uffc2\u8000\uffc7\u8000\uffca"+ + "\u8000\uffcf\u8000\uffd2\u8000\uffd7\u8000\uffda\u8000\uffdc\u8001\u0000"+ + "\u8001\u000b\u8001\r\u8001&\u8001(\u8001:\u8001<\u8001=\u8001?\u8001M"+ + "\u8001P\u8001]\u8001\u0080\u8001\u00fa\u8001\u0280\u8001\u029c\u8001\u02a0"+ + "\u8001\u02d0\u8001\u0300\u8001\u031f\u8001\u032d\u8001\u0340\u8001\u0342"+ + "\u8001\u0349\u8001\u0350\u8001\u0375\u8001\u0380\u8001\u039d\u8001\u03a0"+ + "\u8001\u03c3\u8001\u03c8\u8001\u03cf\u8001\u0400\u8001\u049d\u8001\u04b0"+ + "\u8001\u04d3\u8001\u04d8\u8001\u04fb\u8001\u0500\u8001\u0527\u8001\u0530"+ + "\u8001\u0563\u8001\u0570\u8001\u057a\u8001\u057c\u8001\u058a\u8001\u058c"+ + "\u8001\u0592\u8001\u0594\u8001\u0595\u8001\u0597\u8001\u05a1\u8001\u05a3"+ + "\u8001\u05b1\u8001\u05b3\u8001\u05b9\u8001\u05bb\u8001\u05bc\u8001\u0600"+ + "\u8001\u0736\u8001\u0740\u8001\u0755\u8001\u0760\u8001\u0767\u8001\u0780"+ + "\u8001\u0785\u8001\u0787\u8001\u07b0\u8001\u07b2\u8001\u07ba\u8001\u0800"+ + "\u8001\u0805\u8001\u0808\u8001\u0808\u8001\u080a\u8001\u0835\u8001\u0837"+ + "\u8001\u0838\u8001\u083c\u8001\u083c\u8001\u083f\u8001\u0855\u8001\u0860"+ + "\u8001\u0876\u8001\u0880\u8001\u089e\u8001\u08e0\u8001\u08f2\u8001\u08f4"+ + "\u8001\u08f5\u8001\u0900\u8001\u0915\u8001\u0920\u8001\u0939\u8001\u0980"+ + "\u8001\u09b7\u8001\u09be\u8001\u09bf\u8001\u0a00\u8001\u0a00\u8001\u0a10"+ + "\u8001\u0a13\u8001\u0a15\u8001\u0a17\u8001\u0a19\u8001\u0a35\u8001\u0a60"+ + "\u8001\u0a7c\u8001\u0a80\u8001\u0a9c\u8001\u0ac0\u8001\u0ac7\u8001\u0ac9"+ + "\u8001\u0ae4\u8001\u0b00\u8001\u0b35\u8001\u0b40\u8001\u0b55\u8001\u0b60"+ + "\u8001\u0b72\u8001\u0b80\u8001\u0b91\u8001\u0c00\u8001\u0c48\u8001\u0c80"+ + "\u8001\u0cb2\u8001\u0cc0\u8001\u0cf2\u8001\u0d00\u8001\u0d23\u8001\u0e80"+ + "\u8001\u0ea9\u8001\u0eb0\u8001\u0eb1\u8001\u0f00\u8001\u0f1c\u8001\u0f27"+ + "\u8001\u0f27\u8001\u0f30\u8001\u0f45\u8001\u0f70\u8001\u0f81\u8001\u0fb0"+ + "\u8001\u0fc4\u8001\u0fe0\u8001\u0ff6\u8001\u1003\u8001\u1037\u8001\u1071"+ + "\u8001\u1072\u8001\u1075\u8001\u1075\u8001\u1083\u8001\u10af\u8001\u10d0"+ + "\u8001\u10e8\u8001\u1103\u8001\u1126\u8001\u1144\u8001\u1144\u8001\u1147"+ + "\u8001\u1147\u8001\u1150\u8001\u1172\u8001\u1176\u8001\u1176\u8001\u1183"+ + "\u8001\u11b2\u8001\u11c1\u8001\u11c4\u8001\u11da\u8001\u11da\u8001\u11dc"+ + "\u8001\u11dc\u8001\u1200\u8001\u1211\u8001\u1213\u8001\u122b\u8001\u123f"+ + "\u8001\u1240\u8001\u1280\u8001\u1286\u8001\u1288\u8001\u1288\u8001\u128a"+ + "\u8001\u128d\u8001\u128f\u8001\u129d\u8001\u129f\u8001\u12a8\u8001\u12b0"+ + "\u8001\u12de\u8001\u1305\u8001\u130c\u8001\u130f\u8001\u1310\u8001\u1313"+ + "\u8001\u1328\u8001\u132a\u8001\u1330\u8001\u1332\u8001\u1333\u8001\u1335"+ + "\u8001\u1339\u8001\u133d\u8001\u133d\u8001\u1350\u8001\u1350\u8001\u135d"+ + "\u8001\u1361\u8001\u1400\u8001\u1434\u8001\u1447\u8001\u144a\u8001\u145f"+ + "\u8001\u1461\u8001\u1480\u8001\u14af\u8001\u14c4\u8001\u14c5\u8001\u14c7"+ + "\u8001\u14c7\u8001\u1580\u8001\u15ae\u8001\u15d8\u8001\u15db\u8001\u1600"+ + "\u8001\u162f\u8001\u1644\u8001\u1644\u8001\u1680\u8001\u16aa\u8001\u16b8"+ + "\u8001\u16b8\u8001\u1700\u8001\u171a\u8001\u1740\u8001\u1746\u8001\u1800"+ + "\u8001\u182b\u8001\u18a0\u8001\u18df\u8001\u18ff\u8001\u1906\u8001\u1909"+ + "\u8001\u1909\u8001\u190c\u8001\u1913\u8001\u1915\u8001\u1916\u8001\u1918"+ + "\u8001\u192f\u8001\u193f\u8001\u193f\u8001\u1941\u8001\u1941\u8001\u19a0"+ + "\u8001\u19a7\u8001\u19aa\u8001\u19d0\u8001\u19e1\u8001\u19e1\u8001\u19e3"+ + "\u8001\u19e3\u8001\u1a00\u8001\u1a00\u8001\u1a0b\u8001\u1a32\u8001\u1a3a"+ + "\u8001\u1a3a\u8001\u1a50\u8001\u1a50\u8001\u1a5c\u8001\u1a89\u8001\u1a9d"+ + "\u8001\u1a9d\u8001\u1ab0\u8001\u1af8\u8001\u1c00\u8001\u1c08\u8001\u1c0a"+ + "\u8001\u1c2e\u8001\u1c40\u8001\u1c40\u8001\u1c72\u8001\u1c8f\u8001\u1d00"+ + "\u8001\u1d06\u8001\u1d08\u8001\u1d09\u8001\u1d0b\u8001\u1d30\u8001\u1d46"+ + "\u8001\u1d46\u8001\u1d60\u8001\u1d65\u8001\u1d67\u8001\u1d68\u8001\u1d6a"+ + "\u8001\u1d89\u8001\u1d98\u8001\u1d98\u8001\u1ee0\u8001\u1ef2\u8001\u1f02"+ + "\u8001\u1f02\u8001\u1f04\u8001\u1f10\u8001\u1f12\u8001\u1f33\u8001\u1fb0"+ + "\u8001\u1fb0\u8001\u2000\u8001\u2399\u8001\u2480\u8001\u2543\u8001\u2f90"+ + "\u8001\u2ff0\u8001\u3000\u8001\u342f\u8001\u3441\u8001\u3446\u8001\u4400"+ + "\u8001\u4646\u8001\u6800\u8001\u6a38\u8001\u6a40\u8001\u6a5e\u8001\u6a70"+ + "\u8001\u6abe\u8001\u6ad0\u8001\u6aed\u8001\u6b00\u8001\u6b2f\u8001\u6b40"+ + "\u8001\u6b43\u8001\u6b63\u8001\u6b77\u8001\u6b7d\u8001\u6b8f\u8001\u6e40"+ + "\u8001\u6e7f\u8001\u6f00\u8001\u6f4a\u8001\u6f50\u8001\u6f50\u8001\u6f93"+ + "\u8001\u6f9f\u8001\u6fe0\u8001\u6fe1\u8001\u6fe3\u8001\u6fe3\u8001\u7000"+ + "\u8001\u87f7\u8001\u8800\u8001\u8cd5\u8001\u8d00\u8001\u8d08\u8001\uaff0"+ + "\u8001\uaff3\u8001\uaff5\u8001\uaffb\u8001\uaffd\u8001\uaffe\u8001\ub000"+ + "\u8001\ub122\u8001\ub132\u8001\ub132\u8001\ub150\u8001\ub152\u8001\ub155"+ + "\u8001\ub155\u8001\ub164\u8001\ub167\u8001\ub170\u8001\ub2fb\u8001\ubc00"+ + "\u8001\ubc6a\u8001\ubc70\u8001\ubc7c\u8001\ubc80\u8001\ubc88\u8001\ubc90"+ + "\u8001\ubc99\u8001\ud400\u8001\ud454\u8001\ud456\u8001\ud49c\u8001\ud49e"+ + "\u8001\ud49f\u8001\ud4a2\u8001\ud4a2\u8001\ud4a5\u8001\ud4a6\u8001\ud4a9"+ + "\u8001\ud4ac\u8001\ud4ae\u8001\ud4b9\u8001\ud4bb\u8001\ud4bb\u8001\ud4bd"+ + "\u8001\ud4c3\u8001\ud4c5\u8001\ud505\u8001\ud507\u8001\ud50a\u8001\ud50d"+ + "\u8001\ud514\u8001\ud516\u8001\ud51c\u8001\ud51e\u8001\ud539\u8001\ud53b"+ + "\u8001\ud53e\u8001\ud540\u8001\ud544\u8001\ud546\u8001\ud546\u8001\ud54a"+ + "\u8001\ud550\u8001\ud552\u8001\ud6a5\u8001\ud6a8\u8001\ud6c0\u8001\ud6c2"+ + "\u8001\ud6da\u8001\ud6dc\u8001\ud6fa\u8001\ud6fc\u8001\ud714\u8001\ud716"+ + "\u8001\ud734\u8001\ud736\u8001\ud74e\u8001\ud750\u8001\ud76e\u8001\ud770"+ + "\u8001\ud788\u8001\ud78a\u8001\ud7a8\u8001\ud7aa\u8001\ud7c2\u8001\ud7c4"+ + "\u8001\ud7cb\u8001\udf00\u8001\udf1e\u8001\udf25\u8001\udf2a\u8001\ue030"+ + "\u8001\ue06d\u8001\ue100\u8001\ue12c\u8001\ue137\u8001\ue13d\u8001\ue14e"+ + "\u8001\ue14e\u8001\ue290\u8001\ue2ad\u8001\ue2c0\u8001\ue2eb\u8001\ue4d0"+ + "\u8001\ue4eb\u8001\ue7e0\u8001\ue7e6\u8001\ue7e8\u8001\ue7eb\u8001\ue7ed"+ + "\u8001\ue7ee\u8001\ue7f0\u8001\ue7fe\u8001\ue800\u8001\ue8c4\u8001\ue900"+ + "\u8001\ue943\u8001\ue94b\u8001\ue94b\u8001\uee00\u8001\uee03\u8001\uee05"+ + "\u8001\uee1f\u8001\uee21\u8001\uee22\u8001\uee24\u8001\uee24\u8001\uee27"+ + "\u8001\uee27\u8001\uee29\u8001\uee32\u8001\uee34\u8001\uee37\u8001\uee39"+ + "\u8001\uee39\u8001\uee3b\u8001\uee3b\u8001\uee42\u8001\uee42\u8001\uee47"+ + "\u8001\uee47\u8001\uee49\u8001\uee49\u8001\uee4b\u8001\uee4b\u8001\uee4d"+ + "\u8001\uee4f\u8001\uee51\u8001\uee52\u8001\uee54\u8001\uee54\u8001\uee57"+ + "\u8001\uee57\u8001\uee59\u8001\uee59\u8001\uee5b\u8001\uee5b\u8001\uee5d"+ + "\u8001\uee5d\u8001\uee5f\u8001\uee5f\u8001\uee61\u8001\uee62\u8001\uee64"+ + "\u8001\uee64\u8001\uee67\u8001\uee6a\u8001\uee6c\u8001\uee72\u8001\uee74"+ + "\u8001\uee77\u8001\uee79\u8001\uee7c\u8001\uee7e\u8001\uee7e\u8001\uee80"+ + "\u8001\uee89\u8001\uee8b\u8001\uee9b\u8001\ueea1\u8001\ueea3\u8001\ueea5"+ + "\u8001\ueea9\u8001\ueeab\u8001\ueebb\u8002\u0000\u8002\ua6df\u8002\ua700"+ + "\u8002\ub739\u8002\ub740\u8002\ub81d\u8002\ub820\u8002\ucea1\u8002\uceb0"+ + "\u8002\uebe0\u8002\uf800\u8002\ufa1d\u8003\u0000\u8003\u134a\u8003\u1350"+ + "\u8003\u23af\u0002\u0000\n\n``\u01f4\u0000\u0002\u0001\u0000\u0000\u0000"+ + "\u0000\u0006\u0001\u0000\u0000\u0000\u0000\b\u0001\u0000\u0000\u0000\u0000"+ + "\n\u0001\u0000\u0000\u0000\u0000\f\u0001\u0000\u0000\u0000\u0000\u000e"+ + "\u0001\u0000\u0000\u0000\u0000\u0010\u0001\u0000\u0000\u0000\u0000\u0012"+ + "\u0001\u0000\u0000\u0000\u0000\u0014\u0001\u0000\u0000\u0000\u0000\u0016"+ + "\u0001\u0000\u0000\u0000\u0000\u0018\u0001\u0000\u0000\u0000\u0000\u001a"+ + "\u0001\u0000\u0000\u0000\u0000\u001c\u0001\u0000\u0000\u0000\u0000\u001e"+ + "\u0001\u0000\u0000\u0000\u0000 \u0001\u0000\u0000\u0000\u0000\"\u0001"+ + "\u0000\u0000\u0000\u0000$\u0001\u0000\u0000\u0000\u0000&\u0001\u0000\u0000"+ + "\u0000\u0000(\u0001\u0000\u0000\u0000\u0000*\u0001\u0000\u0000\u0000\u0000"+ + ",\u0001\u0000\u0000\u0000\u0000.\u0001\u0000\u0000\u0000\u00000\u0001"+ + "\u0000\u0000\u0000\u00002\u0001\u0000\u0000\u0000\u00004\u0001\u0000\u0000"+ + "\u0000\u00006\u0001\u0000\u0000\u0000\u00008\u0001\u0000\u0000\u0000\u0000"+ + ":\u0001\u0000\u0000\u0000\u0000<\u0001\u0000\u0000\u0000\u0000>\u0001"+ + "\u0000\u0000\u0000\u0000@\u0001\u0000\u0000\u0000\u0000B\u0001\u0000\u0000"+ + "\u0000\u0000D\u0001\u0000\u0000\u0000\u0000F\u0001\u0000\u0000\u0000\u0000"+ + "H\u0001\u0000\u0000\u0000\u0000J\u0001\u0000\u0000\u0000\u0000L\u0001"+ + "\u0000\u0000\u0000\u0000N\u0001\u0000\u0000\u0000\u0000P\u0001\u0000\u0000"+ + "\u0000\u0000R\u0001\u0000\u0000\u0000\u0000T\u0001\u0000\u0000\u0000\u0000"+ + "V\u0001\u0000\u0000\u0000\u0000X\u0001\u0000\u0000\u0000\u0000Z\u0001"+ + "\u0000\u0000\u0000\u0000\\\u0001\u0000\u0000\u0000\u0000^\u0001\u0000"+ + "\u0000\u0000\u0000`\u0001\u0000\u0000\u0000\u0000b\u0001\u0000\u0000\u0000"+ + "\u0000d\u0001\u0000\u0000\u0000\u0000f\u0001\u0000\u0000\u0000\u0000h"+ + "\u0001\u0000\u0000\u0000\u0000j\u0001\u0000\u0000\u0000\u0000l\u0001\u0000"+ + "\u0000\u0000\u0000n\u0001\u0000\u0000\u0000\u0000p\u0001\u0000\u0000\u0000"+ + "\u0000r\u0001\u0000\u0000\u0000\u0000t\u0001\u0000\u0000\u0000\u0000v"+ + "\u0001\u0000\u0000\u0000\u0000x\u0001\u0000\u0000\u0000\u0000z\u0001\u0000"+ + "\u0000\u0000\u0000|\u0001\u0000\u0000\u0000\u0001\u008e\u0001\u0000\u0000"+ + "\u0000\u0001\u0090\u0001\u0000\u0000\u0000\u0001\u0092\u0001\u0000\u0000"+ + "\u0000\u0001\u0094\u0001\u0000\u0000\u0000\u0002\u0096\u0001\u0000\u0000"+ + "\u0000\u0004\u009b\u0001\u0000\u0000\u0000\u0006\u009e\u0001\u0000\u0000"+ + "\u0000\b\u00a4\u0001\u0000\u0000\u0000\n\u00a7\u0001\u0000\u0000\u0000"+ + "\f\u00a9\u0001\u0000\u0000\u0000\u000e\u00ac\u0001\u0000\u0000\u0000\u0010"+ + "\u00ae\u0001\u0000\u0000\u0000\u0012\u00b0\u0001\u0000\u0000\u0000\u0014"+ + "\u00b2\u0001\u0000\u0000\u0000\u0016\u00b4\u0001\u0000\u0000\u0000\u0018"+ + "\u00b6\u0001\u0000\u0000\u0000\u001a\u00b8\u0001\u0000\u0000\u0000\u001c"+ + "\u00ba\u0001\u0000\u0000\u0000\u001e\u00bc\u0001\u0000\u0000\u0000 \u00be"+ + "\u0001\u0000\u0000\u0000\"\u00c0\u0001\u0000\u0000\u0000$\u00c2\u0001"+ + "\u0000\u0000\u0000&\u00c4\u0001\u0000\u0000\u0000(\u00c6\u0001\u0000\u0000"+ + "\u0000*\u00c9\u0001\u0000\u0000\u0000,\u00cb\u0001\u0000\u0000\u0000."+ + "\u00ce\u0001\u0000\u0000\u00000\u00d1\u0001\u0000\u0000\u00002\u00d3\u0001"+ + "\u0000\u0000\u00004\u00d6\u0001\u0000\u0000\u00006\u00d8\u0001\u0000\u0000"+ + "\u00008\u00db\u0001\u0000\u0000\u0000:\u00dd\u0001\u0000\u0000\u0000<"+ + "\u00e0\u0001\u0000\u0000\u0000>\u00e3\u0001\u0000\u0000\u0000@\u00e6\u0001"+ + "\u0000\u0000\u0000B\u00e9\u0001\u0000\u0000\u0000D\u00eb\u0001\u0000\u0000"+ + "\u0000F\u00ee\u0001\u0000\u0000\u0000H\u00f1\u0001\u0000\u0000\u0000J"+ + "\u00f3\u0001\u0000\u0000\u0000L\u00f6\u0001\u0000\u0000\u0000N\u00f8\u0001"+ + "\u0000\u0000\u0000P\u00fd\u0001\u0000\u0000\u0000R\u0102\u0001\u0000\u0000"+ + "\u0000T\u0106\u0001\u0000\u0000\u0000V\u0109\u0001\u0000\u0000\u0000X"+ + "\u010d\u0001\u0000\u0000\u0000Z\u0112\u0001\u0000\u0000\u0000\\\u0118"+ + "\u0001\u0000\u0000\u0000^\u011c\u0001\u0000\u0000\u0000`\u0121\u0001\u0000"+ + "\u0000\u0000b\u0123\u0001\u0000\u0000\u0000d\u012b\u0001\u0000\u0000\u0000"+ + "f\u012e\u0001\u0000\u0000\u0000h\u0131\u0001\u0000\u0000\u0000j\u0134"+ + "\u0001\u0000\u0000\u0000l\u0137\u0001\u0000\u0000\u0000n\u013a\u0001\u0000"+ + "\u0000\u0000p\u013f\u0001\u0000\u0000\u0000r\u0176\u0001\u0000\u0000\u0000"+ + "t\u0179\u0001\u0000\u0000\u0000v\u0182\u0001\u0000\u0000\u0000x\u0184"+ + "\u0001\u0000\u0000\u0000z\u018f\u0001\u0000\u0000\u0000|\u019a\u0001\u0000"+ + "\u0000\u0000~\u01a5\u0001\u0000\u0000\u0000\u0080\u01a7\u0001\u0000\u0000"+ + "\u0000\u0082\u01a9\u0001\u0000\u0000\u0000\u0084\u01c3\u0001\u0000\u0000"+ + "\u0000\u0086\u01c5\u0001\u0000\u0000\u0000\u0088\u01c7\u0001\u0000\u0000"+ + "\u0000\u008a\u01ca\u0001\u0000\u0000\u0000\u008c\u01cc\u0001\u0000\u0000"+ + "\u0000\u008e\u01ce\u0001\u0000\u0000\u0000\u0090\u01d1\u0001\u0000\u0000"+ + "\u0000\u0092\u01d8\u0001\u0000\u0000\u0000\u0094\u01da\u0001\u0000\u0000"+ + "\u0000\u0096\u0097\u0005;\u0000\u0000\u0097\u0003\u0001\u0000\u0000\u0000"+ + "\u0098\u0099\u0005\r\u0000\u0000\u0099\u009c\u0005\n\u0000\u0000\u009a"+ + "\u009c\u0007\u0000\u0000\u0000\u009b\u0098\u0001\u0000\u0000\u0000\u009b"+ + "\u009a\u0001\u0000\u0000\u0000\u009c\u0005\u0001\u0000\u0000\u0000\u009d"+ + "\u009f\u0007\u0001\u0000\u0000\u009e\u009d\u0001\u0000\u0000\u0000\u009f"+ + "\u00a0\u0001\u0000\u0000\u0000\u00a0\u009e\u0001\u0000\u0000\u0000\u00a0"+ + "\u00a1\u0001\u0000\u0000\u0000\u00a1\u00a2\u0001\u0000\u0000\u0000\u00a2"+ + "\u00a3\u0006\u0002\u0000\u0000\u00a3\u0007\u0001\u0000\u0000\u0000\u00a4"+ + "\u00a5\u0005+\u0000\u0000\u00a5\u00a6\u0005+\u0000\u0000\u00a6\t\u0001"+ + "\u0000\u0000\u0000\u00a7\u00a8\u0005+\u0000\u0000\u00a8\u000b\u0001\u0000"+ + "\u0000\u0000\u00a9\u00aa\u0005-\u0000\u0000\u00aa\u00ab\u0005-\u0000\u0000"+ + "\u00ab\r\u0001\u0000\u0000\u0000\u00ac\u00ad\u0005-\u0000\u0000\u00ad"+ + "\u000f\u0001\u0000\u0000\u0000\u00ae\u00af\u0005:\u0000\u0000\u00af\u0011"+ + "\u0001\u0000\u0000\u0000\u00b0\u00b1\u0005.\u0000\u0000\u00b1\u0013\u0001"+ + "\u0000\u0000\u0000\u00b2\u00b3\u0005,\u0000\u0000\u00b3\u0015\u0001\u0000"+ + "\u0000\u0000\u00b4\u00b5\u0005*\u0000\u0000\u00b5\u0017\u0001\u0000\u0000"+ + "\u0000\u00b6\u00b7\u0005/\u0000\u0000\u00b7\u0019\u0001\u0000\u0000\u0000"+ + "\u00b8\u00b9\u0005%\u0000\u0000\u00b9\u001b\u0001\u0000\u0000\u0000\u00ba"+ + "\u00bb\u0005(\u0000\u0000\u00bb\u001d\u0001\u0000\u0000\u0000\u00bc\u00bd"+ + "\u0005)\u0000\u0000\u00bd\u001f\u0001\u0000\u0000\u0000\u00be\u00bf\u0005"+ + "[\u0000\u0000\u00bf!\u0001\u0000\u0000\u0000\u00c0\u00c1\u0005]\u0000"+ + "\u0000\u00c1#\u0001\u0000\u0000\u0000\u00c2\u00c3\u0005#\u0000\u0000\u00c3"+ + "%\u0001\u0000\u0000\u0000\u00c4\u00c5\u0005@\u0000\u0000\u00c5\'\u0001"+ + "\u0000\u0000\u0000\u00c6\u00c7\u0005^\u0000\u0000\u00c7\u00c8\u0005[\u0000"+ + "\u0000\u00c8)\u0001\u0000\u0000\u0000\u00c9\u00ca\u0005^\u0000\u0000\u00ca"+ + "+\u0001\u0000\u0000\u0000\u00cb\u00cc\u0005!\u0000\u0000\u00cc\u00cd\u0005"+ + "=\u0000\u0000\u00cd-\u0001\u0000\u0000\u0000\u00ce\u00cf\u0005!\u0000"+ + "\u0000\u00cf\u00d0\u0005[\u0000\u0000\u00d0/\u0001\u0000\u0000\u0000\u00d1"+ + "\u00d2\u0005!\u0000\u0000\u00d21\u0001\u0000\u0000\u0000\u00d3\u00d4\u0005"+ + "=\u0000\u0000\u00d4\u00d5\u0005=\u0000\u0000\u00d53\u0001\u0000\u0000"+ + "\u0000\u00d6\u00d7\u0005=\u0000\u0000\u00d75\u0001\u0000\u0000\u0000\u00d8"+ + "\u00d9\u0005&\u0000\u0000\u00d9\u00da\u0005&\u0000\u0000\u00da7\u0001"+ + "\u0000\u0000\u0000\u00db\u00dc\u0005&\u0000\u0000\u00dc9\u0001\u0000\u0000"+ + "\u0000\u00dd\u00de\u0005|\u0000\u0000\u00de\u00df\u0005|\u0000\u0000\u00df"+ + ";\u0001\u0000\u0000\u0000\u00e0\u00e1\u0005?\u0000\u0000\u00e1\u00e2\u0005"+ + "[\u0000\u0000\u00e2=\u0001\u0000\u0000\u0000\u00e3\u00e4\u0005?\u0000"+ + "\u0000\u00e4\u00e5\u0005:\u0000\u0000\u00e5?\u0001\u0000\u0000\u0000\u00e6"+ + "\u00e7\u0005?\u0000\u0000\u00e7\u00e8\u0005.\u0000\u0000\u00e8A\u0001"+ + "\u0000\u0000\u0000\u00e9\u00ea\u0005?\u0000\u0000\u00eaC\u0001\u0000\u0000"+ + "\u0000\u00eb\u00ec\u0005$\u0000\u0000\u00ec\u00ed\u0005[\u0000\u0000\u00ed"+ + "E\u0001\u0000\u0000\u0000\u00ee\u00ef\u0005>\u0000\u0000\u00ef\u00f0\u0005"+ + "=\u0000\u0000\u00f0G\u0001\u0000\u0000\u0000\u00f1\u00f2\u0005>\u0000"+ + "\u0000\u00f2I\u0001\u0000\u0000\u0000\u00f3\u00f4\u0005<\u0000\u0000\u00f4"+ + "\u00f5\u0005=\u0000\u0000\u00f5K\u0001\u0000\u0000\u0000\u00f6\u00f7\u0005"+ + "<\u0000\u0000\u00f7M\u0001\u0000\u0000\u0000\u00f8\u00f9\u0005{\u0000"+ + "\u0000\u00f9\u00fa\u0006&\u0001\u0000\u00fa\u00fb\u0001\u0000\u0000\u0000"+ + "\u00fb\u00fc\u0006&\u0002\u0000\u00fcO\u0001\u0000\u0000\u0000\u00fd\u00fe"+ + "\u0005}\u0000\u0000\u00fe\u00ff\u0006\'\u0003\u0000\u00ff\u0100\u0001"+ + "\u0000\u0000\u0000\u0100\u0101\u0006\'\u0004\u0000\u0101Q\u0001\u0000"+ + "\u0000\u0000\u0102\u0103\u0005`\u0000\u0000\u0103\u0104\u0001\u0000\u0000"+ + "\u0000\u0104\u0105\u0006(\u0005\u0000\u0105S\u0001\u0000\u0000\u0000\u0106"+ + "\u0107\u0005o\u0000\u0000\u0107\u0108\u0005r\u0000\u0000\u0108U\u0001"+ + "\u0000\u0000\u0000\u0109\u010a\u0005a\u0000\u0000\u010a\u010b\u0005n\u0000"+ + "\u0000\u010b\u010c\u0005d\u0000\u0000\u010cW\u0001\u0000\u0000\u0000\u010d"+ + "\u010e\u0005t\u0000\u0000\u010e\u010f\u0005r\u0000\u0000\u010f\u0110\u0005"+ + "u\u0000\u0000\u0110\u0111\u0005e\u0000\u0000\u0111Y\u0001\u0000\u0000"+ + "\u0000\u0112\u0113\u0005f\u0000\u0000\u0113\u0114\u0005a\u0000\u0000\u0114"+ + "\u0115\u0005l\u0000\u0000\u0115\u0116\u0005s\u0000\u0000\u0116\u0117\u0005"+ + "e\u0000\u0000\u0117[\u0001\u0000\u0000\u0000\u0118\u0119\u0005n\u0000"+ + "\u0000\u0119\u011a\u0005e\u0000\u0000\u011a\u011b\u0005w\u0000\u0000\u011b"+ + "]\u0001\u0000\u0000\u0000\u011c\u011d\u0005n\u0000\u0000\u011d\u011e\u0005"+ + "u\u0000\u0000\u011e\u011f\u0005l\u0000\u0000\u011f\u0120\u0005l\u0000"+ + "\u0000\u0120_\u0001\u0000\u0000\u0000\u0121\u0122\u0005T\u0000\u0000\u0122"+ + "a\u0001\u0000\u0000\u0000\u0123\u0124\u0005m\u0000\u0000\u0124\u0125\u0005"+ + "a\u0000\u0000\u0125\u0126\u0005t\u0000\u0000\u0126\u0127\u0005c\u0000"+ + "\u0000\u0127\u0128\u0005h\u0000\u0000\u0128\u0129\u0005e\u0000\u0000\u0129"+ + "\u012a\u0005s\u0000\u0000\u012ac\u0001\u0000\u0000\u0000\u012b\u012c\u0005"+ + "g\u0000\u0000\u012c\u012d\u0005t\u0000\u0000\u012de\u0001\u0000\u0000"+ + "\u0000\u012e\u012f\u0005g\u0000\u0000\u012f\u0130\u0005e\u0000\u0000\u0130"+ + "g\u0001\u0000\u0000\u0000\u0131\u0132\u0005l\u0000\u0000\u0132\u0133\u0005"+ + "e\u0000\u0000\u0133i\u0001\u0000\u0000\u0000\u0134\u0135\u0005l\u0000"+ + "\u0000\u0135\u0136\u0005t\u0000\u0000\u0136k\u0001\u0000\u0000\u0000\u0137"+ + "\u0138\u0005e\u0000\u0000\u0138\u0139\u0005q\u0000\u0000\u0139m\u0001"+ + "\u0000\u0000\u0000\u013a\u013b\u0005n\u0000\u0000\u013b\u013c\u0005e\u0000"+ + "\u0000\u013co\u0001\u0000\u0000\u0000\u013d\u0140\u0003\u008aD\u0000\u013e"+ + "\u0140\u0005_\u0000\u0000\u013f\u013d\u0001\u0000\u0000\u0000\u013f\u013e"+ + "\u0001\u0000\u0000\u0000\u0140\u0146\u0001\u0000\u0000\u0000\u0141\u0145"+ + "\u0003\u008aD\u0000\u0142\u0145\u0003\u008cE\u0000\u0143\u0145\u0007\u0002"+ + "\u0000\u0000\u0144\u0141\u0001\u0000\u0000\u0000\u0144\u0142\u0001\u0000"+ + "\u0000\u0000\u0144\u0143\u0001\u0000\u0000\u0000\u0145\u0148\u0001\u0000"+ + "\u0000\u0000\u0146\u0144\u0001\u0000\u0000\u0000\u0146\u0147\u0001\u0000"+ + "\u0000\u0000\u0147q\u0001\u0000\u0000\u0000\u0148\u0146\u0001\u0000\u0000"+ + "\u0000\u0149\u014b\u0005.\u0000\u0000\u014a\u014c\u0003\u0082@\u0000\u014b"+ + "\u014a\u0001\u0000\u0000\u0000\u014c\u014d\u0001\u0000\u0000\u0000\u014d"+ + "\u014b\u0001\u0000\u0000\u0000\u014d\u014e\u0001\u0000\u0000\u0000\u014e"+ + "\u0150\u0001\u0000\u0000\u0000\u014f\u0151\u0003\u0084A\u0000\u0150\u014f"+ + "\u0001\u0000\u0000\u0000\u0150\u0151\u0001\u0000\u0000\u0000\u0151\u0153"+ + "\u0001\u0000\u0000\u0000\u0152\u0154\u0003\u0088C\u0000\u0153\u0152\u0001"+ + "\u0000\u0000\u0000\u0153\u0154\u0001\u0000\u0000\u0000\u0154\u0177\u0001"+ + "\u0000\u0000\u0000\u0155\u0157\u0003\u0082@\u0000\u0156\u0155\u0001\u0000"+ + "\u0000\u0000\u0157\u0158\u0001\u0000\u0000\u0000\u0158\u0156\u0001\u0000"+ + "\u0000\u0000\u0158\u0159\u0001\u0000\u0000\u0000\u0159\u015a\u0001\u0000"+ + "\u0000\u0000\u015a\u015c\u0005.\u0000\u0000\u015b\u015d\u0003\u0082@\u0000"+ + "\u015c\u015b\u0001\u0000\u0000\u0000\u015d\u015e\u0001\u0000\u0000\u0000"+ + "\u015e\u015c\u0001\u0000\u0000\u0000\u015e\u015f\u0001\u0000\u0000\u0000"+ + "\u015f\u0161\u0001\u0000\u0000\u0000\u0160\u0162\u0003\u0084A\u0000\u0161"+ + "\u0160\u0001\u0000\u0000\u0000\u0161\u0162\u0001\u0000\u0000\u0000\u0162"+ + "\u0164\u0001\u0000\u0000\u0000\u0163\u0165\u0003\u0088C\u0000\u0164\u0163"+ + "\u0001\u0000\u0000\u0000\u0164\u0165\u0001\u0000\u0000\u0000\u0165\u0177"+ + "\u0001\u0000\u0000\u0000\u0166\u0168\u0003\u0082@\u0000\u0167\u0166\u0001"+ + "\u0000\u0000\u0000\u0168\u0169\u0001\u0000\u0000\u0000\u0169\u0167\u0001"+ + "\u0000\u0000\u0000\u0169\u016a\u0001\u0000\u0000\u0000\u016a\u016b\u0001"+ + "\u0000\u0000\u0000\u016b\u016d\u0003\u0084A\u0000\u016c\u016e\u0003\u0088"+ + "C\u0000\u016d\u016c\u0001\u0000\u0000\u0000\u016d\u016e\u0001\u0000\u0000"+ + "\u0000\u016e\u0177\u0001\u0000\u0000\u0000\u016f\u0171\u0003\u0082@\u0000"+ + "\u0170\u016f\u0001\u0000\u0000\u0000\u0171\u0172\u0001\u0000\u0000\u0000"+ + "\u0172\u0170\u0001\u0000\u0000\u0000\u0172\u0173\u0001\u0000\u0000\u0000"+ + "\u0173\u0174\u0001\u0000\u0000\u0000\u0174\u0175\u0003\u0088C\u0000\u0175"+ + "\u0177\u0001\u0000\u0000\u0000\u0176\u0149\u0001\u0000\u0000\u0000\u0176"+ + "\u0156\u0001\u0000\u0000\u0000\u0176\u0167\u0001\u0000\u0000\u0000\u0176"+ + "\u0170\u0001\u0000\u0000\u0000\u0177s\u0001\u0000\u0000\u0000\u0178\u017a"+ + "\u0003\u0082@\u0000\u0179\u0178\u0001\u0000\u0000\u0000\u017a\u017b\u0001"+ + "\u0000\u0000\u0000\u017b\u0179\u0001\u0000\u0000\u0000\u017b\u017c\u0001"+ + "\u0000\u0000\u0000\u017c\u017e\u0001\u0000\u0000\u0000\u017d\u017f\u0003"+ + "~>\u0000\u017e\u017d\u0001\u0000\u0000\u0000\u017e\u017f\u0001\u0000\u0000"+ + "\u0000\u017fu\u0001\u0000\u0000\u0000\u0180\u0183\u0003x;\u0000\u0181"+ + "\u0183\u0003z<\u0000\u0182\u0180\u0001\u0000\u0000\u0000\u0182\u0181\u0001"+ + "\u0000\u0000\u0000\u0183w\u0001\u0000\u0000\u0000\u0184\u018a\u0005\'"+ + "\u0000\u0000\u0185\u0186\u0005\'\u0000\u0000\u0186\u0189\u0005\'\u0000"+ + "\u0000\u0187\u0189\b\u0003\u0000\u0000\u0188\u0185\u0001\u0000\u0000\u0000"+ + "\u0188\u0187\u0001\u0000\u0000\u0000\u0189\u018c\u0001\u0000\u0000\u0000"+ + "\u018a\u0188\u0001\u0000\u0000\u0000\u018a\u018b\u0001\u0000\u0000\u0000"+ + "\u018b\u018d\u0001\u0000\u0000\u0000\u018c\u018a\u0001\u0000\u0000\u0000"+ + "\u018d\u018e\u0005\'\u0000\u0000\u018ey\u0001\u0000\u0000\u0000\u018f"+ + "\u0195\u0005\"\u0000\u0000\u0190\u0191\u0005\"\u0000\u0000\u0191\u0194"+ + "\u0005\"\u0000\u0000\u0192\u0194\b\u0004\u0000\u0000\u0193\u0190\u0001"+ + "\u0000\u0000\u0000\u0193\u0192\u0001\u0000\u0000\u0000\u0194\u0197\u0001"+ + "\u0000\u0000\u0000\u0195\u0193\u0001\u0000\u0000\u0000\u0195\u0196\u0001"+ + "\u0000\u0000\u0000\u0196\u0198\u0001\u0000\u0000\u0000\u0197\u0195\u0001"+ + "\u0000\u0000\u0000\u0198\u0199\u0005\"\u0000\u0000\u0199{\u0001\u0000"+ + "\u0000\u0000\u019a\u019b\u0005$\u0000\u0000\u019b\u019c\u0005{\u0000\u0000"+ + "\u019c\u01a0\u0001\u0000\u0000\u0000\u019d\u019f\t\u0000\u0000\u0000\u019e"+ + "\u019d\u0001\u0000\u0000\u0000\u019f\u01a2\u0001\u0000\u0000\u0000\u01a0"+ + "\u01a1\u0001\u0000\u0000\u0000\u01a0\u019e\u0001\u0000\u0000\u0000\u01a1"+ + "\u01a3\u0001\u0000\u0000\u0000\u01a2\u01a0\u0001\u0000\u0000\u0000\u01a3"+ + "\u01a4\u0005}\u0000\u0000\u01a4}\u0001\u0000\u0000\u0000\u01a5\u01a6\u0007"+ + "\u0005\u0000\u0000\u01a6\u007f\u0001\u0000\u0000\u0000\u01a7\u01a8\u0007"+ + "\u0006\u0000\u0000\u01a8\u0081\u0001\u0000\u0000\u0000\u01a9\u01aa\u0007"+ + "\u0007\u0000\u0000\u01aa\u0083\u0001\u0000\u0000\u0000\u01ab\u01af\u0005"+ + "e\u0000\u0000\u01ac\u01ae\u0003\u0086B\u0000\u01ad\u01ac\u0001\u0000\u0000"+ + "\u0000\u01ae\u01b1\u0001\u0000\u0000\u0000\u01af\u01ad\u0001\u0000\u0000"+ + "\u0000\u01af\u01b0\u0001\u0000\u0000\u0000\u01b0\u01b3\u0001\u0000\u0000"+ + "\u0000\u01b1\u01af\u0001\u0000\u0000\u0000\u01b2\u01b4\u0003\u0082@\u0000"+ + "\u01b3\u01b2\u0001\u0000\u0000\u0000\u01b4\u01b5\u0001\u0000\u0000\u0000"+ + "\u01b5\u01b3\u0001\u0000\u0000\u0000\u01b5\u01b6\u0001\u0000\u0000\u0000"+ + "\u01b6\u01c4\u0001\u0000\u0000\u0000\u01b7\u01bb\u0005E\u0000\u0000\u01b8"+ + "\u01ba\u0003\u0086B\u0000\u01b9\u01b8\u0001\u0000\u0000\u0000\u01ba\u01bd"+ + "\u0001\u0000\u0000\u0000\u01bb\u01b9\u0001\u0000\u0000\u0000\u01bb\u01bc"+ + "\u0001\u0000\u0000\u0000\u01bc\u01bf\u0001\u0000\u0000\u0000\u01bd\u01bb"+ + "\u0001\u0000\u0000\u0000\u01be\u01c0\u0003\u0082@\u0000\u01bf\u01be\u0001"+ + "\u0000\u0000\u0000\u01c0\u01c1\u0001\u0000\u0000\u0000\u01c1\u01bf\u0001"+ + "\u0000\u0000\u0000\u01c1\u01c2\u0001\u0000\u0000\u0000\u01c2\u01c4\u0001"+ + "\u0000\u0000\u0000\u01c3\u01ab\u0001\u0000\u0000\u0000\u01c3\u01b7\u0001"+ + "\u0000\u0000\u0000\u01c4\u0085\u0001\u0000\u0000\u0000\u01c5\u01c6\u0007"+ + "\b\u0000\u0000\u01c6\u0087\u0001\u0000\u0000\u0000\u01c7\u01c8\u0007\t"+ + "\u0000\u0000\u01c8\u0089\u0001\u0000\u0000\u0000\u01c9\u01cb\u0007\n\u0000"+ + "\u0000\u01ca\u01c9\u0001\u0000\u0000\u0000\u01cb\u008b\u0001\u0000\u0000"+ + "\u0000\u01cc\u01cd\u0007\u0007\u0000\u0000\u01cd\u008d\u0001\u0000\u0000"+ + "\u0000\u01ce\u01cf\u0005`\u0000\u0000\u01cf\u01d0\u0005`\u0000\u0000\u01d0"+ + "\u008f\u0001\u0000\u0000\u0000\u01d1\u01d2\u0005#\u0000\u0000\u01d2\u01d3"+ + "\u0005{\u0000\u0000\u01d3\u01d4\u0001\u0000\u0000\u0000\u01d4\u01d5\u0006"+ + "G\u0006\u0000\u01d5\u01d6\u0001\u0000\u0000\u0000\u01d6\u01d7\u0006G\u0002"+ + "\u0000\u01d7\u0091\u0001\u0000\u0000\u0000\u01d8\u01d9\b\u000b\u0000\u0000"+ + "\u01d9\u0093\u0001\u0000\u0000\u0000\u01da\u01db\u0005`\u0000\u0000\u01db"+ + "\u01dc\u0001\u0000\u0000\u0000\u01dc\u01dd\u0006I\u0007\u0000\u01dd\u01de"+ + "\u0006I\u0004\u0000\u01de\u0095\u0001\u0000\u0000\u0000 \u0000\u0001\u009b"+ + "\u00a0\u013f\u0144\u0146\u014d\u0150\u0153\u0158\u015e\u0161\u0164\u0169"+ + "\u016d\u0172\u0176\u017b\u017e\u0182\u0188\u018a\u0193\u0195\u01a0\u01af"+ + "\u01b5\u01bb\u01c1\u01c3\u01ca\b\u0000\u0001\u0000\u0001&\u0000\u0005"+ + "\u0000\u0000\u0001\'\u0001\u0004\u0000\u0000\u0005\u0001\u0000\u0001G"+ + "\u0002\u0007(\u0000"; public static final ATN _ATN = new ATNDeserializer().deserialize(_serializedATN.toCharArray()); static { diff --git a/headless-services/commons/jpql/src/main/java/org/springframework/ide/vscode/parser/spel/SpelParser.java b/headless-services/commons/jpql/src/main/java/org/springframework/ide/vscode/parser/spel/SpelParser.java index c832e2432d..0f5ba2b7b2 100644 --- a/headless-services/commons/jpql/src/main/java/org/springframework/ide/vscode/parser/spel/SpelParser.java +++ b/headless-services/commons/jpql/src/main/java/org/springframework/ide/vscode/parser/spel/SpelParser.java @@ -38,8 +38,8 @@ public class SpelParser extends Parser { FALSE=44, NEW=45, NULL=46, T=47, MATCHES=48, GT_KEYWORD=49, GE_KEYWORD=50, LE_KEYWORD=51, LT_KEYWORD=52, EQ_KEYWORD=53, NE_KEYWORD=54, IDENTIFIER=55, REAL_LITERAL=56, INTEGER_LITERAL=57, STRING_LITERAL=58, SINGLE_QUOTED_STRING=59, - DOUBLE_QUOTED_STRING=60, ESCAPED_BACKTICK=61, SPEL_IN_TEMPLATE_STRING_OPEN=62, - TEMPLATE_TEXT=63; + DOUBLE_QUOTED_STRING=60, PROPERTY_PLACE_HOLDER=61, ESCAPED_BACKTICK=62, + SPEL_IN_TEMPLATE_STRING_OPEN=63, TEMPLATE_TEXT=64; public static final int RULE_script = 0, RULE_spelExpr = 1, RULE_node = 2, RULE_nonDottedNode = 3, RULE_dottedNode = 4, RULE_functionOrVar = 5, RULE_methodArgs = 6, RULE_args = 7, @@ -48,7 +48,8 @@ public class SpelParser extends Parser { RULE_typeReference = 15, RULE_possiblyQualifiedId = 16, RULE_nullReference = 17, RULE_constructorReference = 18, RULE_constructorArgs = 19, RULE_inlineListOrMap = 20, RULE_listBindings = 21, RULE_listBinding = 22, RULE_mapBindings = 23, - RULE_mapBinding = 24, RULE_beanReference = 25, RULE_inputParameter = 26; + RULE_mapBinding = 24, RULE_beanReference = 25, RULE_inputParameter = 26, + RULE_propertyPlaceHolder = 27; private static String[] makeRuleNames() { return new String[] { "script", "spelExpr", "node", "nonDottedNode", "dottedNode", "functionOrVar", @@ -56,7 +57,7 @@ private static String[] makeRuleNames() { "startNode", "literal", "numericLiteral", "parenspelExpr", "typeReference", "possiblyQualifiedId", "nullReference", "constructorReference", "constructorArgs", "inlineListOrMap", "listBindings", "listBinding", "mapBindings", "mapBinding", - "beanReference", "inputParameter" + "beanReference", "inputParameter", "propertyPlaceHolder" }; } public static final String[] ruleNames = makeRuleNames(); @@ -69,7 +70,7 @@ private static String[] makeLiteralNames() { "'?:'", "'?.'", "'?'", "'$['", "'>='", "'>'", "'<='", "'<'", null, null, null, "'or'", "'and'", "'true'", "'false'", "'new'", "'null'", "'T'", "'matches'", "'gt'", "'ge'", "'le'", "'lt'", "'eq'", "'ne'", null, null, - null, null, null, null, "'``'" + null, null, null, null, null, "'``'" }; } private static final String[] _LITERAL_NAMES = makeLiteralNames(); @@ -83,8 +84,8 @@ private static String[] makeSymbolicNames() { "LCURLY", "RCURLY", "BACKTICK", "OR", "AND", "TRUE", "FALSE", "NEW", "NULL", "T", "MATCHES", "GT_KEYWORD", "GE_KEYWORD", "LE_KEYWORD", "LT_KEYWORD", "EQ_KEYWORD", "NE_KEYWORD", "IDENTIFIER", "REAL_LITERAL", "INTEGER_LITERAL", - "STRING_LITERAL", "SINGLE_QUOTED_STRING", "DOUBLE_QUOTED_STRING", "ESCAPED_BACKTICK", - "SPEL_IN_TEMPLATE_STRING_OPEN", "TEMPLATE_TEXT" + "STRING_LITERAL", "SINGLE_QUOTED_STRING", "DOUBLE_QUOTED_STRING", "PROPERTY_PLACE_HOLDER", + "ESCAPED_BACKTICK", "SPEL_IN_TEMPLATE_STRING_OPEN", "TEMPLATE_TEXT" }; } private static final String[] _SYMBOLIC_NAMES = makeSymbolicNames(); @@ -164,9 +165,9 @@ public final ScriptContext script() throws RecognitionException { try { enterOuterAlt(_localctx, 1); { - setState(54); + setState(56); spelExpr(0); - setState(55); + setState(57); match(EOF); } } @@ -258,7 +259,7 @@ private SpelExprContext spelExpr(int _p) throws RecognitionException { int _alt; enterOuterAlt(_localctx, 1); { - setState(67); + setState(69); _errHandler.sync(this); switch (_input.LA(1)) { case INC: @@ -267,7 +268,7 @@ private SpelExprContext spelExpr(int _p) throws RecognitionException { case MINUS: case NOT: { - setState(58); + setState(60); _la = _input.LA(1); if ( !((((_la) & ~0x3f) == 0 && ((1L << _la) & 8388728L) != 0)) ) { _errHandler.recoverInline(this); @@ -277,7 +278,7 @@ private SpelExprContext spelExpr(int _p) throws RecognitionException { _errHandler.reportMatch(this); consume(); } - setState(59); + setState(61); spelExpr(13); } break; @@ -300,22 +301,23 @@ private SpelExprContext spelExpr(int _p) throws RecognitionException { case REAL_LITERAL: case INTEGER_LITERAL: case STRING_LITERAL: + case PROPERTY_PLACE_HOLDER: { - setState(60); + setState(62); startNode(); - setState(64); + setState(66); _errHandler.sync(this); _alt = getInterpreter().adaptivePredict(_input,0,_ctx); while ( _alt!=2 && _alt!=org.antlr.v4.runtime.atn.ATN.INVALID_ALT_NUMBER ) { if ( _alt==1 ) { { { - setState(61); + setState(63); node(); } } } - setState(66); + setState(68); _errHandler.sync(this); _alt = getInterpreter().adaptivePredict(_input,0,_ctx); } @@ -325,7 +327,7 @@ private SpelExprContext spelExpr(int _p) throws RecognitionException { throw new NoViableAltException(this); } _ctx.stop = _input.LT(-1); - setState(106); + setState(108); _errHandler.sync(this); _alt = getInterpreter().adaptivePredict(_input,3,_ctx); while ( _alt!=2 && _alt!=org.antlr.v4.runtime.atn.ATN.INVALID_ALT_NUMBER ) { @@ -333,18 +335,18 @@ private SpelExprContext spelExpr(int _p) throws RecognitionException { if ( _parseListeners!=null ) triggerExitRuleEvent(); _prevctx = _localctx; { - setState(104); + setState(106); _errHandler.sync(this); switch ( getInterpreter().adaptivePredict(_input,2,_ctx) ) { case 1: { _localctx = new SpelExprContext(_parentctx, _parentState); pushNewRecursionContext(_localctx, _startState, RULE_spelExpr); - setState(69); + setState(71); if (!(precpred(_ctx, 11))) throw new FailedPredicateException(this, "precpred(_ctx, 11)"); - setState(70); + setState(72); match(POWER); - setState(71); + setState(73); spelExpr(12); } break; @@ -352,9 +354,9 @@ private SpelExprContext spelExpr(int _p) throws RecognitionException { { _localctx = new SpelExprContext(_parentctx, _parentState); pushNewRecursionContext(_localctx, _startState, RULE_spelExpr); - setState(72); + setState(74); if (!(precpred(_ctx, 10))) throw new FailedPredicateException(this, "precpred(_ctx, 10)"); - setState(73); + setState(75); _la = _input.LA(1); if ( !((((_la) & ~0x3f) == 0 && ((1L << _la) & 7168L) != 0)) ) { _errHandler.recoverInline(this); @@ -364,7 +366,7 @@ private SpelExprContext spelExpr(int _p) throws RecognitionException { _errHandler.reportMatch(this); consume(); } - setState(74); + setState(76); spelExpr(11); } break; @@ -372,9 +374,9 @@ private SpelExprContext spelExpr(int _p) throws RecognitionException { { _localctx = new SpelExprContext(_parentctx, _parentState); pushNewRecursionContext(_localctx, _startState, RULE_spelExpr); - setState(75); + setState(77); if (!(precpred(_ctx, 9))) throw new FailedPredicateException(this, "precpred(_ctx, 9)"); - setState(76); + setState(78); _la = _input.LA(1); if ( !(_la==PLUS || _la==MINUS) ) { _errHandler.recoverInline(this); @@ -384,7 +386,7 @@ private SpelExprContext spelExpr(int _p) throws RecognitionException { _errHandler.reportMatch(this); consume(); } - setState(77); + setState(79); spelExpr(10); } break; @@ -392,9 +394,9 @@ private SpelExprContext spelExpr(int _p) throws RecognitionException { { _localctx = new SpelExprContext(_parentctx, _parentState); pushNewRecursionContext(_localctx, _startState, RULE_spelExpr); - setState(78); + setState(80); if (!(precpred(_ctx, 8))) throw new FailedPredicateException(this, "precpred(_ctx, 8)"); - setState(79); + setState(81); _la = _input.LA(1); if ( !((((_la) & ~0x3f) == 0 && ((1L << _la) & 35466104782454784L) != 0)) ) { _errHandler.recoverInline(this); @@ -404,7 +406,7 @@ private SpelExprContext spelExpr(int _p) throws RecognitionException { _errHandler.reportMatch(this); consume(); } - setState(80); + setState(82); spelExpr(9); } break; @@ -412,9 +414,9 @@ private SpelExprContext spelExpr(int _p) throws RecognitionException { { _localctx = new SpelExprContext(_parentctx, _parentState); pushNewRecursionContext(_localctx, _startState, RULE_spelExpr); - setState(81); + setState(83); if (!(precpred(_ctx, 7))) throw new FailedPredicateException(this, "precpred(_ctx, 7)"); - setState(82); + setState(84); _la = _input.LA(1); if ( !(_la==SYMBOLIC_AND || _la==AND) ) { _errHandler.recoverInline(this); @@ -424,7 +426,7 @@ private SpelExprContext spelExpr(int _p) throws RecognitionException { _errHandler.reportMatch(this); consume(); } - setState(83); + setState(85); spelExpr(8); } break; @@ -432,9 +434,9 @@ private SpelExprContext spelExpr(int _p) throws RecognitionException { { _localctx = new SpelExprContext(_parentctx, _parentState); pushNewRecursionContext(_localctx, _startState, RULE_spelExpr); - setState(84); + setState(86); if (!(precpred(_ctx, 6))) throw new FailedPredicateException(this, "precpred(_ctx, 6)"); - setState(85); + setState(87); _la = _input.LA(1); if ( !(_la==SYMBOLIC_OR || _la==OR) ) { _errHandler.recoverInline(this); @@ -444,7 +446,7 @@ private SpelExprContext spelExpr(int _p) throws RecognitionException { _errHandler.reportMatch(this); consume(); } - setState(86); + setState(88); spelExpr(7); } break; @@ -452,11 +454,11 @@ private SpelExprContext spelExpr(int _p) throws RecognitionException { { _localctx = new SpelExprContext(_parentctx, _parentState); pushNewRecursionContext(_localctx, _startState, RULE_spelExpr); - setState(87); + setState(89); if (!(precpred(_ctx, 5))) throw new FailedPredicateException(this, "precpred(_ctx, 5)"); - setState(88); + setState(90); match(MATCHES); - setState(89); + setState(91); spelExpr(6); } break; @@ -464,11 +466,11 @@ private SpelExprContext spelExpr(int _p) throws RecognitionException { { _localctx = new SpelExprContext(_parentctx, _parentState); pushNewRecursionContext(_localctx, _startState, RULE_spelExpr); - setState(90); + setState(92); if (!(precpred(_ctx, 4))) throw new FailedPredicateException(this, "precpred(_ctx, 4)"); - setState(91); + setState(93); match(ASSIGN); - setState(92); + setState(94); spelExpr(5); } break; @@ -476,11 +478,11 @@ private SpelExprContext spelExpr(int _p) throws RecognitionException { { _localctx = new SpelExprContext(_parentctx, _parentState); pushNewRecursionContext(_localctx, _startState, RULE_spelExpr); - setState(93); + setState(95); if (!(precpred(_ctx, 3))) throw new FailedPredicateException(this, "precpred(_ctx, 3)"); - setState(94); + setState(96); match(ELVIS); - setState(95); + setState(97); spelExpr(4); } break; @@ -488,15 +490,15 @@ private SpelExprContext spelExpr(int _p) throws RecognitionException { { _localctx = new SpelExprContext(_parentctx, _parentState); pushNewRecursionContext(_localctx, _startState, RULE_spelExpr); - setState(96); + setState(98); if (!(precpred(_ctx, 2))) throw new FailedPredicateException(this, "precpred(_ctx, 2)"); - setState(97); + setState(99); match(QMARK); - setState(98); + setState(100); spelExpr(0); - setState(99); + setState(101); match(COLON); - setState(100); + setState(102); spelExpr(3); } break; @@ -504,9 +506,9 @@ private SpelExprContext spelExpr(int _p) throws RecognitionException { { _localctx = new SpelExprContext(_parentctx, _parentState); pushNewRecursionContext(_localctx, _startState, RULE_spelExpr); - setState(102); + setState(104); if (!(precpred(_ctx, 12))) throw new FailedPredicateException(this, "precpred(_ctx, 12)"); - setState(103); + setState(105); _la = _input.LA(1); if ( !(_la==INC || _la==DEC) ) { _errHandler.recoverInline(this); @@ -521,7 +523,7 @@ private SpelExprContext spelExpr(int _p) throws RecognitionException { } } } - setState(108); + setState(110); _errHandler.sync(this); _alt = getInterpreter().adaptivePredict(_input,3,_ctx); } @@ -564,7 +566,7 @@ public final NodeContext node() throws RecognitionException { NodeContext _localctx = new NodeContext(_ctx, getState()); enterRule(_localctx, 4, RULE_node); try { - setState(111); + setState(113); _errHandler.sync(this); switch (_input.LA(1)) { case DOT: @@ -576,14 +578,15 @@ public final NodeContext node() throws RecognitionException { case SELECT_LAST: enterOuterAlt(_localctx, 1); { - setState(109); + setState(111); dottedNode(); } break; case LSQUARE: + case PROPERTY_PLACE_HOLDER: enterOuterAlt(_localctx, 2); { - setState(110); + setState(112); nonDottedNode(); } break; @@ -612,6 +615,9 @@ public SpelExprContext spelExpr() { public InputParameterContext inputParameter() { return getRuleContext(InputParameterContext.class,0); } + public PropertyPlaceHolderContext propertyPlaceHolder() { + return getRuleContext(PropertyPlaceHolderContext.class,0); + } public NonDottedNodeContext(ParserRuleContext parent, int invokingState) { super(parent, invokingState); } @@ -630,18 +636,18 @@ public final NonDottedNodeContext nonDottedNode() throws RecognitionException { NonDottedNodeContext _localctx = new NonDottedNodeContext(_ctx, getState()); enterRule(_localctx, 6, RULE_nonDottedNode); try { - setState(118); + setState(121); _errHandler.sync(this); switch ( getInterpreter().adaptivePredict(_input,5,_ctx) ) { case 1: enterOuterAlt(_localctx, 1); { { - setState(113); + setState(115); match(LSQUARE); - setState(114); + setState(116); spelExpr(0); - setState(115); + setState(117); match(RSQUARE); } } @@ -649,10 +655,17 @@ public final NonDottedNodeContext nonDottedNode() throws RecognitionException { case 2: enterOuterAlt(_localctx, 2); { - setState(117); + setState(119); inputParameter(); } break; + case 3: + enterOuterAlt(_localctx, 3); + { + setState(120); + propertyPlaceHolder(); + } + break; } } catch (RecognitionException re) { @@ -701,14 +714,14 @@ public final DottedNodeContext dottedNode() throws RecognitionException { enterRule(_localctx, 8, RULE_dottedNode); int _la; try { - setState(125); + setState(128); _errHandler.sync(this); switch (_input.LA(1)) { case DOT: case SAFE_NAVI: enterOuterAlt(_localctx, 1); { - setState(120); + setState(123); _la = _input.LA(1); if ( !(_la==DOT || _la==SAFE_NAVI) ) { _errHandler.recoverInline(this); @@ -718,21 +731,21 @@ public final DottedNodeContext dottedNode() throws RecognitionException { _errHandler.reportMatch(this); consume(); } - setState(121); + setState(124); methodOrProperty(); } break; case HASH: enterOuterAlt(_localctx, 2); { - setState(122); + setState(125); functionOrVar(); } break; case PROJECT: enterOuterAlt(_localctx, 3); { - setState(123); + setState(126); projection(); } break; @@ -741,7 +754,7 @@ public final DottedNodeContext dottedNode() throws RecognitionException { case SELECT_LAST: enterOuterAlt(_localctx, 4); { - setState(124); + setState(127); selection(); } break; @@ -785,26 +798,26 @@ public final FunctionOrVarContext functionOrVar() throws RecognitionException { FunctionOrVarContext _localctx = new FunctionOrVarContext(_ctx, getState()); enterRule(_localctx, 10, RULE_functionOrVar); try { - setState(132); + setState(135); _errHandler.sync(this); switch ( getInterpreter().adaptivePredict(_input,7,_ctx) ) { case 1: enterOuterAlt(_localctx, 1); { - setState(127); + setState(130); match(HASH); - setState(128); + setState(131); match(IDENTIFIER); } break; case 2: enterOuterAlt(_localctx, 2); { - setState(129); + setState(132); match(HASH); - setState(130); + setState(133); match(IDENTIFIER); - setState(131); + setState(134); methodArgs(); } break; @@ -848,11 +861,11 @@ public final MethodArgsContext methodArgs() throws RecognitionException { try { enterOuterAlt(_localctx, 1); { - setState(134); + setState(137); match(LPAREN); - setState(135); + setState(138); args(); - setState(136); + setState(139); match(RPAREN); } } @@ -900,29 +913,29 @@ public final ArgsContext args() throws RecognitionException { try { enterOuterAlt(_localctx, 1); { - setState(139); + setState(142); _errHandler.sync(this); _la = _input.LA(1); - if ((((_la) & ~0x3f) == 0 && ((1L << _la) & 540704918320619640L) != 0)) { + if ((((_la) & ~0x3f) == 0 && ((1L << _la) & 2846547927534313592L) != 0)) { { - setState(138); + setState(141); spelExpr(0); } } - setState(145); + setState(148); _errHandler.sync(this); _la = _input.LA(1); while (_la==COMMA) { { { - setState(141); + setState(144); match(COMMA); - setState(142); + setState(145); spelExpr(0); } } - setState(147); + setState(150); _errHandler.sync(this); _la = _input.LA(1); } @@ -963,22 +976,22 @@ public final MethodOrPropertyContext methodOrProperty() throws RecognitionExcept MethodOrPropertyContext _localctx = new MethodOrPropertyContext(_ctx, getState()); enterRule(_localctx, 16, RULE_methodOrProperty); try { - setState(151); + setState(154); _errHandler.sync(this); switch ( getInterpreter().adaptivePredict(_input,10,_ctx) ) { case 1: enterOuterAlt(_localctx, 1); { - setState(148); + setState(151); match(IDENTIFIER); } break; case 2: enterOuterAlt(_localctx, 2); { - setState(149); + setState(152); match(IDENTIFIER); - setState(150); + setState(153); methodArgs(); } break; @@ -1022,11 +1035,11 @@ public final ProjectionContext projection() throws RecognitionException { try { enterOuterAlt(_localctx, 1); { - setState(153); + setState(156); match(PROJECT); - setState(154); + setState(157); spelExpr(0); - setState(155); + setState(158); match(RSQUARE); } } @@ -1071,7 +1084,7 @@ public final SelectionContext selection() throws RecognitionException { try { enterOuterAlt(_localctx, 1); { - setState(157); + setState(160); _la = _input.LA(1); if ( !((((_la) & ~0x3f) == 0 && ((1L << _la) & 9127329792L) != 0)) ) { _errHandler.recoverInline(this); @@ -1081,9 +1094,9 @@ public final SelectionContext selection() throws RecognitionException { _errHandler.reportMatch(this); consume(); } - setState(158); + setState(161); spelExpr(0); - setState(159); + setState(162); match(RSQUARE); } } @@ -1136,6 +1149,9 @@ public InlineListOrMapContext inlineListOrMap() { public InputParameterContext inputParameter() { return getRuleContext(InputParameterContext.class,0); } + public PropertyPlaceHolderContext propertyPlaceHolder() { + return getRuleContext(PropertyPlaceHolderContext.class,0); + } public StartNodeContext(ParserRuleContext parent, int invokingState) { super(parent, invokingState); } @@ -1154,7 +1170,7 @@ public final StartNodeContext startNode() throws RecognitionException { StartNodeContext _localctx = new StartNodeContext(_ctx, getState()); enterRule(_localctx, 22, RULE_startNode); try { - setState(173); + setState(177); _errHandler.sync(this); switch (_input.LA(1)) { case TRUE: @@ -1164,49 +1180,49 @@ public final StartNodeContext startNode() throws RecognitionException { case STRING_LITERAL: enterOuterAlt(_localctx, 1); { - setState(161); + setState(164); literal(); } break; case LPAREN: enterOuterAlt(_localctx, 2); { - setState(162); + setState(165); parenspelExpr(); } break; case T: enterOuterAlt(_localctx, 3); { - setState(163); + setState(166); typeReference(); } break; case NULL: enterOuterAlt(_localctx, 4); { - setState(164); + setState(167); nullReference(); } break; case NEW: enterOuterAlt(_localctx, 5); { - setState(165); + setState(168); constructorReference(); } break; case IDENTIFIER: enterOuterAlt(_localctx, 6); { - setState(166); + setState(169); methodOrProperty(); } break; case HASH: enterOuterAlt(_localctx, 7); { - setState(167); + setState(170); functionOrVar(); } break; @@ -1214,14 +1230,14 @@ public final StartNodeContext startNode() throws RecognitionException { case FACTORY_BEAN_REF: enterOuterAlt(_localctx, 8); { - setState(168); + setState(171); beanReference(); } break; case PROJECT: enterOuterAlt(_localctx, 9); { - setState(169); + setState(172); projection(); } break; @@ -1230,24 +1246,31 @@ public final StartNodeContext startNode() throws RecognitionException { case SELECT_LAST: enterOuterAlt(_localctx, 10); { - setState(170); + setState(173); selection(); } break; case LCURLY: enterOuterAlt(_localctx, 11); { - setState(171); + setState(174); inlineListOrMap(); } break; case LSQUARE: enterOuterAlt(_localctx, 12); { - setState(172); + setState(175); inputParameter(); } break; + case PROPERTY_PLACE_HOLDER: + enterOuterAlt(_localctx, 13); + { + setState(176); + propertyPlaceHolder(); + } + break; default: throw new NoViableAltException(this); } @@ -1289,35 +1312,35 @@ public final LiteralContext literal() throws RecognitionException { LiteralContext _localctx = new LiteralContext(_ctx, getState()); enterRule(_localctx, 24, RULE_literal); try { - setState(179); + setState(183); _errHandler.sync(this); switch (_input.LA(1)) { case REAL_LITERAL: case INTEGER_LITERAL: enterOuterAlt(_localctx, 1); { - setState(175); + setState(179); numericLiteral(); } break; case STRING_LITERAL: enterOuterAlt(_localctx, 2); { - setState(176); + setState(180); match(STRING_LITERAL); } break; case TRUE: enterOuterAlt(_localctx, 3); { - setState(177); + setState(181); match(TRUE); } break; case FALSE: enterOuterAlt(_localctx, 4); { - setState(178); + setState(182); match(FALSE); } break; @@ -1361,7 +1384,7 @@ public final NumericLiteralContext numericLiteral() throws RecognitionException try { enterOuterAlt(_localctx, 1); { - setState(181); + setState(185); _la = _input.LA(1); if ( !(_la==REAL_LITERAL || _la==INTEGER_LITERAL) ) { _errHandler.recoverInline(this); @@ -1411,11 +1434,11 @@ public final ParenspelExprContext parenspelExpr() throws RecognitionException { try { enterOuterAlt(_localctx, 1); { - setState(183); + setState(187); match(LPAREN); - setState(184); + setState(188); spelExpr(0); - setState(185); + setState(189); match(RPAREN); } } @@ -1467,29 +1490,29 @@ public final TypeReferenceContext typeReference() throws RecognitionException { try { enterOuterAlt(_localctx, 1); { - setState(187); + setState(191); match(T); - setState(188); + setState(192); match(LPAREN); - setState(189); + setState(193); possiblyQualifiedId(); - setState(194); + setState(198); _errHandler.sync(this); _la = _input.LA(1); while (_la==LSQUARE) { { { - setState(190); + setState(194); match(LSQUARE); - setState(191); + setState(195); match(RSQUARE); } } - setState(196); + setState(200); _errHandler.sync(this); _la = _input.LA(1); } - setState(197); + setState(201); match(RPAREN); } } @@ -1535,21 +1558,21 @@ public final PossiblyQualifiedIdContext possiblyQualifiedId() throws Recognition try { enterOuterAlt(_localctx, 1); { - setState(199); + setState(203); match(IDENTIFIER); - setState(204); + setState(208); _errHandler.sync(this); _la = _input.LA(1); while (_la==DOT) { { { - setState(200); + setState(204); match(DOT); - setState(201); + setState(205); match(IDENTIFIER); } } - setState(206); + setState(210); _errHandler.sync(this); _la = _input.LA(1); } @@ -1589,7 +1612,7 @@ public final NullReferenceContext nullReference() throws RecognitionException { try { enterOuterAlt(_localctx, 1); { - setState(207); + setState(211); match(NULL); } } @@ -1650,17 +1673,17 @@ public final ConstructorReferenceContext constructorReference() throws Recogniti int _la; try { int _alt; - setState(227); + setState(231); _errHandler.sync(this); switch ( getInterpreter().adaptivePredict(_input,18,_ctx) ) { case 1: enterOuterAlt(_localctx, 1); { - setState(209); + setState(213); match(NEW); - setState(210); + setState(214); possiblyQualifiedId(); - setState(216); + setState(220); _errHandler.sync(this); _alt = 1; do { @@ -1668,19 +1691,19 @@ public final ConstructorReferenceContext constructorReference() throws Recogniti case 1: { { - setState(211); + setState(215); match(LSQUARE); - setState(213); + setState(217); _errHandler.sync(this); _la = _input.LA(1); - if ((((_la) & ~0x3f) == 0 && ((1L << _la) & 540704918320619640L) != 0)) { + if ((((_la) & ~0x3f) == 0 && ((1L << _la) & 2846547927534313592L) != 0)) { { - setState(212); + setState(216); spelExpr(0); } } - setState(215); + setState(219); match(RSQUARE); } } @@ -1688,16 +1711,16 @@ public final ConstructorReferenceContext constructorReference() throws Recogniti default: throw new NoViableAltException(this); } - setState(218); + setState(222); _errHandler.sync(this); _alt = getInterpreter().adaptivePredict(_input,16,_ctx); } while ( _alt!=2 && _alt!=org.antlr.v4.runtime.atn.ATN.INVALID_ALT_NUMBER ); - setState(221); + setState(225); _errHandler.sync(this); switch ( getInterpreter().adaptivePredict(_input,17,_ctx) ) { case 1: { - setState(220); + setState(224); inlineListOrMap(); } break; @@ -1707,11 +1730,11 @@ public final ConstructorReferenceContext constructorReference() throws Recogniti case 2: enterOuterAlt(_localctx, 2); { - setState(223); + setState(227); match(NEW); - setState(224); + setState(228); possiblyQualifiedId(); - setState(225); + setState(229); constructorArgs(); } break; @@ -1755,11 +1778,11 @@ public final ConstructorArgsContext constructorArgs() throws RecognitionExceptio try { enterOuterAlt(_localctx, 1); { - setState(229); + setState(233); match(LPAREN); - setState(230); + setState(234); args(); - setState(231); + setState(235); match(RPAREN); } } @@ -1803,48 +1826,48 @@ public final InlineListOrMapContext inlineListOrMap() throws RecognitionExceptio InlineListOrMapContext _localctx = new InlineListOrMapContext(_ctx, getState()); enterRule(_localctx, 40, RULE_inlineListOrMap); try { - setState(246); + setState(250); _errHandler.sync(this); switch ( getInterpreter().adaptivePredict(_input,19,_ctx) ) { case 1: enterOuterAlt(_localctx, 1); { - setState(233); + setState(237); match(LCURLY); - setState(234); + setState(238); match(RCURLY); } break; case 2: enterOuterAlt(_localctx, 2); { - setState(235); + setState(239); match(LCURLY); - setState(236); + setState(240); match(COLON); - setState(237); + setState(241); match(RCURLY); } break; case 3: enterOuterAlt(_localctx, 3); { - setState(238); + setState(242); match(LCURLY); - setState(239); + setState(243); listBindings(); - setState(240); + setState(244); match(RCURLY); } break; case 4: enterOuterAlt(_localctx, 4); { - setState(242); + setState(246); match(LCURLY); - setState(243); + setState(247); mapBindings(); - setState(244); + setState(248); match(RCURLY); } break; @@ -1896,23 +1919,23 @@ public final ListBindingsContext listBindings() throws RecognitionException { try { enterOuterAlt(_localctx, 1); { - setState(248); + setState(252); ((ListBindingsContext)_localctx).listBinding = listBinding(); ((ListBindingsContext)_localctx).bindings.add(((ListBindingsContext)_localctx).listBinding); - setState(253); + setState(257); _errHandler.sync(this); _la = _input.LA(1); while (_la==COMMA) { { { - setState(249); + setState(253); match(COMMA); - setState(250); + setState(254); ((ListBindingsContext)_localctx).listBinding = listBinding(); ((ListBindingsContext)_localctx).bindings.add(((ListBindingsContext)_localctx).listBinding); } } - setState(255); + setState(259); _errHandler.sync(this); _la = _input.LA(1); } @@ -1954,7 +1977,7 @@ public final ListBindingContext listBinding() throws RecognitionException { try { enterOuterAlt(_localctx, 1); { - setState(256); + setState(260); spelExpr(0); } } @@ -2004,23 +2027,23 @@ public final MapBindingsContext mapBindings() throws RecognitionException { try { enterOuterAlt(_localctx, 1); { - setState(258); + setState(262); ((MapBindingsContext)_localctx).mapBinding = mapBinding(); ((MapBindingsContext)_localctx).bindings.add(((MapBindingsContext)_localctx).mapBinding); - setState(263); + setState(267); _errHandler.sync(this); _la = _input.LA(1); while (_la==COMMA) { { { - setState(259); + setState(263); match(COMMA); - setState(260); + setState(264); ((MapBindingsContext)_localctx).mapBinding = mapBinding(); ((MapBindingsContext)_localctx).bindings.add(((MapBindingsContext)_localctx).mapBinding); } } - setState(265); + setState(269); _errHandler.sync(this); _la = _input.LA(1); } @@ -2068,11 +2091,11 @@ public final MapBindingContext mapBinding() throws RecognitionException { try { enterOuterAlt(_localctx, 1); { - setState(266); + setState(270); ((MapBindingContext)_localctx).key = spelExpr(0); - setState(267); + setState(271); match(COLON); - setState(268); + setState(272); ((MapBindingContext)_localctx).value = spelExpr(0); } } @@ -2114,7 +2137,7 @@ public final BeanReferenceContext beanReference() throws RecognitionException { try { enterOuterAlt(_localctx, 1); { - setState(270); + setState(274); _la = _input.LA(1); if ( !(_la==BEAN_REF || _la==FACTORY_BEAN_REF) ) { _errHandler.recoverInline(this); @@ -2124,7 +2147,7 @@ public final BeanReferenceContext beanReference() throws RecognitionException { _errHandler.reportMatch(this); consume(); } - setState(271); + setState(275); _la = _input.LA(1); if ( !(_la==IDENTIFIER || _la==STRING_LITERAL) ) { _errHandler.recoverInline(this); @@ -2173,11 +2196,11 @@ public final InputParameterContext inputParameter() throws RecognitionException enterOuterAlt(_localctx, 1); { { - setState(273); + setState(277); match(LSQUARE); - setState(274); + setState(278); match(INTEGER_LITERAL); - setState(275); + setState(279); match(RSQUARE); } } @@ -2193,6 +2216,44 @@ public final InputParameterContext inputParameter() throws RecognitionException return _localctx; } + @SuppressWarnings("CheckReturnValue") + public static class PropertyPlaceHolderContext extends ParserRuleContext { + public TerminalNode PROPERTY_PLACE_HOLDER() { return getToken(SpelParser.PROPERTY_PLACE_HOLDER, 0); } + public PropertyPlaceHolderContext(ParserRuleContext parent, int invokingState) { + super(parent, invokingState); + } + @Override public int getRuleIndex() { return RULE_propertyPlaceHolder; } + @Override + public void enterRule(ParseTreeListener listener) { + if ( listener instanceof SpelParserListener ) ((SpelParserListener)listener).enterPropertyPlaceHolder(this); + } + @Override + public void exitRule(ParseTreeListener listener) { + if ( listener instanceof SpelParserListener ) ((SpelParserListener)listener).exitPropertyPlaceHolder(this); + } + } + + public final PropertyPlaceHolderContext propertyPlaceHolder() throws RecognitionException { + PropertyPlaceHolderContext _localctx = new PropertyPlaceHolderContext(_ctx, getState()); + enterRule(_localctx, 54, RULE_propertyPlaceHolder); + try { + enterOuterAlt(_localctx, 1); + { + setState(281); + match(PROPERTY_PLACE_HOLDER); + } + } + catch (RecognitionException re) { + _localctx.exception = re; + _errHandler.reportError(this, re); + _errHandler.recover(this, re); + } + finally { + exitRule(); + } + return _localctx; + } + public boolean sempred(RuleContext _localctx, int ruleIndex, int predIndex) { switch (ruleIndex) { case 1: @@ -2229,7 +2290,7 @@ private boolean spelExpr_sempred(SpelExprContext _localctx, int predIndex) { } public static final String _serializedATN = - "\u0004\u0001?\u0116\u0002\u0000\u0007\u0000\u0002\u0001\u0007\u0001\u0002"+ + "\u0004\u0001@\u011c\u0002\u0000\u0007\u0000\u0002\u0001\u0007\u0001\u0002"+ "\u0002\u0007\u0002\u0002\u0003\u0007\u0003\u0002\u0004\u0007\u0004\u0002"+ "\u0005\u0007\u0005\u0002\u0006\u0007\u0006\u0002\u0007\u0007\u0007\u0002"+ "\b\u0007\b\u0002\t\u0007\t\u0002\n\u0007\n\u0002\u000b\u0007\u000b\u0002"+ @@ -2237,180 +2298,185 @@ private boolean spelExpr_sempred(SpelExprContext _localctx, int predIndex) { "\u0002\u0010\u0007\u0010\u0002\u0011\u0007\u0011\u0002\u0012\u0007\u0012"+ "\u0002\u0013\u0007\u0013\u0002\u0014\u0007\u0014\u0002\u0015\u0007\u0015"+ "\u0002\u0016\u0007\u0016\u0002\u0017\u0007\u0017\u0002\u0018\u0007\u0018"+ - "\u0002\u0019\u0007\u0019\u0002\u001a\u0007\u001a\u0001\u0000\u0001\u0000"+ - "\u0001\u0000\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001"+ - "\u0005\u0001?\b\u0001\n\u0001\f\u0001B\t\u0001\u0003\u0001D\b\u0001\u0001"+ + "\u0002\u0019\u0007\u0019\u0002\u001a\u0007\u001a\u0002\u001b\u0007\u001b"+ + "\u0001\u0000\u0001\u0000\u0001\u0000\u0001\u0001\u0001\u0001\u0001\u0001"+ + "\u0001\u0001\u0001\u0001\u0005\u0001A\b\u0001\n\u0001\f\u0001D\t\u0001"+ + "\u0003\u0001F\b\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001"+ "\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001"+ "\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001"+ "\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001"+ "\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001"+ "\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001"+ - "\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0005\u0001i\b"+ - "\u0001\n\u0001\f\u0001l\t\u0001\u0001\u0002\u0001\u0002\u0003\u0002p\b"+ - "\u0002\u0001\u0003\u0001\u0003\u0001\u0003\u0001\u0003\u0001\u0003\u0003"+ - "\u0003w\b\u0003\u0001\u0004\u0001\u0004\u0001\u0004\u0001\u0004\u0001"+ - "\u0004\u0003\u0004~\b\u0004\u0001\u0005\u0001\u0005\u0001\u0005\u0001"+ - "\u0005\u0001\u0005\u0003\u0005\u0085\b\u0005\u0001\u0006\u0001\u0006\u0001"+ - "\u0006\u0001\u0006\u0001\u0007\u0003\u0007\u008c\b\u0007\u0001\u0007\u0001"+ - "\u0007\u0005\u0007\u0090\b\u0007\n\u0007\f\u0007\u0093\t\u0007\u0001\b"+ - "\u0001\b\u0001\b\u0003\b\u0098\b\b\u0001\t\u0001\t\u0001\t\u0001\t\u0001"+ - "\n\u0001\n\u0001\n\u0001\n\u0001\u000b\u0001\u000b\u0001\u000b\u0001\u000b"+ - "\u0001\u000b\u0001\u000b\u0001\u000b\u0001\u000b\u0001\u000b\u0001\u000b"+ - "\u0001\u000b\u0001\u000b\u0003\u000b\u00ae\b\u000b\u0001\f\u0001\f\u0001"+ - "\f\u0001\f\u0003\f\u00b4\b\f\u0001\r\u0001\r\u0001\u000e\u0001\u000e\u0001"+ - "\u000e\u0001\u000e\u0001\u000f\u0001\u000f\u0001\u000f\u0001\u000f\u0001"+ - "\u000f\u0005\u000f\u00c1\b\u000f\n\u000f\f\u000f\u00c4\t\u000f\u0001\u000f"+ - "\u0001\u000f\u0001\u0010\u0001\u0010\u0001\u0010\u0005\u0010\u00cb\b\u0010"+ - "\n\u0010\f\u0010\u00ce\t\u0010\u0001\u0011\u0001\u0011\u0001\u0012\u0001"+ - "\u0012\u0001\u0012\u0001\u0012\u0003\u0012\u00d6\b\u0012\u0001\u0012\u0004"+ - "\u0012\u00d9\b\u0012\u000b\u0012\f\u0012\u00da\u0001\u0012\u0003\u0012"+ - "\u00de\b\u0012\u0001\u0012\u0001\u0012\u0001\u0012\u0001\u0012\u0003\u0012"+ - "\u00e4\b\u0012\u0001\u0013\u0001\u0013\u0001\u0013\u0001\u0013\u0001\u0014"+ - "\u0001\u0014\u0001\u0014\u0001\u0014\u0001\u0014\u0001\u0014\u0001\u0014"+ - "\u0001\u0014\u0001\u0014\u0001\u0014\u0001\u0014\u0001\u0014\u0001\u0014"+ - "\u0003\u0014\u00f7\b\u0014\u0001\u0015\u0001\u0015\u0001\u0015\u0005\u0015"+ - "\u00fc\b\u0015\n\u0015\f\u0015\u00ff\t\u0015\u0001\u0016\u0001\u0016\u0001"+ - "\u0017\u0001\u0017\u0001\u0017\u0005\u0017\u0106\b\u0017\n\u0017\f\u0017"+ - "\u0109\t\u0017\u0001\u0018\u0001\u0018\u0001\u0018\u0001\u0018\u0001\u0019"+ - "\u0001\u0019\u0001\u0019\u0001\u001a\u0001\u001a\u0001\u001a\u0001\u001a"+ - "\u0001\u001a\u0000\u0001\u0002\u001b\u0000\u0002\u0004\u0006\b\n\f\u000e"+ - "\u0010\u0012\u0014\u0016\u0018\u001a\u001c\u001e \"$&(*,.024\u0000\f\u0002"+ - "\u0000\u0003\u0006\u0017\u0017\u0001\u0000\n\f\u0002\u0000\u0004\u0004"+ - "\u0006\u0006\u0004\u0000\u0015\u0015\u0018\u0018\"%16\u0002\u0000\u001a"+ - "\u001a**\u0002\u0000\u001c\u001c))\u0002\u0000\u0003\u0003\u0005\u0005"+ - "\u0002\u0000\b\b\u001f\u001f\u0003\u0000\u0013\u0013\u001d\u001d!!\u0001"+ - "\u000089\u0002\u0000\u0012\u0012\u001b\u001b\u0002\u000077::\u0129\u0000"+ - "6\u0001\u0000\u0000\u0000\u0002C\u0001\u0000\u0000\u0000\u0004o\u0001"+ - "\u0000\u0000\u0000\u0006v\u0001\u0000\u0000\u0000\b}\u0001\u0000\u0000"+ - "\u0000\n\u0084\u0001\u0000\u0000\u0000\f\u0086\u0001\u0000\u0000\u0000"+ - "\u000e\u008b\u0001\u0000\u0000\u0000\u0010\u0097\u0001\u0000\u0000\u0000"+ - "\u0012\u0099\u0001\u0000\u0000\u0000\u0014\u009d\u0001\u0000\u0000\u0000"+ - "\u0016\u00ad\u0001\u0000\u0000\u0000\u0018\u00b3\u0001\u0000\u0000\u0000"+ - "\u001a\u00b5\u0001\u0000\u0000\u0000\u001c\u00b7\u0001\u0000\u0000\u0000"+ - "\u001e\u00bb\u0001\u0000\u0000\u0000 \u00c7\u0001\u0000\u0000\u0000\""+ - "\u00cf\u0001\u0000\u0000\u0000$\u00e3\u0001\u0000\u0000\u0000&\u00e5\u0001"+ - "\u0000\u0000\u0000(\u00f6\u0001\u0000\u0000\u0000*\u00f8\u0001\u0000\u0000"+ - "\u0000,\u0100\u0001\u0000\u0000\u0000.\u0102\u0001\u0000\u0000\u00000"+ - "\u010a\u0001\u0000\u0000\u00002\u010e\u0001\u0000\u0000\u00004\u0111\u0001"+ - "\u0000\u0000\u000067\u0003\u0002\u0001\u000078\u0005\u0000\u0000\u0001"+ - "8\u0001\u0001\u0000\u0000\u00009:\u0006\u0001\uffff\uffff\u0000:;\u0007"+ - "\u0000\u0000\u0000;D\u0003\u0002\u0001\r<@\u0003\u0016\u000b\u0000=?\u0003"+ - "\u0004\u0002\u0000>=\u0001\u0000\u0000\u0000?B\u0001\u0000\u0000\u0000"+ - "@>\u0001\u0000\u0000\u0000@A\u0001\u0000\u0000\u0000AD\u0001\u0000\u0000"+ - "\u0000B@\u0001\u0000\u0000\u0000C9\u0001\u0000\u0000\u0000C<\u0001\u0000"+ - "\u0000\u0000Dj\u0001\u0000\u0000\u0000EF\n\u000b\u0000\u0000FG\u0005\u0014"+ - "\u0000\u0000Gi\u0003\u0002\u0001\fHI\n\n\u0000\u0000IJ\u0007\u0001\u0000"+ - "\u0000Ji\u0003\u0002\u0001\u000bKL\n\t\u0000\u0000LM\u0007\u0002\u0000"+ - "\u0000Mi\u0003\u0002\u0001\nNO\n\b\u0000\u0000OP\u0007\u0003\u0000\u0000"+ - "Pi\u0003\u0002\u0001\tQR\n\u0007\u0000\u0000RS\u0007\u0004\u0000\u0000"+ - "Si\u0003\u0002\u0001\bTU\n\u0006\u0000\u0000UV\u0007\u0005\u0000\u0000"+ - "Vi\u0003\u0002\u0001\u0007WX\n\u0005\u0000\u0000XY\u00050\u0000\u0000"+ - "Yi\u0003\u0002\u0001\u0006Z[\n\u0004\u0000\u0000[\\\u0005\u0019\u0000"+ - "\u0000\\i\u0003\u0002\u0001\u0005]^\n\u0003\u0000\u0000^_\u0005\u001e"+ - "\u0000\u0000_i\u0003\u0002\u0001\u0004`a\n\u0002\u0000\u0000ab\u0005 "+ - "\u0000\u0000bc\u0003\u0002\u0001\u0000cd\u0005\u0007\u0000\u0000de\u0003"+ - "\u0002\u0001\u0003ei\u0001\u0000\u0000\u0000fg\n\f\u0000\u0000gi\u0007"+ - "\u0006\u0000\u0000hE\u0001\u0000\u0000\u0000hH\u0001\u0000\u0000\u0000"+ - "hK\u0001\u0000\u0000\u0000hN\u0001\u0000\u0000\u0000hQ\u0001\u0000\u0000"+ - "\u0000hT\u0001\u0000\u0000\u0000hW\u0001\u0000\u0000\u0000hZ\u0001\u0000"+ - "\u0000\u0000h]\u0001\u0000\u0000\u0000h`\u0001\u0000\u0000\u0000hf\u0001"+ - "\u0000\u0000\u0000il\u0001\u0000\u0000\u0000jh\u0001\u0000\u0000\u0000"+ - "jk\u0001\u0000\u0000\u0000k\u0003\u0001\u0000\u0000\u0000lj\u0001\u0000"+ - "\u0000\u0000mp\u0003\b\u0004\u0000np\u0003\u0006\u0003\u0000om\u0001\u0000"+ - "\u0000\u0000on\u0001\u0000\u0000\u0000p\u0005\u0001\u0000\u0000\u0000"+ - "qr\u0005\u000f\u0000\u0000rs\u0003\u0002\u0001\u0000st\u0005\u0010\u0000"+ - "\u0000tw\u0001\u0000\u0000\u0000uw\u00034\u001a\u0000vq\u0001\u0000\u0000"+ - "\u0000vu\u0001\u0000\u0000\u0000w\u0007\u0001\u0000\u0000\u0000xy\u0007"+ - "\u0007\u0000\u0000y~\u0003\u0010\b\u0000z~\u0003\n\u0005\u0000{~\u0003"+ - "\u0012\t\u0000|~\u0003\u0014\n\u0000}x\u0001\u0000\u0000\u0000}z\u0001"+ - "\u0000\u0000\u0000}{\u0001\u0000\u0000\u0000}|\u0001\u0000\u0000\u0000"+ - "~\t\u0001\u0000\u0000\u0000\u007f\u0080\u0005\u0011\u0000\u0000\u0080"+ - "\u0085\u00057\u0000\u0000\u0081\u0082\u0005\u0011\u0000\u0000\u0082\u0083"+ - "\u00057\u0000\u0000\u0083\u0085\u0003\f\u0006\u0000\u0084\u007f\u0001"+ - "\u0000\u0000\u0000\u0084\u0081\u0001\u0000\u0000\u0000\u0085\u000b\u0001"+ - "\u0000\u0000\u0000\u0086\u0087\u0005\r\u0000\u0000\u0087\u0088\u0003\u000e"+ - "\u0007\u0000\u0088\u0089\u0005\u000e\u0000\u0000\u0089\r\u0001\u0000\u0000"+ - "\u0000\u008a\u008c\u0003\u0002\u0001\u0000\u008b\u008a\u0001\u0000\u0000"+ - "\u0000\u008b\u008c\u0001\u0000\u0000\u0000\u008c\u0091\u0001\u0000\u0000"+ - "\u0000\u008d\u008e\u0005\t\u0000\u0000\u008e\u0090\u0003\u0002\u0001\u0000"+ - "\u008f\u008d\u0001\u0000\u0000\u0000\u0090\u0093\u0001\u0000\u0000\u0000"+ - "\u0091\u008f\u0001\u0000\u0000\u0000\u0091\u0092\u0001\u0000\u0000\u0000"+ - "\u0092\u000f\u0001\u0000\u0000\u0000\u0093\u0091\u0001\u0000\u0000\u0000"+ - "\u0094\u0098\u00057\u0000\u0000\u0095\u0096\u00057\u0000\u0000\u0096\u0098"+ - "\u0003\f\u0006\u0000\u0097\u0094\u0001\u0000\u0000\u0000\u0097\u0095\u0001"+ - "\u0000\u0000\u0000\u0098\u0011\u0001\u0000\u0000\u0000\u0099\u009a\u0005"+ - "\u0016\u0000\u0000\u009a\u009b\u0003\u0002\u0001\u0000\u009b\u009c\u0005"+ - "\u0010\u0000\u0000\u009c\u0013\u0001\u0000\u0000\u0000\u009d\u009e\u0007"+ - "\b\u0000\u0000\u009e\u009f\u0003\u0002\u0001\u0000\u009f\u00a0\u0005\u0010"+ - "\u0000\u0000\u00a0\u0015\u0001\u0000\u0000\u0000\u00a1\u00ae\u0003\u0018"+ - "\f\u0000\u00a2\u00ae\u0003\u001c\u000e\u0000\u00a3\u00ae\u0003\u001e\u000f"+ - "\u0000\u00a4\u00ae\u0003\"\u0011\u0000\u00a5\u00ae\u0003$\u0012\u0000"+ - "\u00a6\u00ae\u0003\u0010\b\u0000\u00a7\u00ae\u0003\n\u0005\u0000\u00a8"+ - "\u00ae\u00032\u0019\u0000\u00a9\u00ae\u0003\u0012\t\u0000\u00aa\u00ae"+ - "\u0003\u0014\n\u0000\u00ab\u00ae\u0003(\u0014\u0000\u00ac\u00ae\u0003"+ - "4\u001a\u0000\u00ad\u00a1\u0001\u0000\u0000\u0000\u00ad\u00a2\u0001\u0000"+ - "\u0000\u0000\u00ad\u00a3\u0001\u0000\u0000\u0000\u00ad\u00a4\u0001\u0000"+ - "\u0000\u0000\u00ad\u00a5\u0001\u0000\u0000\u0000\u00ad\u00a6\u0001\u0000"+ - "\u0000\u0000\u00ad\u00a7\u0001\u0000\u0000\u0000\u00ad\u00a8\u0001\u0000"+ - "\u0000\u0000\u00ad\u00a9\u0001\u0000\u0000\u0000\u00ad\u00aa\u0001\u0000"+ - "\u0000\u0000\u00ad\u00ab\u0001\u0000\u0000\u0000\u00ad\u00ac\u0001\u0000"+ - "\u0000\u0000\u00ae\u0017\u0001\u0000\u0000\u0000\u00af\u00b4\u0003\u001a"+ - "\r\u0000\u00b0\u00b4\u0005:\u0000\u0000\u00b1\u00b4\u0005+\u0000\u0000"+ - "\u00b2\u00b4\u0005,\u0000\u0000\u00b3\u00af\u0001\u0000\u0000\u0000\u00b3"+ - "\u00b0\u0001\u0000\u0000\u0000\u00b3\u00b1\u0001\u0000\u0000\u0000\u00b3"+ - "\u00b2\u0001\u0000\u0000\u0000\u00b4\u0019\u0001\u0000\u0000\u0000\u00b5"+ - "\u00b6\u0007\t\u0000\u0000\u00b6\u001b\u0001\u0000\u0000\u0000\u00b7\u00b8"+ - "\u0005\r\u0000\u0000\u00b8\u00b9\u0003\u0002\u0001\u0000\u00b9\u00ba\u0005"+ - "\u000e\u0000\u0000\u00ba\u001d\u0001\u0000\u0000\u0000\u00bb\u00bc\u0005"+ - "/\u0000\u0000\u00bc\u00bd\u0005\r\u0000\u0000\u00bd\u00c2\u0003 \u0010"+ - "\u0000\u00be\u00bf\u0005\u000f\u0000\u0000\u00bf\u00c1\u0005\u0010\u0000"+ - "\u0000\u00c0\u00be\u0001\u0000\u0000\u0000\u00c1\u00c4\u0001\u0000\u0000"+ - "\u0000\u00c2\u00c0\u0001\u0000\u0000\u0000\u00c2\u00c3\u0001\u0000\u0000"+ - "\u0000\u00c3\u00c5\u0001\u0000\u0000\u0000\u00c4\u00c2\u0001\u0000\u0000"+ - "\u0000\u00c5\u00c6\u0005\u000e\u0000\u0000\u00c6\u001f\u0001\u0000\u0000"+ - "\u0000\u00c7\u00cc\u00057\u0000\u0000\u00c8\u00c9\u0005\b\u0000\u0000"+ - "\u00c9\u00cb\u00057\u0000\u0000\u00ca\u00c8\u0001\u0000\u0000\u0000\u00cb"+ - "\u00ce\u0001\u0000\u0000\u0000\u00cc\u00ca\u0001\u0000\u0000\u0000\u00cc"+ - "\u00cd\u0001\u0000\u0000\u0000\u00cd!\u0001\u0000\u0000\u0000\u00ce\u00cc"+ - "\u0001\u0000\u0000\u0000\u00cf\u00d0\u0005.\u0000\u0000\u00d0#\u0001\u0000"+ - "\u0000\u0000\u00d1\u00d2\u0005-\u0000\u0000\u00d2\u00d8\u0003 \u0010\u0000"+ - "\u00d3\u00d5\u0005\u000f\u0000\u0000\u00d4\u00d6\u0003\u0002\u0001\u0000"+ - "\u00d5\u00d4\u0001\u0000\u0000\u0000\u00d5\u00d6\u0001\u0000\u0000\u0000"+ - "\u00d6\u00d7\u0001\u0000\u0000\u0000\u00d7\u00d9\u0005\u0010\u0000\u0000"+ - "\u00d8\u00d3\u0001\u0000\u0000\u0000\u00d9\u00da\u0001\u0000\u0000\u0000"+ - "\u00da\u00d8\u0001\u0000\u0000\u0000\u00da\u00db\u0001\u0000\u0000\u0000"+ - "\u00db\u00dd\u0001\u0000\u0000\u0000\u00dc\u00de\u0003(\u0014\u0000\u00dd"+ - "\u00dc\u0001\u0000\u0000\u0000\u00dd\u00de\u0001\u0000\u0000\u0000\u00de"+ - "\u00e4\u0001\u0000\u0000\u0000\u00df\u00e0\u0005-\u0000\u0000\u00e0\u00e1"+ - "\u0003 \u0010\u0000\u00e1\u00e2\u0003&\u0013\u0000\u00e2\u00e4\u0001\u0000"+ - "\u0000\u0000\u00e3\u00d1\u0001\u0000\u0000\u0000\u00e3\u00df\u0001\u0000"+ - "\u0000\u0000\u00e4%\u0001\u0000\u0000\u0000\u00e5\u00e6\u0005\r\u0000"+ - "\u0000\u00e6\u00e7\u0003\u000e\u0007\u0000\u00e7\u00e8\u0005\u000e\u0000"+ - "\u0000\u00e8\'\u0001\u0000\u0000\u0000\u00e9\u00ea\u0005&\u0000\u0000"+ - "\u00ea\u00f7\u0005\'\u0000\u0000\u00eb\u00ec\u0005&\u0000\u0000\u00ec"+ - "\u00ed\u0005\u0007\u0000\u0000\u00ed\u00f7\u0005\'\u0000\u0000\u00ee\u00ef"+ - "\u0005&\u0000\u0000\u00ef\u00f0\u0003*\u0015\u0000\u00f0\u00f1\u0005\'"+ - "\u0000\u0000\u00f1\u00f7\u0001\u0000\u0000\u0000\u00f2\u00f3\u0005&\u0000"+ - "\u0000\u00f3\u00f4\u0003.\u0017\u0000\u00f4\u00f5\u0005\'\u0000\u0000"+ - "\u00f5\u00f7\u0001\u0000\u0000\u0000\u00f6\u00e9\u0001\u0000\u0000\u0000"+ - "\u00f6\u00eb\u0001\u0000\u0000\u0000\u00f6\u00ee\u0001\u0000\u0000\u0000"+ - "\u00f6\u00f2\u0001\u0000\u0000\u0000\u00f7)\u0001\u0000\u0000\u0000\u00f8"+ - "\u00fd\u0003,\u0016\u0000\u00f9\u00fa\u0005\t\u0000\u0000\u00fa\u00fc"+ - "\u0003,\u0016\u0000\u00fb\u00f9\u0001\u0000\u0000\u0000\u00fc\u00ff\u0001"+ - "\u0000\u0000\u0000\u00fd\u00fb\u0001\u0000\u0000\u0000\u00fd\u00fe\u0001"+ - "\u0000\u0000\u0000\u00fe+\u0001\u0000\u0000\u0000\u00ff\u00fd\u0001\u0000"+ - "\u0000\u0000\u0100\u0101\u0003\u0002\u0001\u0000\u0101-\u0001\u0000\u0000"+ - "\u0000\u0102\u0107\u00030\u0018\u0000\u0103\u0104\u0005\t\u0000\u0000"+ - "\u0104\u0106\u00030\u0018\u0000\u0105\u0103\u0001\u0000\u0000\u0000\u0106"+ - "\u0109\u0001\u0000\u0000\u0000\u0107\u0105\u0001\u0000\u0000\u0000\u0107"+ - "\u0108\u0001\u0000\u0000\u0000\u0108/\u0001\u0000\u0000\u0000\u0109\u0107"+ - "\u0001\u0000\u0000\u0000\u010a\u010b\u0003\u0002\u0001\u0000\u010b\u010c"+ - "\u0005\u0007\u0000\u0000\u010c\u010d\u0003\u0002\u0001\u0000\u010d1\u0001"+ - "\u0000\u0000\u0000\u010e\u010f\u0007\n\u0000\u0000\u010f\u0110\u0007\u000b"+ - "\u0000\u0000\u01103\u0001\u0000\u0000\u0000\u0111\u0112\u0005\u000f\u0000"+ - "\u0000\u0112\u0113\u00059\u0000\u0000\u0113\u0114\u0005\u0010\u0000\u0000"+ - "\u01145\u0001\u0000\u0000\u0000\u0016@Chjov}\u0084\u008b\u0091\u0097\u00ad"+ - "\u00b3\u00c2\u00cc\u00d5\u00da\u00dd\u00e3\u00f6\u00fd\u0107"; + "\u0001\u0001\u0005\u0001k\b\u0001\n\u0001\f\u0001n\t\u0001\u0001\u0002"+ + "\u0001\u0002\u0003\u0002r\b\u0002\u0001\u0003\u0001\u0003\u0001\u0003"+ + "\u0001\u0003\u0001\u0003\u0001\u0003\u0003\u0003z\b\u0003\u0001\u0004"+ + "\u0001\u0004\u0001\u0004\u0001\u0004\u0001\u0004\u0003\u0004\u0081\b\u0004"+ + "\u0001\u0005\u0001\u0005\u0001\u0005\u0001\u0005\u0001\u0005\u0003\u0005"+ + "\u0088\b\u0005\u0001\u0006\u0001\u0006\u0001\u0006\u0001\u0006\u0001\u0007"+ + "\u0003\u0007\u008f\b\u0007\u0001\u0007\u0001\u0007\u0005\u0007\u0093\b"+ + "\u0007\n\u0007\f\u0007\u0096\t\u0007\u0001\b\u0001\b\u0001\b\u0003\b\u009b"+ + "\b\b\u0001\t\u0001\t\u0001\t\u0001\t\u0001\n\u0001\n\u0001\n\u0001\n\u0001"+ + "\u000b\u0001\u000b\u0001\u000b\u0001\u000b\u0001\u000b\u0001\u000b\u0001"+ + "\u000b\u0001\u000b\u0001\u000b\u0001\u000b\u0001\u000b\u0001\u000b\u0001"+ + "\u000b\u0003\u000b\u00b2\b\u000b\u0001\f\u0001\f\u0001\f\u0001\f\u0003"+ + "\f\u00b8\b\f\u0001\r\u0001\r\u0001\u000e\u0001\u000e\u0001\u000e\u0001"+ + "\u000e\u0001\u000f\u0001\u000f\u0001\u000f\u0001\u000f\u0001\u000f\u0005"+ + "\u000f\u00c5\b\u000f\n\u000f\f\u000f\u00c8\t\u000f\u0001\u000f\u0001\u000f"+ + "\u0001\u0010\u0001\u0010\u0001\u0010\u0005\u0010\u00cf\b\u0010\n\u0010"+ + "\f\u0010\u00d2\t\u0010\u0001\u0011\u0001\u0011\u0001\u0012\u0001\u0012"+ + "\u0001\u0012\u0001\u0012\u0003\u0012\u00da\b\u0012\u0001\u0012\u0004\u0012"+ + "\u00dd\b\u0012\u000b\u0012\f\u0012\u00de\u0001\u0012\u0003\u0012\u00e2"+ + "\b\u0012\u0001\u0012\u0001\u0012\u0001\u0012\u0001\u0012\u0003\u0012\u00e8"+ + "\b\u0012\u0001\u0013\u0001\u0013\u0001\u0013\u0001\u0013\u0001\u0014\u0001"+ + "\u0014\u0001\u0014\u0001\u0014\u0001\u0014\u0001\u0014\u0001\u0014\u0001"+ + "\u0014\u0001\u0014\u0001\u0014\u0001\u0014\u0001\u0014\u0001\u0014\u0003"+ + "\u0014\u00fb\b\u0014\u0001\u0015\u0001\u0015\u0001\u0015\u0005\u0015\u0100"+ + "\b\u0015\n\u0015\f\u0015\u0103\t\u0015\u0001\u0016\u0001\u0016\u0001\u0017"+ + "\u0001\u0017\u0001\u0017\u0005\u0017\u010a\b\u0017\n\u0017\f\u0017\u010d"+ + "\t\u0017\u0001\u0018\u0001\u0018\u0001\u0018\u0001\u0018\u0001\u0019\u0001"+ + "\u0019\u0001\u0019\u0001\u001a\u0001\u001a\u0001\u001a\u0001\u001a\u0001"+ + "\u001b\u0001\u001b\u0001\u001b\u0000\u0001\u0002\u001c\u0000\u0002\u0004"+ + "\u0006\b\n\f\u000e\u0010\u0012\u0014\u0016\u0018\u001a\u001c\u001e \""+ + "$&(*,.0246\u0000\f\u0002\u0000\u0003\u0006\u0017\u0017\u0001\u0000\n\f"+ + "\u0002\u0000\u0004\u0004\u0006\u0006\u0004\u0000\u0015\u0015\u0018\u0018"+ + "\"%16\u0002\u0000\u001a\u001a**\u0002\u0000\u001c\u001c))\u0002\u0000"+ + "\u0003\u0003\u0005\u0005\u0002\u0000\b\b\u001f\u001f\u0003\u0000\u0013"+ + "\u0013\u001d\u001d!!\u0001\u000089\u0002\u0000\u0012\u0012\u001b\u001b"+ + "\u0002\u000077::\u0130\u00008\u0001\u0000\u0000\u0000\u0002E\u0001\u0000"+ + "\u0000\u0000\u0004q\u0001\u0000\u0000\u0000\u0006y\u0001\u0000\u0000\u0000"+ + "\b\u0080\u0001\u0000\u0000\u0000\n\u0087\u0001\u0000\u0000\u0000\f\u0089"+ + "\u0001\u0000\u0000\u0000\u000e\u008e\u0001\u0000\u0000\u0000\u0010\u009a"+ + "\u0001\u0000\u0000\u0000\u0012\u009c\u0001\u0000\u0000\u0000\u0014\u00a0"+ + "\u0001\u0000\u0000\u0000\u0016\u00b1\u0001\u0000\u0000\u0000\u0018\u00b7"+ + "\u0001\u0000\u0000\u0000\u001a\u00b9\u0001\u0000\u0000\u0000\u001c\u00bb"+ + "\u0001\u0000\u0000\u0000\u001e\u00bf\u0001\u0000\u0000\u0000 \u00cb\u0001"+ + "\u0000\u0000\u0000\"\u00d3\u0001\u0000\u0000\u0000$\u00e7\u0001\u0000"+ + "\u0000\u0000&\u00e9\u0001\u0000\u0000\u0000(\u00fa\u0001\u0000\u0000\u0000"+ + "*\u00fc\u0001\u0000\u0000\u0000,\u0104\u0001\u0000\u0000\u0000.\u0106"+ + "\u0001\u0000\u0000\u00000\u010e\u0001\u0000\u0000\u00002\u0112\u0001\u0000"+ + "\u0000\u00004\u0115\u0001\u0000\u0000\u00006\u0119\u0001\u0000\u0000\u0000"+ + "89\u0003\u0002\u0001\u00009:\u0005\u0000\u0000\u0001:\u0001\u0001\u0000"+ + "\u0000\u0000;<\u0006\u0001\uffff\uffff\u0000<=\u0007\u0000\u0000\u0000"+ + "=F\u0003\u0002\u0001\r>B\u0003\u0016\u000b\u0000?A\u0003\u0004\u0002\u0000"+ + "@?\u0001\u0000\u0000\u0000AD\u0001\u0000\u0000\u0000B@\u0001\u0000\u0000"+ + "\u0000BC\u0001\u0000\u0000\u0000CF\u0001\u0000\u0000\u0000DB\u0001\u0000"+ + "\u0000\u0000E;\u0001\u0000\u0000\u0000E>\u0001\u0000\u0000\u0000Fl\u0001"+ + "\u0000\u0000\u0000GH\n\u000b\u0000\u0000HI\u0005\u0014\u0000\u0000Ik\u0003"+ + "\u0002\u0001\fJK\n\n\u0000\u0000KL\u0007\u0001\u0000\u0000Lk\u0003\u0002"+ + "\u0001\u000bMN\n\t\u0000\u0000NO\u0007\u0002\u0000\u0000Ok\u0003\u0002"+ + "\u0001\nPQ\n\b\u0000\u0000QR\u0007\u0003\u0000\u0000Rk\u0003\u0002\u0001"+ + "\tST\n\u0007\u0000\u0000TU\u0007\u0004\u0000\u0000Uk\u0003\u0002\u0001"+ + "\bVW\n\u0006\u0000\u0000WX\u0007\u0005\u0000\u0000Xk\u0003\u0002\u0001"+ + "\u0007YZ\n\u0005\u0000\u0000Z[\u00050\u0000\u0000[k\u0003\u0002\u0001"+ + "\u0006\\]\n\u0004\u0000\u0000]^\u0005\u0019\u0000\u0000^k\u0003\u0002"+ + "\u0001\u0005_`\n\u0003\u0000\u0000`a\u0005\u001e\u0000\u0000ak\u0003\u0002"+ + "\u0001\u0004bc\n\u0002\u0000\u0000cd\u0005 \u0000\u0000de\u0003\u0002"+ + "\u0001\u0000ef\u0005\u0007\u0000\u0000fg\u0003\u0002\u0001\u0003gk\u0001"+ + "\u0000\u0000\u0000hi\n\f\u0000\u0000ik\u0007\u0006\u0000\u0000jG\u0001"+ + "\u0000\u0000\u0000jJ\u0001\u0000\u0000\u0000jM\u0001\u0000\u0000\u0000"+ + "jP\u0001\u0000\u0000\u0000jS\u0001\u0000\u0000\u0000jV\u0001\u0000\u0000"+ + "\u0000jY\u0001\u0000\u0000\u0000j\\\u0001\u0000\u0000\u0000j_\u0001\u0000"+ + "\u0000\u0000jb\u0001\u0000\u0000\u0000jh\u0001\u0000\u0000\u0000kn\u0001"+ + "\u0000\u0000\u0000lj\u0001\u0000\u0000\u0000lm\u0001\u0000\u0000\u0000"+ + "m\u0003\u0001\u0000\u0000\u0000nl\u0001\u0000\u0000\u0000or\u0003\b\u0004"+ + "\u0000pr\u0003\u0006\u0003\u0000qo\u0001\u0000\u0000\u0000qp\u0001\u0000"+ + "\u0000\u0000r\u0005\u0001\u0000\u0000\u0000st\u0005\u000f\u0000\u0000"+ + "tu\u0003\u0002\u0001\u0000uv\u0005\u0010\u0000\u0000vz\u0001\u0000\u0000"+ + "\u0000wz\u00034\u001a\u0000xz\u00036\u001b\u0000ys\u0001\u0000\u0000\u0000"+ + "yw\u0001\u0000\u0000\u0000yx\u0001\u0000\u0000\u0000z\u0007\u0001\u0000"+ + "\u0000\u0000{|\u0007\u0007\u0000\u0000|\u0081\u0003\u0010\b\u0000}\u0081"+ + "\u0003\n\u0005\u0000~\u0081\u0003\u0012\t\u0000\u007f\u0081\u0003\u0014"+ + "\n\u0000\u0080{\u0001\u0000\u0000\u0000\u0080}\u0001\u0000\u0000\u0000"+ + "\u0080~\u0001\u0000\u0000\u0000\u0080\u007f\u0001\u0000\u0000\u0000\u0081"+ + "\t\u0001\u0000\u0000\u0000\u0082\u0083\u0005\u0011\u0000\u0000\u0083\u0088"+ + "\u00057\u0000\u0000\u0084\u0085\u0005\u0011\u0000\u0000\u0085\u0086\u0005"+ + "7\u0000\u0000\u0086\u0088\u0003\f\u0006\u0000\u0087\u0082\u0001\u0000"+ + "\u0000\u0000\u0087\u0084\u0001\u0000\u0000\u0000\u0088\u000b\u0001\u0000"+ + "\u0000\u0000\u0089\u008a\u0005\r\u0000\u0000\u008a\u008b\u0003\u000e\u0007"+ + "\u0000\u008b\u008c\u0005\u000e\u0000\u0000\u008c\r\u0001\u0000\u0000\u0000"+ + "\u008d\u008f\u0003\u0002\u0001\u0000\u008e\u008d\u0001\u0000\u0000\u0000"+ + "\u008e\u008f\u0001\u0000\u0000\u0000\u008f\u0094\u0001\u0000\u0000\u0000"+ + "\u0090\u0091\u0005\t\u0000\u0000\u0091\u0093\u0003\u0002\u0001\u0000\u0092"+ + "\u0090\u0001\u0000\u0000\u0000\u0093\u0096\u0001\u0000\u0000\u0000\u0094"+ + "\u0092\u0001\u0000\u0000\u0000\u0094\u0095\u0001\u0000\u0000\u0000\u0095"+ + "\u000f\u0001\u0000\u0000\u0000\u0096\u0094\u0001\u0000\u0000\u0000\u0097"+ + "\u009b\u00057\u0000\u0000\u0098\u0099\u00057\u0000\u0000\u0099\u009b\u0003"+ + "\f\u0006\u0000\u009a\u0097\u0001\u0000\u0000\u0000\u009a\u0098\u0001\u0000"+ + "\u0000\u0000\u009b\u0011\u0001\u0000\u0000\u0000\u009c\u009d\u0005\u0016"+ + "\u0000\u0000\u009d\u009e\u0003\u0002\u0001\u0000\u009e\u009f\u0005\u0010"+ + "\u0000\u0000\u009f\u0013\u0001\u0000\u0000\u0000\u00a0\u00a1\u0007\b\u0000"+ + "\u0000\u00a1\u00a2\u0003\u0002\u0001\u0000\u00a2\u00a3\u0005\u0010\u0000"+ + "\u0000\u00a3\u0015\u0001\u0000\u0000\u0000\u00a4\u00b2\u0003\u0018\f\u0000"+ + "\u00a5\u00b2\u0003\u001c\u000e\u0000\u00a6\u00b2\u0003\u001e\u000f\u0000"+ + "\u00a7\u00b2\u0003\"\u0011\u0000\u00a8\u00b2\u0003$\u0012\u0000\u00a9"+ + "\u00b2\u0003\u0010\b\u0000\u00aa\u00b2\u0003\n\u0005\u0000\u00ab\u00b2"+ + "\u00032\u0019\u0000\u00ac\u00b2\u0003\u0012\t\u0000\u00ad\u00b2\u0003"+ + "\u0014\n\u0000\u00ae\u00b2\u0003(\u0014\u0000\u00af\u00b2\u00034\u001a"+ + "\u0000\u00b0\u00b2\u00036\u001b\u0000\u00b1\u00a4\u0001\u0000\u0000\u0000"+ + "\u00b1\u00a5\u0001\u0000\u0000\u0000\u00b1\u00a6\u0001\u0000\u0000\u0000"+ + "\u00b1\u00a7\u0001\u0000\u0000\u0000\u00b1\u00a8\u0001\u0000\u0000\u0000"+ + "\u00b1\u00a9\u0001\u0000\u0000\u0000\u00b1\u00aa\u0001\u0000\u0000\u0000"+ + "\u00b1\u00ab\u0001\u0000\u0000\u0000\u00b1\u00ac\u0001\u0000\u0000\u0000"+ + "\u00b1\u00ad\u0001\u0000\u0000\u0000\u00b1\u00ae\u0001\u0000\u0000\u0000"+ + "\u00b1\u00af\u0001\u0000\u0000\u0000\u00b1\u00b0\u0001\u0000\u0000\u0000"+ + "\u00b2\u0017\u0001\u0000\u0000\u0000\u00b3\u00b8\u0003\u001a\r\u0000\u00b4"+ + "\u00b8\u0005:\u0000\u0000\u00b5\u00b8\u0005+\u0000\u0000\u00b6\u00b8\u0005"+ + ",\u0000\u0000\u00b7\u00b3\u0001\u0000\u0000\u0000\u00b7\u00b4\u0001\u0000"+ + "\u0000\u0000\u00b7\u00b5\u0001\u0000\u0000\u0000\u00b7\u00b6\u0001\u0000"+ + "\u0000\u0000\u00b8\u0019\u0001\u0000\u0000\u0000\u00b9\u00ba\u0007\t\u0000"+ + "\u0000\u00ba\u001b\u0001\u0000\u0000\u0000\u00bb\u00bc\u0005\r\u0000\u0000"+ + "\u00bc\u00bd\u0003\u0002\u0001\u0000\u00bd\u00be\u0005\u000e\u0000\u0000"+ + "\u00be\u001d\u0001\u0000\u0000\u0000\u00bf\u00c0\u0005/\u0000\u0000\u00c0"+ + "\u00c1\u0005\r\u0000\u0000\u00c1\u00c6\u0003 \u0010\u0000\u00c2\u00c3"+ + "\u0005\u000f\u0000\u0000\u00c3\u00c5\u0005\u0010\u0000\u0000\u00c4\u00c2"+ + "\u0001\u0000\u0000\u0000\u00c5\u00c8\u0001\u0000\u0000\u0000\u00c6\u00c4"+ + "\u0001\u0000\u0000\u0000\u00c6\u00c7\u0001\u0000\u0000\u0000\u00c7\u00c9"+ + "\u0001\u0000\u0000\u0000\u00c8\u00c6\u0001\u0000\u0000\u0000\u00c9\u00ca"+ + "\u0005\u000e\u0000\u0000\u00ca\u001f\u0001\u0000\u0000\u0000\u00cb\u00d0"+ + "\u00057\u0000\u0000\u00cc\u00cd\u0005\b\u0000\u0000\u00cd\u00cf\u0005"+ + "7\u0000\u0000\u00ce\u00cc\u0001\u0000\u0000\u0000\u00cf\u00d2\u0001\u0000"+ + "\u0000\u0000\u00d0\u00ce\u0001\u0000\u0000\u0000\u00d0\u00d1\u0001\u0000"+ + "\u0000\u0000\u00d1!\u0001\u0000\u0000\u0000\u00d2\u00d0\u0001\u0000\u0000"+ + "\u0000\u00d3\u00d4\u0005.\u0000\u0000\u00d4#\u0001\u0000\u0000\u0000\u00d5"+ + "\u00d6\u0005-\u0000\u0000\u00d6\u00dc\u0003 \u0010\u0000\u00d7\u00d9\u0005"+ + "\u000f\u0000\u0000\u00d8\u00da\u0003\u0002\u0001\u0000\u00d9\u00d8\u0001"+ + "\u0000\u0000\u0000\u00d9\u00da\u0001\u0000\u0000\u0000\u00da\u00db\u0001"+ + "\u0000\u0000\u0000\u00db\u00dd\u0005\u0010\u0000\u0000\u00dc\u00d7\u0001"+ + "\u0000\u0000\u0000\u00dd\u00de\u0001\u0000\u0000\u0000\u00de\u00dc\u0001"+ + "\u0000\u0000\u0000\u00de\u00df\u0001\u0000\u0000\u0000\u00df\u00e1\u0001"+ + "\u0000\u0000\u0000\u00e0\u00e2\u0003(\u0014\u0000\u00e1\u00e0\u0001\u0000"+ + "\u0000\u0000\u00e1\u00e2\u0001\u0000\u0000\u0000\u00e2\u00e8\u0001\u0000"+ + "\u0000\u0000\u00e3\u00e4\u0005-\u0000\u0000\u00e4\u00e5\u0003 \u0010\u0000"+ + "\u00e5\u00e6\u0003&\u0013\u0000\u00e6\u00e8\u0001\u0000\u0000\u0000\u00e7"+ + "\u00d5\u0001\u0000\u0000\u0000\u00e7\u00e3\u0001\u0000\u0000\u0000\u00e8"+ + "%\u0001\u0000\u0000\u0000\u00e9\u00ea\u0005\r\u0000\u0000\u00ea\u00eb"+ + "\u0003\u000e\u0007\u0000\u00eb\u00ec\u0005\u000e\u0000\u0000\u00ec\'\u0001"+ + "\u0000\u0000\u0000\u00ed\u00ee\u0005&\u0000\u0000\u00ee\u00fb\u0005\'"+ + "\u0000\u0000\u00ef\u00f0\u0005&\u0000\u0000\u00f0\u00f1\u0005\u0007\u0000"+ + "\u0000\u00f1\u00fb\u0005\'\u0000\u0000\u00f2\u00f3\u0005&\u0000\u0000"+ + "\u00f3\u00f4\u0003*\u0015\u0000\u00f4\u00f5\u0005\'\u0000\u0000\u00f5"+ + "\u00fb\u0001\u0000\u0000\u0000\u00f6\u00f7\u0005&\u0000\u0000\u00f7\u00f8"+ + "\u0003.\u0017\u0000\u00f8\u00f9\u0005\'\u0000\u0000\u00f9\u00fb\u0001"+ + "\u0000\u0000\u0000\u00fa\u00ed\u0001\u0000\u0000\u0000\u00fa\u00ef\u0001"+ + "\u0000\u0000\u0000\u00fa\u00f2\u0001\u0000\u0000\u0000\u00fa\u00f6\u0001"+ + "\u0000\u0000\u0000\u00fb)\u0001\u0000\u0000\u0000\u00fc\u0101\u0003,\u0016"+ + "\u0000\u00fd\u00fe\u0005\t\u0000\u0000\u00fe\u0100\u0003,\u0016\u0000"+ + "\u00ff\u00fd\u0001\u0000\u0000\u0000\u0100\u0103\u0001\u0000\u0000\u0000"+ + "\u0101\u00ff\u0001\u0000\u0000\u0000\u0101\u0102\u0001\u0000\u0000\u0000"+ + "\u0102+\u0001\u0000\u0000\u0000\u0103\u0101\u0001\u0000\u0000\u0000\u0104"+ + "\u0105\u0003\u0002\u0001\u0000\u0105-\u0001\u0000\u0000\u0000\u0106\u010b"+ + "\u00030\u0018\u0000\u0107\u0108\u0005\t\u0000\u0000\u0108\u010a\u0003"+ + "0\u0018\u0000\u0109\u0107\u0001\u0000\u0000\u0000\u010a\u010d\u0001\u0000"+ + "\u0000\u0000\u010b\u0109\u0001\u0000\u0000\u0000\u010b\u010c\u0001\u0000"+ + "\u0000\u0000\u010c/\u0001\u0000\u0000\u0000\u010d\u010b\u0001\u0000\u0000"+ + "\u0000\u010e\u010f\u0003\u0002\u0001\u0000\u010f\u0110\u0005\u0007\u0000"+ + "\u0000\u0110\u0111\u0003\u0002\u0001\u0000\u01111\u0001\u0000\u0000\u0000"+ + "\u0112\u0113\u0007\n\u0000\u0000\u0113\u0114\u0007\u000b\u0000\u0000\u0114"+ + "3\u0001\u0000\u0000\u0000\u0115\u0116\u0005\u000f\u0000\u0000\u0116\u0117"+ + "\u00059\u0000\u0000\u0117\u0118\u0005\u0010\u0000\u0000\u01185\u0001\u0000"+ + "\u0000\u0000\u0119\u011a\u0005=\u0000\u0000\u011a7\u0001\u0000\u0000\u0000"+ + "\u0016BEjlqy\u0080\u0087\u008e\u0094\u009a\u00b1\u00b7\u00c6\u00d0\u00d9"+ + "\u00de\u00e1\u00e7\u00fa\u0101\u010b"; public static final ATN _ATN = new ATNDeserializer().deserialize(_serializedATN.toCharArray()); static { diff --git a/headless-services/commons/jpql/src/main/java/org/springframework/ide/vscode/parser/spel/SpelParserBaseListener.java b/headless-services/commons/jpql/src/main/java/org/springframework/ide/vscode/parser/spel/SpelParserBaseListener.java index d6715035e4..9a136ce2f3 100644 --- a/headless-services/commons/jpql/src/main/java/org/springframework/ide/vscode/parser/spel/SpelParserBaseListener.java +++ b/headless-services/commons/jpql/src/main/java/org/springframework/ide/vscode/parser/spel/SpelParserBaseListener.java @@ -348,6 +348,18 @@ public class SpelParserBaseListener implements SpelParserListener { *

The default implementation does nothing.

*/ @Override public void exitInputParameter(SpelParser.InputParameterContext ctx) { } + /** + * {@inheritDoc} + * + *

The default implementation does nothing.

+ */ + @Override public void enterPropertyPlaceHolder(SpelParser.PropertyPlaceHolderContext ctx) { } + /** + * {@inheritDoc} + * + *

The default implementation does nothing.

+ */ + @Override public void exitPropertyPlaceHolder(SpelParser.PropertyPlaceHolderContext ctx) { } /** * {@inheritDoc} diff --git a/headless-services/commons/jpql/src/main/java/org/springframework/ide/vscode/parser/spel/SpelParserListener.java b/headless-services/commons/jpql/src/main/java/org/springframework/ide/vscode/parser/spel/SpelParserListener.java index a75f42e58f..fa89de92fd 100644 --- a/headless-services/commons/jpql/src/main/java/org/springframework/ide/vscode/parser/spel/SpelParserListener.java +++ b/headless-services/commons/jpql/src/main/java/org/springframework/ide/vscode/parser/spel/SpelParserListener.java @@ -289,4 +289,14 @@ public interface SpelParserListener extends ParseTreeListener { * @param ctx the parse tree */ void exitInputParameter(SpelParser.InputParameterContext ctx); + /** + * Enter a parse tree produced by {@link SpelParser#propertyPlaceHolder}. + * @param ctx the parse tree + */ + void enterPropertyPlaceHolder(SpelParser.PropertyPlaceHolderContext ctx); + /** + * Exit a parse tree produced by {@link SpelParser#propertyPlaceHolder}. + * @param ctx the parse tree + */ + void exitPropertyPlaceHolder(SpelParser.PropertyPlaceHolderContext ctx); } \ No newline at end of file diff --git a/headless-services/spring-boot-language-server/src/main/java/org/springframework/ide/vscode/boot/java/SpelProblemType.java b/headless-services/spring-boot-language-server/src/main/java/org/springframework/ide/vscode/boot/java/SpelProblemType.java index c2c683d1d7..a1eb66e18d 100644 --- a/headless-services/spring-boot-language-server/src/main/java/org/springframework/ide/vscode/boot/java/SpelProblemType.java +++ b/headless-services/spring-boot-language-server/src/main/java/org/springframework/ide/vscode/boot/java/SpelProblemType.java @@ -19,7 +19,8 @@ public enum SpelProblemType implements ProblemType { - JAVA_SPEL_EXPRESSION_SYNTAX(ERROR, "SpEL parser raised a ParseException", "SpEL Expression Syntax"); + JAVA_SPEL_EXPRESSION_SYNTAX(ERROR, "SpEL parser raised a ParseException", "SpEL Expression Syntax"), + PROPERTY_PLACE_HOLDER_SYNTAX(ERROR, "Property place holder raised a ParseException", "Property Place Holder Syntax"); private final ProblemSeverity defaultSeverity; private String description; diff --git a/headless-services/spring-boot-language-server/src/main/java/org/springframework/ide/vscode/boot/java/data/jpa/queries/AntlrUtils.java b/headless-services/spring-boot-language-server/src/main/java/org/springframework/ide/vscode/boot/java/data/jpa/queries/AntlrUtils.java new file mode 100644 index 0000000000..799e66c8b0 --- /dev/null +++ b/headless-services/spring-boot-language-server/src/main/java/org/springframework/ide/vscode/boot/java/data/jpa/queries/AntlrUtils.java @@ -0,0 +1,35 @@ +/******************************************************************************* + * Copyright (c) 2024 Broadcom, Inc. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * https://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Broadcom, Inc. - initial API and implementation + *******************************************************************************/ +package org.springframework.ide.vscode.boot.java.data.jpa.queries; + +import java.util.stream.Stream; + +import org.antlr.v4.runtime.ParserRuleContext; +import org.antlr.v4.runtime.Token; +import org.antlr.v4.runtime.tree.TerminalNode; + +public class AntlrUtils { + + public static Stream getAllLeafs(ParserRuleContext ctx) { + if (ctx.children == null) { + return Stream.empty(); + } + return ctx.children.stream().flatMap(n -> { + if (n instanceof ParserRuleContext prc) { + return getAllLeafs(prc); + } else if (n instanceof TerminalNode tn) { + return Stream.of(tn.getSymbol()); + } + return Stream.empty(); + }); + } + +} diff --git a/headless-services/spring-boot-language-server/src/main/java/org/springframework/ide/vscode/boot/java/data/jpa/queries/MySqlSemanticTokens.java b/headless-services/spring-boot-language-server/src/main/java/org/springframework/ide/vscode/boot/java/data/jpa/queries/MySqlSemanticTokens.java index 5bb2a2087e..2d462ec97c 100644 --- a/headless-services/spring-boot-language-server/src/main/java/org/springframework/ide/vscode/boot/java/data/jpa/queries/MySqlSemanticTokens.java +++ b/headless-services/spring-boot-language-server/src/main/java/org/springframework/ide/vscode/boot/java/data/jpa/queries/MySqlSemanticTokens.java @@ -26,7 +26,6 @@ import org.antlr.v4.runtime.CommonTokenStream; import org.antlr.v4.runtime.ConsoleErrorListener; import org.antlr.v4.runtime.Parser; -import org.antlr.v4.runtime.ParserRuleContext; import org.antlr.v4.runtime.RecognitionException; import org.antlr.v4.runtime.Recognizer; import org.antlr.v4.runtime.Token; @@ -201,7 +200,7 @@ public void visitErrorNode(ErrorNode node) { @Override public void exitUdfFunctionCall(UdfFunctionCallContext fc) { if (fc.fullId() != null) { - List ls = getAllLeafs(fc.fullId()).toList(); + List ls = AntlrUtils.getAllLeafs(fc.fullId()).toList(); if (!ls.isEmpty()) { semantics.put(ls.get(ls.size() - 1), "method"); } @@ -211,13 +210,13 @@ public void exitUdfFunctionCall(UdfFunctionCallContext fc) { @Override public void exitParameter(ParameterContext ctx) { if (ctx.dottedId() != null) { - getAllLeafs(ctx.dottedId()).forEach(t -> semantics.put(t, "parameter")); + AntlrUtils.getAllLeafs(ctx.dottedId()).forEach(t -> semantics.put(t, "parameter")); } if (ctx.uid() != null) { - getAllLeafs(ctx.uid()).forEach(t -> semantics.put(t, "parameter")); + AntlrUtils.getAllLeafs(ctx.uid()).forEach(t -> semantics.put(t, "parameter")); } if (ctx.decimalLiteral() != null) { - getAllLeafs(ctx.decimalLiteral()).forEach(t -> semantics.put(t, "parameter")); + AntlrUtils.getAllLeafs(ctx.decimalLiteral()).forEach(t -> semantics.put(t, "parameter")); } } @@ -278,17 +277,6 @@ public void reportAmbiguity(Parser recognizer, DFA dfa, int startIndex, int stop } - static Stream getAllLeafs(ParserRuleContext ctx) { - return ctx.children.stream().flatMap(n -> { - if (n instanceof ParserRuleContext prc) { - return getAllLeafs(prc); - } else if (n instanceof TerminalNode tn) { - return Stream.of(tn.getSymbol()); - } - return Stream.empty(); - }); - } - } diff --git a/headless-services/spring-boot-language-server/src/main/java/org/springframework/ide/vscode/boot/java/data/jpa/queries/PostgreSqlSemanticTokens.java b/headless-services/spring-boot-language-server/src/main/java/org/springframework/ide/vscode/boot/java/data/jpa/queries/PostgreSqlSemanticTokens.java index e898cd0623..cc9d50ffa2 100644 --- a/headless-services/spring-boot-language-server/src/main/java/org/springframework/ide/vscode/boot/java/data/jpa/queries/PostgreSqlSemanticTokens.java +++ b/headless-services/spring-boot-language-server/src/main/java/org/springframework/ide/vscode/boot/java/data/jpa/queries/PostgreSqlSemanticTokens.java @@ -146,7 +146,7 @@ public void exitFunc_name(Func_nameContext funcName) { @Override public void exitData_type(Data_typeContext dataType) { if (dataType.identifier() != null) { - MySqlSemanticTokens.getAllLeafs(dataType.identifier()) + AntlrUtils.getAllLeafs(dataType.identifier()) .filter(t -> t.getType() == PostgreSqlLexer.IDENTIFIER) .forEach(t -> semantics.put(t, "type")); } @@ -155,11 +155,11 @@ public void exitData_type(Data_typeContext dataType) { @Override public void exitParameter(ParameterContext param) { if (param.identifier() != null) { - MySqlSemanticTokens.getAllLeafs(param.identifier()).forEach(t -> semantics.put(t, "parameter")); + AntlrUtils.getAllLeafs(param.identifier()).forEach(t -> semantics.put(t, "parameter")); } else if (param.INTEGER_LITERAL() != null) { semantics.put(param.INTEGER_LITERAL().getSymbol(), "parameter"); } else if (param.reserved_keyword() != null) { - MySqlSemanticTokens.getAllLeafs(param.reserved_keyword()).forEach(t -> semantics.put(t, "parameter")); + AntlrUtils.getAllLeafs(param.reserved_keyword()).forEach(t -> semantics.put(t, "parameter")); } } diff --git a/headless-services/spring-boot-language-server/src/main/java/org/springframework/ide/vscode/boot/java/spel/PropertyPlaceHolderSemanticTokens.java b/headless-services/spring-boot-language-server/src/main/java/org/springframework/ide/vscode/boot/java/spel/PropertyPlaceHolderSemanticTokens.java new file mode 100644 index 0000000000..b83a402a23 --- /dev/null +++ b/headless-services/spring-boot-language-server/src/main/java/org/springframework/ide/vscode/boot/java/spel/PropertyPlaceHolderSemanticTokens.java @@ -0,0 +1,161 @@ +/******************************************************************************* + * Copyright (c) 2024 Broadcom, Inc. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * https://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Broadcom, Inc. - initial API and implementation + *******************************************************************************/ +package org.springframework.ide.vscode.boot.java.spel; + +import java.util.ArrayList; +import java.util.BitSet; +import java.util.Collections; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.Optional; +import java.util.function.Consumer; +import java.util.stream.Collectors; + +import org.antlr.v4.runtime.ANTLRErrorListener; +import org.antlr.v4.runtime.CharStreams; +import org.antlr.v4.runtime.CommonTokenStream; +import org.antlr.v4.runtime.ConsoleErrorListener; +import org.antlr.v4.runtime.Parser; +import org.antlr.v4.runtime.RecognitionException; +import org.antlr.v4.runtime.Recognizer; +import org.antlr.v4.runtime.Token; +import org.antlr.v4.runtime.atn.ATNConfigSet; +import org.antlr.v4.runtime.dfa.DFA; +import org.antlr.v4.runtime.tree.ErrorNode; +import org.antlr.v4.runtime.tree.TerminalNode; +import org.springframework.ide.vscode.boot.java.data.jpa.queries.AntlrUtils; +import org.springframework.ide.vscode.commons.languageserver.semantic.tokens.SemanticTokenData; +import org.springframework.ide.vscode.commons.languageserver.semantic.tokens.SemanticTokensDataProvider; +import org.springframework.ide.vscode.parser.placeholder.PropertyPlaceHolderBaseListener; +import org.springframework.ide.vscode.parser.placeholder.PropertyPlaceHolderLexer; +import org.springframework.ide.vscode.parser.placeholder.PropertyPlaceHolderParser; +import org.springframework.ide.vscode.parser.placeholder.PropertyPlaceHolderParser.DefaultValueContext; +import org.springframework.ide.vscode.parser.placeholder.PropertyPlaceHolderParser.KeyContext; +import org.springframework.ide.vscode.parser.placeholder.PropertyPlaceHolderParser.ValueContext; + +public class PropertyPlaceHolderSemanticTokens implements SemanticTokensDataProvider { + + private final Optional> parseErrorHandler; + + public PropertyPlaceHolderSemanticTokens(Optional> parseErrorHandler) { + this.parseErrorHandler = parseErrorHandler; + } + + @Override + public List getTokenTypes() { + return List.of("property", "string", "operator"); + } + + @Override + public List computeTokens(String text, int initialOffset) { + PropertyPlaceHolderLexer lexer = new PropertyPlaceHolderLexer(CharStreams.fromString(text)); + CommonTokenStream antlrTokens = new CommonTokenStream(lexer); + PropertyPlaceHolderParser parser = new PropertyPlaceHolderParser(antlrTokens); + + Map semantics = new HashMap<>(); + + lexer.removeErrorListener(ConsoleErrorListener.INSTANCE); + parser.removeErrorListener(ConsoleErrorListener.INSTANCE); + + List tokens = new ArrayList<>(); + + parser.addParseListener(new PropertyPlaceHolderBaseListener() { + + @Override + public void exitKey(KeyContext ctx) { + // Remove all children nodes semantics as they will be replaced by a single token spanning multiple AST nodes + AntlrUtils.getAllLeafs(ctx).forEach(semantics::remove); + int start = ctx.getStart().getStartIndex() + initialOffset; + int end = start + ctx.getText().length(); + tokens.add(new SemanticTokenData(start, end, "property", new String[0])); + } + + @Override + public void exitDefaultValue(DefaultValueContext ctx) { + AntlrUtils.getAllLeafs(ctx).forEach(semantics::remove); + if (ctx.Colon() != null) { + semantics.put(ctx.Colon().getSymbol(), "operator"); + } + if (ctx.value() != null) { + ValueContext valueCtx = ctx.value(); + int start = valueCtx.getStart().getStartIndex() + initialOffset; + int end = start + valueCtx.getText().length(); + tokens.add(new SemanticTokenData(start, end, "string", new String[0])); + } + } + + @Override + public void visitTerminal(TerminalNode node) { + processTerminalNode(node); + } + + @Override + public void visitErrorNode(ErrorNode node) { + processTerminalNode(node); + } + + private void processTerminalNode(TerminalNode node) { + Token token = node.getSymbol(); + switch (token.getType()) { + case PropertyPlaceHolderLexer.Space: + case PropertyPlaceHolderLexer.LineBreak: + case PropertyPlaceHolderLexer.EOF: + break; + case PropertyPlaceHolderLexer.Colon: + semantics.put(node.getSymbol(), "operator"); + break; + default: + semantics.put(node.getSymbol(), "property"); + } + } + + }); + + parser.addErrorListener(new ANTLRErrorListener() { + + @Override + public void syntaxError(Recognizer recognizer, Object offendingSymbol, int line, int charPositionInLine, + String msg, RecognitionException e) { + parseErrorHandler.ifPresent(h -> h.accept(e)); + } + + @Override + public void reportContextSensitivity(Parser recognizer, DFA dfa, int startIndex, int stopIndex, int prediction, + ATNConfigSet configs) { + } + + @Override + public void reportAttemptingFullContext(Parser recognizer, DFA dfa, int startIndex, int stopIndex, + BitSet conflictingAlts, ATNConfigSet configs) { + } + + @Override + public void reportAmbiguity(Parser recognizer, DFA dfa, int startIndex, int stopIndex, boolean exact, + BitSet ambigAlts, ATNConfigSet configs) { + } + }); + + + parser.start(); + + tokens.addAll(semantics.entrySet().stream() + .map(e -> new SemanticTokenData(e.getKey().getStartIndex() + initialOffset, + e.getKey().getStartIndex() + e.getKey().getText().length() + initialOffset, e.getValue(), + new String[0])) + .collect(Collectors.toList())); + + Collections.sort(tokens); + + return tokens; + } + +} diff --git a/headless-services/spring-boot-language-server/src/main/java/org/springframework/ide/vscode/boot/java/spel/SpelReconciler.java b/headless-services/spring-boot-language-server/src/main/java/org/springframework/ide/vscode/boot/java/spel/SpelReconciler.java index 772922de22..8b35334c39 100644 --- a/headless-services/spring-boot-language-server/src/main/java/org/springframework/ide/vscode/boot/java/spel/SpelReconciler.java +++ b/headless-services/spring-boot-language-server/src/main/java/org/springframework/ide/vscode/boot/java/spel/SpelReconciler.java @@ -10,20 +10,29 @@ *******************************************************************************/ package org.springframework.ide.vscode.boot.java.spel; +import org.antlr.v4.runtime.Parser; +import org.antlr.v4.runtime.ParserRuleContext; +import org.antlr.v4.runtime.tree.ErrorNode; +import org.antlr.v4.runtime.tree.ParseTreeListener; +import org.antlr.v4.runtime.tree.TerminalNode; import org.springframework.ide.vscode.boot.java.SpelProblemType; import org.springframework.ide.vscode.boot.java.data.jpa.queries.AntlrReconciler; import org.springframework.ide.vscode.commons.languageserver.reconcile.IProblemCollector; +import org.springframework.ide.vscode.parser.placeholder.PropertyPlaceHolderLexer; +import org.springframework.ide.vscode.parser.placeholder.PropertyPlaceHolderParser; import org.springframework.ide.vscode.parser.spel.SpelLexer; import org.springframework.ide.vscode.parser.spel.SpelParser; public class SpelReconciler extends AntlrReconciler { private boolean enabled; + private AntlrReconciler propertyHolderReconciler; public SpelReconciler() { super("SPEL", SpelParser.class, SpelLexer.class, "spelExpr", SpelProblemType.JAVA_SPEL_EXPRESSION_SYNTAX); this.errorOnUnrecognizedTokens = false; this.enabled = true; + this.propertyHolderReconciler = new AntlrReconciler("Place-Holder", PropertyPlaceHolderParser.class, PropertyPlaceHolderLexer.class, "start", SpelProblemType.PROPERTY_PLACE_HOLDER_SYNTAX); } public void setEnabled(boolean spelExpressionValidationEnabled) { @@ -38,4 +47,42 @@ public void reconcile(String text, int startPosition, IProblemCollector problemC super.reconcile(text, startPosition, problemCollector); } + @Override + protected Parser createParser(String text, int startPosition, IProblemCollector problemCollector) throws Exception { + Parser parser = super.createParser(text, startPosition, problemCollector); + + // Reconcile embedded SPEL + parser.addParseListener(new ParseTreeListener() { + + private void processTerminal(TerminalNode node) { + if (node.getSymbol().getType() == SpelLexer.PROPERTY_PLACE_HOLDER) { + int placeHolderStartPosition = startPosition + node.getSymbol().getStartIndex() + 2; + String content = node.getSymbol().getText().substring(2, node.getSymbol().getText().length() - 1); + propertyHolderReconciler.reconcile(content, placeHolderStartPosition, problemCollector); + } + } + + @Override + public void visitTerminal(TerminalNode node) { + processTerminal(node); + } + + @Override + public void visitErrorNode(ErrorNode node) { + processTerminal(node); + } + + @Override + public void enterEveryRule(ParserRuleContext ctx) { + } + + @Override + public void exitEveryRule(ParserRuleContext ctx) { + } + + }); + + return parser; + } + } diff --git a/headless-services/spring-boot-language-server/src/main/java/org/springframework/ide/vscode/boot/java/spel/SpelSemanticTokens.java b/headless-services/spring-boot-language-server/src/main/java/org/springframework/ide/vscode/boot/java/spel/SpelSemanticTokens.java index ae0c80d3b3..3beb378bec 100644 --- a/headless-services/spring-boot-language-server/src/main/java/org/springframework/ide/vscode/boot/java/spel/SpelSemanticTokens.java +++ b/headless-services/spring-boot-language-server/src/main/java/org/springframework/ide/vscode/boot/java/spel/SpelSemanticTokens.java @@ -14,8 +14,10 @@ import java.util.ArrayList; import java.util.BitSet; +import java.util.Collection; import java.util.Collections; import java.util.HashMap; +import java.util.LinkedHashSet; import java.util.List; import java.util.Map; import java.util.Optional; @@ -50,9 +52,11 @@ public class SpelSemanticTokens implements SemanticTokensDataProvider { private final Optional> parseErrorHandler; + private final PropertyPlaceHolderSemanticTokens propertyPlaceHolderSemanticTokens; public SpelSemanticTokens(Optional> parseErrorHandler) { this.parseErrorHandler = parseErrorHandler; + this.propertyPlaceHolderSemanticTokens = new PropertyPlaceHolderSemanticTokens(parseErrorHandler); } public SpelSemanticTokens() { @@ -61,7 +65,9 @@ public SpelSemanticTokens() { @Override public List getTokenTypes() { - return List.of("operator", "keyword", "type", "string", "number", "method", "property", "parameter"); + LinkedHashSet tokenTypes = new LinkedHashSet<>(List.of("operator", "keyword", "type", "string", "number", "method", "property", "parameter")); + tokenTypes.addAll(propertyPlaceHolderSemanticTokens.getTokenTypes()); + return tokenTypes.stream().toList(); } @Override @@ -151,6 +157,9 @@ private void processTerminalNode(TerminalNode node) { case DOUBLE_QUOTED_STRING: semantics.put(node.getSymbol(), "string"); break; + case PROPERTY_PLACE_HOLDER: + tokens.addAll(computeTokensFromPropertyPlaceHolderNode(node, initialOffset)); + break; } } @@ -260,5 +269,24 @@ public void reportAmbiguity(Parser recognizer, DFA dfa, int startIndex, int stop return tokens; } + + private Collection computeTokensFromPropertyPlaceHolderNode(TerminalNode node, + int initialOffset) { + List placeHolderTokens = new ArrayList<>(); + + int startPosition = initialOffset + node.getSymbol().getStartIndex(); + int placeHolderStartPosition = startPosition + 2; + int endPosition = startPosition + node.getText().length(); + int placeHolderEndPosition = endPosition - 1; + // '${' operator + placeHolderTokens.add(new SemanticTokenData(startPosition, placeHolderStartPosition, "operator", new String[0])); + // Property Place Holder contents + placeHolderTokens.addAll(propertyPlaceHolderSemanticTokens.computeTokens(node.getText().substring(2, node.getText().length() - 1), placeHolderStartPosition)); + // '}' operator + placeHolderTokens.add(new SemanticTokenData(placeHolderEndPosition, endPosition, "operator", new String[0])); + return placeHolderTokens; + } + + } diff --git a/headless-services/spring-boot-language-server/src/main/resources/problem-types.json b/headless-services/spring-boot-language-server/src/main/resources/problem-types.json index 41f150abda..0044bd9f3b 100644 --- a/headless-services/spring-boot-language-server/src/main/resources/problem-types.json +++ b/headless-services/spring-boot-language-server/src/main/resources/problem-types.json @@ -334,6 +334,12 @@ "label": "SpEL Expression Syntax", "description": "SpEL parser raised a ParseException", "defaultSeverity": "ERROR" + }, + { + "code": "PROPERTY_PLACE_HOLDER_SYNTAX", + "label": "Property Place Holder Syntax", + "description": "Property place holder raised a ParseException", + "defaultSeverity": "ERROR" } ] }, diff --git a/headless-services/spring-boot-language-server/src/test/java/org/springframework/ide/vscode/boot/java/spel/PropertyPlaceHolderSemanticTokensTest.java b/headless-services/spring-boot-language-server/src/test/java/org/springframework/ide/vscode/boot/java/spel/PropertyPlaceHolderSemanticTokensTest.java new file mode 100644 index 0000000000..70d018d782 --- /dev/null +++ b/headless-services/spring-boot-language-server/src/test/java/org/springframework/ide/vscode/boot/java/spel/PropertyPlaceHolderSemanticTokensTest.java @@ -0,0 +1,59 @@ +package org.springframework.ide.vscode.boot.java.spel; + +import static org.assertj.core.api.Assertions.assertThat; + +import java.util.List; +import java.util.Optional; + +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.Test; +import org.springframework.ide.vscode.commons.languageserver.semantic.tokens.SemanticTokenData; + +public class PropertyPlaceHolderSemanticTokensTest { + + private PropertyPlaceHolderSemanticTokens provider = new PropertyPlaceHolderSemanticTokens(Optional.of(Assertions::fail)); + + @Test + void propertyWithDefault() { + List tokens = provider.computeTokens("server.port:5673", 0); + assertThat(tokens.size()).isEqualTo(3); + assertThat(tokens.get(0)).isEqualTo(new SemanticTokenData(0, 11, "property", new String[0])); + assertThat(tokens.get(1)).isEqualTo(new SemanticTokenData(11, 12, "operator", new String[0])); + assertThat(tokens.get(2)).isEqualTo(new SemanticTokenData(12, 16, "string", new String[0])); + } + + @Test + void propertyOnly() { + List tokens = provider.computeTokens("server.port", 0); + assertThat(tokens.size()).isEqualTo(1); + assertThat(tokens.get(0)).isEqualTo(new SemanticTokenData(0, 11, "property", new String[0])); + } + + @Test + void propertyWithEmptyDefaulValue() { + List tokens = provider.computeTokens("server.port:", 0); + assertThat(tokens.size()).isEqualTo(3); + assertThat(tokens.get(0)).isEqualTo(new SemanticTokenData(0, 11, "property", new String[0])); + assertThat(tokens.get(1)).isEqualTo(new SemanticTokenData(11, 12, "operator", new String[0])); + assertThat(tokens.get(2)).isEqualTo(new SemanticTokenData(12, 12, "string", new String[0])); + } + + @Test + void error_1() { + provider = new PropertyPlaceHolderSemanticTokens(Optional.empty()); + List tokens = provider.computeTokens("server.:", 0); + assertThat(tokens.size()).isEqualTo(3); + assertThat(tokens.get(0)).isEqualTo(new SemanticTokenData(0, 6, "property", new String[0])); + assertThat(tokens.get(1)).isEqualTo(new SemanticTokenData(6, 7, "property", new String[0])); + assertThat(tokens.get(2)).isEqualTo(new SemanticTokenData(7, 8, "operator", new String[0])); + } + + @Test + void error_2() { + provider = new PropertyPlaceHolderSemanticTokens(Optional.empty()); + List tokens = provider.computeTokens("server.", 0); + assertThat(tokens.size()).isEqualTo(2); + assertThat(tokens.get(0)).isEqualTo(new SemanticTokenData(0, 6, "property", new String[0])); + assertThat(tokens.get(1)).isEqualTo(new SemanticTokenData(6, 7, "property", new String[0])); + } +} diff --git a/headless-services/spring-boot-language-server/src/test/java/org/springframework/ide/vscode/boot/java/spel/SpelSemanticTokensTest.java b/headless-services/spring-boot-language-server/src/test/java/org/springframework/ide/vscode/boot/java/spel/SpelSemanticTokensTest.java index c8ce227b4f..2f2410c049 100644 --- a/headless-services/spring-boot-language-server/src/test/java/org/springframework/ide/vscode/boot/java/spel/SpelSemanticTokensTest.java +++ b/headless-services/spring-boot-language-server/src/test/java/org/springframework/ide/vscode/boot/java/spel/SpelSemanticTokensTest.java @@ -143,5 +143,17 @@ void inputParameter() { assertThat(tokens.get(8)).isEqualTo(new SemanticTokenData(21, 22, "operator", new String[0])); // ) } + @Test + void withPropertyPlaceHolder() { + List tokens = provider.computeTokens("${server.port:8080} == 8080", 0); + assertThat(tokens.size()).isEqualTo(7); + assertThat(tokens.get(0)).isEqualTo(new SemanticTokenData(0, 2, "operator", new String[0])); // ${ + assertThat(tokens.get(1)).isEqualTo(new SemanticTokenData(2, 13, "property", new String[0])); // server.port + assertThat(tokens.get(2)).isEqualTo(new SemanticTokenData(13, 14, "operator", new String[0])); // : + assertThat(tokens.get(3)).isEqualTo(new SemanticTokenData(14, 18, "string", new String[0])); // 8080 + assertThat(tokens.get(4)).isEqualTo(new SemanticTokenData(18, 19, "operator", new String[0])); // } + assertThat(tokens.get(5)).isEqualTo(new SemanticTokenData(20, 22, "operator", new String[0])); // == + assertThat(tokens.get(6)).isEqualTo(new SemanticTokenData(23, 27, "number", new String[0])); // 8080 + } } diff --git a/headless-services/spring-boot-language-server/src/test/java/org/springframework/ide/vscode/boot/java/value/test/ValueSpelExpressionValidationTest.java b/headless-services/spring-boot-language-server/src/test/java/org/springframework/ide/vscode/boot/java/value/test/ValueSpelExpressionValidationTest.java index 8154b5b858..3de037695f 100644 --- a/headless-services/spring-boot-language-server/src/test/java/org/springframework/ide/vscode/boot/java/value/test/ValueSpelExpressionValidationTest.java +++ b/headless-services/spring-boot-language-server/src/test/java/org/springframework/ide/vscode/boot/java/value/test/ValueSpelExpressionValidationTest.java @@ -12,6 +12,7 @@ import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertNotNull; +import static org.junit.jupiter.api.Assertions.assertTrue; import java.io.File; import java.net.URI; @@ -43,6 +44,7 @@ import org.springframework.ide.vscode.boot.editor.harness.PropertyIndexHarness; import org.springframework.ide.vscode.boot.index.cache.IndexCache; import org.springframework.ide.vscode.boot.index.cache.IndexCacheVoid; +import org.springframework.ide.vscode.boot.java.SpelProblemType; import org.springframework.ide.vscode.boot.java.handlers.BootJavaReconcileEngine; import org.springframework.ide.vscode.boot.java.links.SourceLinkFactory; import org.springframework.ide.vscode.boot.java.links.SourceLinks; @@ -330,7 +332,7 @@ void testIncorrectSpelExpressionFoundOnCustomAnnotation() throws Exception { } @Test - void testIgnoreSpelExpressionsWithPropertyPlaceholder() throws Exception { + void testSpelExpressionsWithPropertyPlaceholder_noErrors() throws Exception { TextDocument doc = prepareDocument("@Value(\"onField\")", "@Value(value=\"#{${property.hello:false}}\")"); assertNotNull(doc); @@ -340,6 +342,23 @@ void testIgnoreSpelExpressionsWithPropertyPlaceholder() throws Exception { assertEquals(0, problems.size()); } + @Test + void testSpelExpressionsWithPropertyPlaceholder_withErrors() throws Exception { + TextDocument doc = prepareDocument("@Value(\"onField\")", "@Value(value=\"#{${property.}}\")"); + assertNotNull(doc); + + reconcileEngine.reconcile(doc, problemCollector); + + List problems = problemCollector.getCollectedProblems(); + assertEquals(1, problems.size()); + + ReconcileProblem problem = problems.get(0); + assertEquals(199, problem.getOffset()); + assertEquals(0, problem.getLength()); + assertEquals(SpelProblemType.PROPERTY_PLACE_HOLDER_SYNTAX, problem.getType()); + assertTrue(problem.getMessage().startsWith("Place-Holder:")); + } + private TextDocument prepareDocument(String selectedAnnotation, String annotationStatementBeforeTest) throws Exception { String content = IOUtils.toString(new URI(docUri), StandardCharsets.UTF_8); diff --git a/vscode-extensions/vscode-spring-boot/package.json b/vscode-extensions/vscode-spring-boot/package.json index 6400008f60..afbadefe7a 100644 --- a/vscode-extensions/vscode-spring-boot/package.json +++ b/vscode-extensions/vscode-spring-boot/package.json @@ -1068,6 +1068,18 @@ "HINT", "ERROR" ] + }, + "spring-boot.ls.problem.spel.PROPERTY_PLACE_HOLDER_SYNTAX": { + "type": "string", + "default": "ERROR", + "description": "Property place holder raised a ParseException", + "enum": [ + "IGNORE", + "INFO", + "WARNING", + "HINT", + "ERROR" + ] } } }, @@ -1312,4 +1324,4 @@ "extensionDependencies": [ "redhat.java" ] -} +} \ No newline at end of file