diff --git a/.github/workflows/unittest.yaml b/.github/workflows/unittest.yaml new file mode 100644 index 0000000..1780cd8 --- /dev/null +++ b/.github/workflows/unittest.yaml @@ -0,0 +1,31 @@ +name: Run unit tests +run-name: Testing ${{ github.actor }}'s changes +on: + push: + branches: + - main + pull_request: + branches: + - main +jobs: + unit-test: + runs-on: ubuntu-latest + + services: + age: + image: apache/age + env: + POSTGRES_PASSWORD: agens + POSTGRES_USER: postgres + POSTGRES_DB: postgres + ports: + - 5432:5432 + + steps: + - uses: actions/checkout@v3 + - uses: actions/setup-python@v4 + with: + python-version: "3.11" + - run: python -m pip install antlr4-python3-runtime==4.11.1 psycopg2 + - name: Run tests + run: python -m unittest -v test_age_py test_agtypes.py diff --git a/README.md b/README.md index b835389..353b346 100644 --- a/README.md +++ b/README.md @@ -21,7 +21,7 @@ Apache AGE is: sudo apt-get update sudo apt-get install python3-dev libpq-dev pip install --no-binary :all: psycopg2 -pip install antlr4-python3-runtime==4.9.2 +pip install antlr4-python3-runtime==4.11.1 ``` ### Install via PIP diff --git a/age/gen/AgtypeLexer.py b/age/gen/AgtypeLexer.py index 3b59334..b286b83 100644 --- a/age/gen/AgtypeLexer.py +++ b/age/gen/AgtypeLexer.py @@ -1,4 +1,4 @@ -# Generated from Agtype.g4 by ANTLR 4.9.2 +# Generated from antlr/Agtype.g4 by ANTLR 4.11.1 from antlr4 import * from io import StringIO import sys @@ -8,86 +8,76 @@ from typing.io import TextIO - def serializedATN(): - with StringIO() as buf: - buf.write("\3\u608b\ua72a\u8133\ub9ed\u417c\u3be7\u7786\u5964\2\25") - buf.write("\u00b9\b\1\4\2\t\2\4\3\t\3\4\4\t\4\4\5\t\5\4\6\t\6\4\7") - buf.write("\t\7\4\b\t\b\4\t\t\t\4\n\t\n\4\13\t\13\4\f\t\f\4\r\t\r") - buf.write("\4\16\t\16\4\17\t\17\4\20\t\20\4\21\t\21\4\22\t\22\4\23") - buf.write("\t\23\4\24\t\24\4\25\t\25\4\26\t\26\4\27\t\27\4\30\t\30") - buf.write("\4\31\t\31\4\32\t\32\4\33\t\33\3\2\3\2\3\2\3\2\3\2\3\3") - buf.write("\3\3\3\3\3\3\3\3\3\3\3\4\3\4\3\4\3\4\3\4\3\5\3\5\3\6\3") - buf.write("\6\3\7\3\7\3\b\3\b\3\t\3\t\3\n\3\n\3\13\3\13\3\13\3\f") - buf.write("\3\f\3\r\3\r\3\r\3\r\3\r\3\r\3\r\3\r\3\r\3\16\3\16\3\16") - buf.write("\3\16\3\17\3\17\7\17h\n\17\f\17\16\17k\13\17\3\20\3\20") - buf.write("\3\20\7\20p\n\20\f\20\16\20s\13\20\3\20\3\20\3\21\3\21") - buf.write("\3\21\5\21z\n\21\3\22\3\22\3\22\3\22\3\22\3\22\3\23\3") - buf.write("\23\3\24\3\24\3\25\5\25\u0087\n\25\3\25\3\25\3\26\3\26") - buf.write("\3\26\7\26\u008e\n\26\f\26\16\26\u0091\13\26\5\26\u0093") - buf.write("\n\26\3\27\5\27\u0096\n\27\3\27\3\27\3\27\3\30\5\30\u009c") - buf.write("\n\30\3\30\3\30\5\30\u00a0\n\30\3\30\3\30\3\31\3\31\6") - buf.write("\31\u00a6\n\31\r\31\16\31\u00a7\3\32\3\32\5\32\u00ac\n") - buf.write("\32\3\32\6\32\u00af\n\32\r\32\16\32\u00b0\3\33\6\33\u00b4") - buf.write("\n\33\r\33\16\33\u00b5\3\33\3\33\2\2\34\3\3\5\4\7\5\t") - buf.write("\6\13\7\r\b\17\t\21\n\23\13\25\f\27\r\31\16\33\17\35\20") - buf.write("\37\21!\2#\2%\2\'\2)\22+\2-\23/\24\61\2\63\2\65\25\3\2") - buf.write("\f\5\2C\\aac|\7\2&&\62;C\\aac|\n\2$$\61\61^^ddhhppttv") - buf.write("v\5\2\62;CHch\5\2\2!$$^^\3\2\63;\3\2\62;\4\2GGgg\4\2-") - buf.write("-//\5\2\13\f\17\17\"\"\2\u00bf\2\3\3\2\2\2\2\5\3\2\2\2") - buf.write("\2\7\3\2\2\2\2\t\3\2\2\2\2\13\3\2\2\2\2\r\3\2\2\2\2\17") - buf.write("\3\2\2\2\2\21\3\2\2\2\2\23\3\2\2\2\2\25\3\2\2\2\2\27\3") - buf.write("\2\2\2\2\31\3\2\2\2\2\33\3\2\2\2\2\35\3\2\2\2\2\37\3\2") - buf.write("\2\2\2)\3\2\2\2\2-\3\2\2\2\2/\3\2\2\2\2\65\3\2\2\2\3\67") - buf.write("\3\2\2\2\5<\3\2\2\2\7B\3\2\2\2\tG\3\2\2\2\13I\3\2\2\2") - buf.write("\rK\3\2\2\2\17M\3\2\2\2\21O\3\2\2\2\23Q\3\2\2\2\25S\3") - buf.write("\2\2\2\27V\3\2\2\2\31X\3\2\2\2\33a\3\2\2\2\35e\3\2\2\2") - buf.write("\37l\3\2\2\2!v\3\2\2\2#{\3\2\2\2%\u0081\3\2\2\2\'\u0083") - buf.write("\3\2\2\2)\u0086\3\2\2\2+\u0092\3\2\2\2-\u0095\3\2\2\2") - buf.write("/\u009b\3\2\2\2\61\u00a3\3\2\2\2\63\u00a9\3\2\2\2\65\u00b3") - buf.write("\3\2\2\2\678\7v\2\289\7t\2\29:\7w\2\2:;\7g\2\2;\4\3\2") - buf.write("\2\2<=\7h\2\2=>\7c\2\2>?\7n\2\2?@\7u\2\2@A\7g\2\2A\6\3") - buf.write("\2\2\2BC\7p\2\2CD\7w\2\2DE\7n\2\2EF\7n\2\2F\b\3\2\2\2") - buf.write("GH\7}\2\2H\n\3\2\2\2IJ\7.\2\2J\f\3\2\2\2KL\7\177\2\2L") - buf.write("\16\3\2\2\2MN\7<\2\2N\20\3\2\2\2OP\7]\2\2P\22\3\2\2\2") - buf.write("QR\7_\2\2R\24\3\2\2\2ST\7<\2\2TU\7<\2\2U\26\3\2\2\2VW") - buf.write("\7/\2\2W\30\3\2\2\2XY\7K\2\2YZ\7p\2\2Z[\7h\2\2[\\\7k\2") - buf.write("\2\\]\7p\2\2]^\7k\2\2^_\7v\2\2_`\7{\2\2`\32\3\2\2\2ab") - buf.write("\7P\2\2bc\7c\2\2cd\7P\2\2d\34\3\2\2\2ei\t\2\2\2fh\t\3") - buf.write("\2\2gf\3\2\2\2hk\3\2\2\2ig\3\2\2\2ij\3\2\2\2j\36\3\2\2") - buf.write("\2ki\3\2\2\2lq\7$\2\2mp\5!\21\2np\5\'\24\2om\3\2\2\2o") - buf.write("n\3\2\2\2ps\3\2\2\2qo\3\2\2\2qr\3\2\2\2rt\3\2\2\2sq\3") - buf.write("\2\2\2tu\7$\2\2u \3\2\2\2vy\7^\2\2wz\t\4\2\2xz\5#\22\2") - buf.write("yw\3\2\2\2yx\3\2\2\2z\"\3\2\2\2{|\7w\2\2|}\5%\23\2}~\5") - buf.write("%\23\2~\177\5%\23\2\177\u0080\5%\23\2\u0080$\3\2\2\2\u0081") - buf.write("\u0082\t\5\2\2\u0082&\3\2\2\2\u0083\u0084\n\6\2\2\u0084") - buf.write("(\3\2\2\2\u0085\u0087\7/\2\2\u0086\u0085\3\2\2\2\u0086") - buf.write("\u0087\3\2\2\2\u0087\u0088\3\2\2\2\u0088\u0089\5+\26\2") - buf.write("\u0089*\3\2\2\2\u008a\u0093\7\62\2\2\u008b\u008f\t\7\2") - buf.write("\2\u008c\u008e\t\b\2\2\u008d\u008c\3\2\2\2\u008e\u0091") - buf.write("\3\2\2\2\u008f\u008d\3\2\2\2\u008f\u0090\3\2\2\2\u0090") - buf.write("\u0093\3\2\2\2\u0091\u008f\3\2\2\2\u0092\u008a\3\2\2\2") - buf.write("\u0092\u008b\3\2\2\2\u0093,\3\2\2\2\u0094\u0096\7/\2\2") - buf.write("\u0095\u0094\3\2\2\2\u0095\u0096\3\2\2\2\u0096\u0097\3") - buf.write("\2\2\2\u0097\u0098\5+\26\2\u0098\u0099\5\61\31\2\u0099") - buf.write(".\3\2\2\2\u009a\u009c\7/\2\2\u009b\u009a\3\2\2\2\u009b") - buf.write("\u009c\3\2\2\2\u009c\u009d\3\2\2\2\u009d\u009f\5+\26\2") - buf.write("\u009e\u00a0\5\61\31\2\u009f\u009e\3\2\2\2\u009f\u00a0") - buf.write("\3\2\2\2\u00a0\u00a1\3\2\2\2\u00a1\u00a2\5\63\32\2\u00a2") - buf.write("\60\3\2\2\2\u00a3\u00a5\7\60\2\2\u00a4\u00a6\t\b\2\2\u00a5") - buf.write("\u00a4\3\2\2\2\u00a6\u00a7\3\2\2\2\u00a7\u00a5\3\2\2\2") - buf.write("\u00a7\u00a8\3\2\2\2\u00a8\62\3\2\2\2\u00a9\u00ab\t\t") - buf.write("\2\2\u00aa\u00ac\t\n\2\2\u00ab\u00aa\3\2\2\2\u00ab\u00ac") - buf.write("\3\2\2\2\u00ac\u00ae\3\2\2\2\u00ad\u00af\t\b\2\2\u00ae") - buf.write("\u00ad\3\2\2\2\u00af\u00b0\3\2\2\2\u00b0\u00ae\3\2\2\2") - buf.write("\u00b0\u00b1\3\2\2\2\u00b1\64\3\2\2\2\u00b2\u00b4\t\13") - buf.write("\2\2\u00b3\u00b2\3\2\2\2\u00b4\u00b5\3\2\2\2\u00b5\u00b3") - buf.write("\3\2\2\2\u00b5\u00b6\3\2\2\2\u00b6\u00b7\3\2\2\2\u00b7") - buf.write("\u00b8\b\33\2\2\u00b8\66\3\2\2\2\21\2ioqy\u0086\u008f") - buf.write("\u0092\u0095\u009b\u009f\u00a7\u00ab\u00b0\u00b5\3\b\2") - buf.write("\2") - return buf.getvalue() - + return [ + 4,0,19,183,6,-1,2,0,7,0,2,1,7,1,2,2,7,2,2,3,7,3,2,4,7,4,2,5,7,5, + 2,6,7,6,2,7,7,7,2,8,7,8,2,9,7,9,2,10,7,10,2,11,7,11,2,12,7,12,2, + 13,7,13,2,14,7,14,2,15,7,15,2,16,7,16,2,17,7,17,2,18,7,18,2,19,7, + 19,2,20,7,20,2,21,7,21,2,22,7,22,2,23,7,23,2,24,7,24,2,25,7,25,1, + 0,1,0,1,0,1,0,1,0,1,1,1,1,1,1,1,1,1,1,1,1,1,2,1,2,1,2,1,2,1,2,1, + 3,1,3,1,4,1,4,1,5,1,5,1,6,1,6,1,7,1,7,1,8,1,8,1,9,1,9,1,9,1,10,1, + 10,1,11,1,11,1,11,1,11,1,11,1,11,1,11,1,11,1,11,1,12,1,12,1,12,1, + 12,1,13,1,13,5,13,102,8,13,10,13,12,13,105,9,13,1,14,1,14,1,14,5, + 14,110,8,14,10,14,12,14,113,9,14,1,14,1,14,1,15,1,15,1,15,3,15,120, + 8,15,1,16,1,16,1,16,1,16,1,16,1,16,1,17,1,17,1,18,1,18,1,19,3,19, + 133,8,19,1,19,1,19,1,20,1,20,1,20,5,20,140,8,20,10,20,12,20,143, + 9,20,3,20,145,8,20,1,21,3,21,148,8,21,1,21,1,21,1,21,1,22,3,22,154, + 8,22,1,22,1,22,3,22,158,8,22,1,22,1,22,1,23,1,23,4,23,164,8,23,11, + 23,12,23,165,1,24,1,24,3,24,170,8,24,1,24,4,24,173,8,24,11,24,12, + 24,174,1,25,4,25,178,8,25,11,25,12,25,179,1,25,1,25,0,0,26,1,1,3, + 2,5,3,7,4,9,5,11,6,13,7,15,8,17,9,19,10,21,11,23,12,25,13,27,14, + 29,15,31,0,33,0,35,0,37,0,39,16,41,0,43,17,45,18,47,0,49,0,51,19, + 1,0,10,3,0,65,90,95,95,97,122,5,0,36,36,48,57,65,90,95,95,97,122, + 8,0,34,34,47,47,92,92,98,98,102,102,110,110,114,114,116,116,3,0, + 48,57,65,70,97,102,3,0,0,31,34,34,92,92,1,0,49,57,1,0,48,57,2,0, + 69,69,101,101,2,0,43,43,45,45,3,0,9,10,13,13,32,32,189,0,1,1,0,0, + 0,0,3,1,0,0,0,0,5,1,0,0,0,0,7,1,0,0,0,0,9,1,0,0,0,0,11,1,0,0,0,0, + 13,1,0,0,0,0,15,1,0,0,0,0,17,1,0,0,0,0,19,1,0,0,0,0,21,1,0,0,0,0, + 23,1,0,0,0,0,25,1,0,0,0,0,27,1,0,0,0,0,29,1,0,0,0,0,39,1,0,0,0,0, + 43,1,0,0,0,0,45,1,0,0,0,0,51,1,0,0,0,1,53,1,0,0,0,3,58,1,0,0,0,5, + 64,1,0,0,0,7,69,1,0,0,0,9,71,1,0,0,0,11,73,1,0,0,0,13,75,1,0,0,0, + 15,77,1,0,0,0,17,79,1,0,0,0,19,81,1,0,0,0,21,84,1,0,0,0,23,86,1, + 0,0,0,25,95,1,0,0,0,27,99,1,0,0,0,29,106,1,0,0,0,31,116,1,0,0,0, + 33,121,1,0,0,0,35,127,1,0,0,0,37,129,1,0,0,0,39,132,1,0,0,0,41,144, + 1,0,0,0,43,147,1,0,0,0,45,153,1,0,0,0,47,161,1,0,0,0,49,167,1,0, + 0,0,51,177,1,0,0,0,53,54,5,116,0,0,54,55,5,114,0,0,55,56,5,117,0, + 0,56,57,5,101,0,0,57,2,1,0,0,0,58,59,5,102,0,0,59,60,5,97,0,0,60, + 61,5,108,0,0,61,62,5,115,0,0,62,63,5,101,0,0,63,4,1,0,0,0,64,65, + 5,110,0,0,65,66,5,117,0,0,66,67,5,108,0,0,67,68,5,108,0,0,68,6,1, + 0,0,0,69,70,5,123,0,0,70,8,1,0,0,0,71,72,5,44,0,0,72,10,1,0,0,0, + 73,74,5,125,0,0,74,12,1,0,0,0,75,76,5,58,0,0,76,14,1,0,0,0,77,78, + 5,91,0,0,78,16,1,0,0,0,79,80,5,93,0,0,80,18,1,0,0,0,81,82,5,58,0, + 0,82,83,5,58,0,0,83,20,1,0,0,0,84,85,5,45,0,0,85,22,1,0,0,0,86,87, + 5,73,0,0,87,88,5,110,0,0,88,89,5,102,0,0,89,90,5,105,0,0,90,91,5, + 110,0,0,91,92,5,105,0,0,92,93,5,116,0,0,93,94,5,121,0,0,94,24,1, + 0,0,0,95,96,5,78,0,0,96,97,5,97,0,0,97,98,5,78,0,0,98,26,1,0,0,0, + 99,103,7,0,0,0,100,102,7,1,0,0,101,100,1,0,0,0,102,105,1,0,0,0,103, + 101,1,0,0,0,103,104,1,0,0,0,104,28,1,0,0,0,105,103,1,0,0,0,106,111, + 5,34,0,0,107,110,3,31,15,0,108,110,3,37,18,0,109,107,1,0,0,0,109, + 108,1,0,0,0,110,113,1,0,0,0,111,109,1,0,0,0,111,112,1,0,0,0,112, + 114,1,0,0,0,113,111,1,0,0,0,114,115,5,34,0,0,115,30,1,0,0,0,116, + 119,5,92,0,0,117,120,7,2,0,0,118,120,3,33,16,0,119,117,1,0,0,0,119, + 118,1,0,0,0,120,32,1,0,0,0,121,122,5,117,0,0,122,123,3,35,17,0,123, + 124,3,35,17,0,124,125,3,35,17,0,125,126,3,35,17,0,126,34,1,0,0,0, + 127,128,7,3,0,0,128,36,1,0,0,0,129,130,8,4,0,0,130,38,1,0,0,0,131, + 133,5,45,0,0,132,131,1,0,0,0,132,133,1,0,0,0,133,134,1,0,0,0,134, + 135,3,41,20,0,135,40,1,0,0,0,136,145,5,48,0,0,137,141,7,5,0,0,138, + 140,7,6,0,0,139,138,1,0,0,0,140,143,1,0,0,0,141,139,1,0,0,0,141, + 142,1,0,0,0,142,145,1,0,0,0,143,141,1,0,0,0,144,136,1,0,0,0,144, + 137,1,0,0,0,145,42,1,0,0,0,146,148,5,45,0,0,147,146,1,0,0,0,147, + 148,1,0,0,0,148,149,1,0,0,0,149,150,3,41,20,0,150,151,3,47,23,0, + 151,44,1,0,0,0,152,154,5,45,0,0,153,152,1,0,0,0,153,154,1,0,0,0, + 154,155,1,0,0,0,155,157,3,41,20,0,156,158,3,47,23,0,157,156,1,0, + 0,0,157,158,1,0,0,0,158,159,1,0,0,0,159,160,3,49,24,0,160,46,1,0, + 0,0,161,163,5,46,0,0,162,164,7,6,0,0,163,162,1,0,0,0,164,165,1,0, + 0,0,165,163,1,0,0,0,165,166,1,0,0,0,166,48,1,0,0,0,167,169,7,7,0, + 0,168,170,7,8,0,0,169,168,1,0,0,0,169,170,1,0,0,0,170,172,1,0,0, + 0,171,173,7,6,0,0,172,171,1,0,0,0,173,174,1,0,0,0,174,172,1,0,0, + 0,174,175,1,0,0,0,175,50,1,0,0,0,176,178,7,9,0,0,177,176,1,0,0,0, + 178,179,1,0,0,0,179,177,1,0,0,0,179,180,1,0,0,0,180,181,1,0,0,0, + 181,182,6,25,0,0,182,52,1,0,0,0,15,0,103,109,111,119,132,141,144, + 147,153,157,165,169,174,179,1,6,0,0 + ] class AgtypeLexer(Lexer): @@ -137,7 +127,7 @@ class AgtypeLexer(Lexer): def __init__(self, input=None, output:TextIO = sys.stdout): super().__init__(input, output) - self.checkVersion("4.9.2") + self.checkVersion("4.11.1") self._interp = LexerATNSimulator(self, self.atn, self.decisionsToDFA, PredictionContextCache()) self._actions = None self._predicates = None diff --git a/age/gen/AgtypeListener.py b/age/gen/AgtypeListener.py index f0fd8a3..1f239f5 100644 --- a/age/gen/AgtypeListener.py +++ b/age/gen/AgtypeListener.py @@ -1,4 +1,4 @@ -# Generated from Agtype.g4 by ANTLR 4.9.2 +# Generated from antlr/Agtype.g4 by ANTLR 4.11.1 from antlr4 import * if __name__ is not None and "." in __name__: from .AgtypeParser import AgtypeParser diff --git a/age/gen/AgtypeParser.py b/age/gen/AgtypeParser.py index 73539df..5251c93 100644 --- a/age/gen/AgtypeParser.py +++ b/age/gen/AgtypeParser.py @@ -1,4 +1,4 @@ -# Generated from Agtype.g4 by ANTLR 4.9.2 +# Generated from antlr/Agtype.g4 by ANTLR 4.11.1 # encoding: utf-8 from antlr4 import * from io import StringIO @@ -8,39 +8,35 @@ else: from typing.io import TextIO - def serializedATN(): - with StringIO() as buf: - buf.write("\3\u608b\ua72a\u8133\ub9ed\u417c\u3be7\u7786\u5964\3\25") - buf.write("R\4\2\t\2\4\3\t\3\4\4\t\4\4\5\t\5\4\6\t\6\4\7\t\7\4\b") - buf.write("\t\b\4\t\t\t\3\2\3\2\3\2\3\3\3\3\5\3\30\n\3\3\4\3\4\3") - buf.write("\4\3\4\3\4\3\4\3\4\3\4\5\4\"\n\4\3\5\3\5\3\5\3\5\7\5(") - buf.write("\n\5\f\5\16\5+\13\5\3\5\3\5\3\5\3\5\5\5\61\n\5\3\6\3\6") - buf.write("\3\6\3\6\3\7\3\7\3\7\3\7\7\7;\n\7\f\7\16\7>\13\7\3\7\3") - buf.write("\7\3\7\3\7\5\7D\n\7\3\b\3\b\3\b\3\t\3\t\3\t\5\tL\n\t\3") - buf.write("\t\3\t\5\tP\n\t\3\t\2\2\n\2\4\6\b\n\f\16\20\2\2\2Y\2\22") - buf.write("\3\2\2\2\4\25\3\2\2\2\6!\3\2\2\2\b\60\3\2\2\2\n\62\3\2") - buf.write("\2\2\fC\3\2\2\2\16E\3\2\2\2\20O\3\2\2\2\22\23\5\4\3\2") - buf.write("\23\24\7\2\2\3\24\3\3\2\2\2\25\27\5\6\4\2\26\30\5\16\b") - buf.write("\2\27\26\3\2\2\2\27\30\3\2\2\2\30\5\3\2\2\2\31\"\7\21") - buf.write("\2\2\32\"\7\22\2\2\33\"\5\20\t\2\34\"\7\3\2\2\35\"\7\4") - buf.write("\2\2\36\"\7\5\2\2\37\"\5\b\5\2 \"\5\f\7\2!\31\3\2\2\2") - buf.write("!\32\3\2\2\2!\33\3\2\2\2!\34\3\2\2\2!\35\3\2\2\2!\36\3") - buf.write("\2\2\2!\37\3\2\2\2! \3\2\2\2\"\7\3\2\2\2#$\7\6\2\2$)\5") - buf.write("\n\6\2%&\7\7\2\2&(\5\n\6\2\'%\3\2\2\2(+\3\2\2\2)\'\3\2") - buf.write("\2\2)*\3\2\2\2*,\3\2\2\2+)\3\2\2\2,-\7\b\2\2-\61\3\2\2") - buf.write("\2./\7\6\2\2/\61\7\b\2\2\60#\3\2\2\2\60.\3\2\2\2\61\t") - buf.write("\3\2\2\2\62\63\7\21\2\2\63\64\7\t\2\2\64\65\5\4\3\2\65") - buf.write("\13\3\2\2\2\66\67\7\n\2\2\67<\5\4\3\289\7\7\2\29;\5\4") - buf.write("\3\2:8\3\2\2\2;>\3\2\2\2<:\3\2\2\2<=\3\2\2\2=?\3\2\2\2") - buf.write("><\3\2\2\2?@\7\13\2\2@D\3\2\2\2AB\7\n\2\2BD\7\13\2\2C") - buf.write("\66\3\2\2\2CA\3\2\2\2D\r\3\2\2\2EF\7\f\2\2FG\7\20\2\2") - buf.write("G\17\3\2\2\2HP\7\23\2\2IP\7\24\2\2JL\7\r\2\2KJ\3\2\2\2") - buf.write("KL\3\2\2\2LM\3\2\2\2MP\7\16\2\2NP\7\17\2\2OH\3\2\2\2O") - buf.write("I\3\2\2\2OK\3\2\2\2ON\3\2\2\2P\21\3\2\2\2\n\27!)\60