diff --git a/.gitattributes b/.gitattributes index f866a77b1ba64..b6c5e9d2e83ee 100644 --- a/.gitattributes +++ b/.gitattributes @@ -4,12 +4,13 @@ CHANGELOG.asciidoc merge=union # Windows build-tools-internal/src/test/resources/org/elasticsearch/gradle/internal/release/*.asciidoc text eol=lf +# ESQL parsing and source generated related assets x-pack/plugin/esql/compute/src/main/generated/** linguist-generated=true x-pack/plugin/esql/compute/src/main/generated-src/** linguist-generated=true x-pack/plugin/esql/src/main/antlr/*.tokens linguist-generated=true x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/parser/*.interp linguist-generated=true -x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/parser/EsqlBaseLexer*.java linguist-generated=true -x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/parser/EsqlBaseParser*.java linguist-generated=true +x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/parser/*BaseLexer*.java linguist-generated=true +x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/parser/*BaseParser*.java linguist-generated=true x-pack/plugin/esql/src/main/generated/** linguist-generated=true x-pack/plugin/esql/src/main/generated-src/** linguist-generated=true diff --git a/build-tools-internal/src/main/resources/checkstyle_suppressions.xml b/build-tools-internal/src/main/resources/checkstyle_suppressions.xml index cb4a58ee453a7..8c7722e4cd1e2 100644 --- a/build-tools-internal/src/main/resources/checkstyle_suppressions.xml +++ b/build-tools-internal/src/main/resources/checkstyle_suppressions.xml @@ -12,7 +12,7 @@ - + diff --git a/x-pack/plugin/esql-core/src/main/java/org/elasticsearch/xpack/esql/core/expression/Literal.java b/x-pack/plugin/esql-core/src/main/java/org/elasticsearch/xpack/esql/core/expression/Literal.java index 6105acf5eecdc..9c347fcd96d0c 100644 --- a/x-pack/plugin/esql-core/src/main/java/org/elasticsearch/xpack/esql/core/expression/Literal.java +++ b/x-pack/plugin/esql-core/src/main/java/org/elasticsearch/xpack/esql/core/expression/Literal.java @@ -22,6 +22,7 @@ import java.io.IOException; import java.time.Duration; +import java.time.Instant; import java.util.Collection; import java.util.Objects; @@ -217,6 +218,10 @@ public static Literal timeDuration(Source source, Duration literal) { return new Literal(source, literal, DataType.TIME_DURATION); } + public static Literal dateTime(Source source, Instant literal) { + return new Literal(source, literal, DataType.DATETIME); + } + public static Literal integer(Source source, Integer literal) { return new Literal(source, literal, INTEGER); } @@ -229,6 +234,10 @@ public static Literal fromLong(Source source, Long literal) { return new Literal(source, literal, LONG); } + public static Expression fromBoolean(Source source, Boolean literal) { + return new Literal(source, literal, DataType.BOOLEAN); + } + private static BytesRef longAsWKB(DataType dataType, long encoded) { return dataType == GEO_POINT ? GEO.longAsWkb(encoded) : CARTESIAN.longAsWkb(encoded); } diff --git a/x-pack/plugin/esql-core/src/main/java/org/elasticsearch/xpack/esql/core/expression/predicate/operator/arithmetic/Arithmetics.java b/x-pack/plugin/esql-core/src/main/java/org/elasticsearch/xpack/esql/core/expression/predicate/operator/arithmetic/Arithmetics.java index 4776fd57dbfa9..7ef26250e8557 100644 --- a/x-pack/plugin/esql-core/src/main/java/org/elasticsearch/xpack/esql/core/expression/predicate/operator/arithmetic/Arithmetics.java +++ b/x-pack/plugin/esql-core/src/main/java/org/elasticsearch/xpack/esql/core/expression/predicate/operator/arithmetic/Arithmetics.java @@ -148,7 +148,7 @@ public static Number mod(Number l, Number r) { return l.intValue() % r.intValue(); } - static Number negate(Number n) { + public static Number negate(Number n) { if (n == null) { return null; } diff --git a/x-pack/plugin/esql/build.gradle b/x-pack/plugin/esql/build.gradle index 3da5a972b4d4e..7beb680653298 100644 --- a/x-pack/plugin/esql/build.gradle +++ b/x-pack/plugin/esql/build.gradle @@ -332,6 +332,8 @@ pluginManager.withPlugin('com.diffplug.spotless') { // for some reason "${outputPath}/EsqlBaseParser*.java" does not match the same files... targetExclude "src/main/java/org/elasticsearch/xpack/esql/parser/EsqlBaseLexer*.java", "src/main/java/org/elasticsearch/xpack/esql/parser/EsqlBaseParser*.java", + "src/main/java/org/elasticsearch/xpack/esql/parser/PromqlBaseLexer*.java", + "src/main/java/org/elasticsearch/xpack/esql/parser/PromqlBaseParser*.java", "src/main/generated/**/*.java", "src/main/generated-src/generated/**/*.java" toggleOffOn('begin generated imports', 'end generated imports') @@ -345,6 +347,7 @@ tasks.register("cleanGenerated", Delete) { } delete fileTree(outputPath) { include 'EsqlBase*.java' + include 'PromqlBase*.java' } } @@ -384,19 +387,59 @@ tasks.register("regenParser", JavaExec) { "${file(grammarPath)}/EsqlBaseParser.g4" } +tasks.register("regenPromqlLexer", JavaExec) { + dependsOn "cleanGenerated" + mainClass = 'org.antlr.v4.Tool' + classpath = configurations.regenerate + systemProperty 'file.encoding', 'UTF-8' + systemProperty 'user.language', 'en' + systemProperty 'user.country', 'US' + systemProperty 'user.variant', '' + args '-Werror', + '-package', 'org.elasticsearch.xpack.esql.parser', + '-listener', + '-visitor', + '-lib', "${file(grammarPath)}", + '-o', outputPath, + "${file(grammarPath)}/PromqlBaseLexer.g4" +} + +tasks.register("regenPromqlParser", JavaExec) { + dependsOn "cleanGenerated" + dependsOn "regenPromqlLexer" + mainClass = 'org.antlr.v4.Tool' + classpath = configurations.regenerate + systemProperty 'file.encoding', 'UTF-8' + systemProperty 'user.language', 'en' + systemProperty 'user.country', 'US' + systemProperty 'user.variant', '' + args '-Werror', + '-package', 'org.elasticsearch.xpack.esql.parser', + '-listener', + '-visitor', + '-lib', outputPath, + '-lib', "${file(grammarPath)}", + '-o', outputPath, + "${file(grammarPath)}/PromqlBaseParser.g4" +} + tasks.register("regen") { dependsOn "regenParser" + dependsOn "regenPromqlParser" doLast { // moves token files to grammar directory for use with IDE's ant.move(file: "${outputPath}/EsqlBaseLexer.tokens", toDir: grammarPath) ant.move(file: "${outputPath}/EsqlBaseParser.tokens", toDir: grammarPath) + ant.move(file: "${outputPath}/PromqlBaseLexer.tokens", toDir: grammarPath) + ant.move(file: "${outputPath}/PromqlBaseParser.tokens", toDir: grammarPath) + // make the generated classes package private ant.replaceregexp( - match: 'public ((interface|class) \\QEsqlBase(Parser|Lexer)\\E\\w+)', + match: 'public ((interface|class) \\Q(Es|Prom)qlBase(Parser|Lexer)\\E\\w+)', replace: '\\1', encoding: 'UTF-8' ) { - fileset(dir: outputPath, includes: 'EsqlBase*.java') + fileset(dir: outputPath, includes: '*qlBase*.java') } // nuke timestamps/filenames in generated files ant.replaceregexp( @@ -404,20 +447,21 @@ tasks.register("regen") { replace: '\\/\\/ ANTLR GENERATED CODE: DO NOT EDIT', encoding: 'UTF-8' ) { - fileset(dir: outputPath, includes: 'EsqlBase*.java') + fileset(dir: outputPath, includes: '*qlBase*.java') } // remove tabs in antlr generated files ant.replaceregexp(match: '\t', flags: 'g', replace: ' ', encoding: 'UTF-8') { - fileset(dir: outputPath, includes: 'EsqlBase*.java') + fileset(dir: outputPath, includes: '*qlBase*.java') } // suppress this-escape warnings on EsqlBaseLexer ant.replaceregexp( - match: 'public EsqlBaseLexer', - replace: '@SuppressWarnings("this-escape")${line.separator} public EsqlBaseLexer', + match: 'public ((Es|Prom)qlBaseLexer)', + replace: '@SuppressWarnings("this-escape")${line.separator} public \\1', encoding: 'UTF-8' ) { - fileset(dir: outputPath, includes: 'EsqlBaseLexer.java') + fileset(dir: outputPath, includes: '*qlBaseLexer.java') } + // suppress this-escape warnings on all internal EsqlBaseParser class constructores ant.replaceregexp( match: '([ ]+)public ([A-Z][a-z]+[a-z,A-Z]+\\()', @@ -425,11 +469,11 @@ tasks.register("regen") { replace: '\\1@SuppressWarnings("this-escape")${line.separator}\\1public \\2', encoding: 'UTF-8' ) { - fileset(dir: outputPath, includes: 'EsqlBaseParser.java') + fileset(dir: outputPath, includes: '*qlBaseParser.java') } // fix line endings ant.fixcrlf(srcdir: outputPath, eol: 'lf') { - patternset(includes: 'EsqlBase*.java') + patternset(includes: '*qlBase*.java') } } } diff --git a/x-pack/plugin/esql/qa/server/src/main/java/org/elasticsearch/xpack/esql/qa/rest/generative/GenerativeForkRestTest.java b/x-pack/plugin/esql/qa/server/src/main/java/org/elasticsearch/xpack/esql/qa/rest/generative/GenerativeForkRestTest.java index 291de3d413417..17e9441d51956 100644 --- a/x-pack/plugin/esql/qa/server/src/main/java/org/elasticsearch/xpack/esql/qa/rest/generative/GenerativeForkRestTest.java +++ b/x-pack/plugin/esql/qa/server/src/main/java/org/elasticsearch/xpack/esql/qa/rest/generative/GenerativeForkRestTest.java @@ -60,6 +60,8 @@ protected void shouldSkipTest(String testName) throws IOException { testCase.requiredCapabilities.contains(SUBQUERY_IN_FROM_COMMAND.capabilityName()) ); + assumeFalse("Tests using PROMQL are not supported for now", testCase.requiredCapabilities.contains(PROMQL_V0.capabilityName())); + assumeTrue("Cluster needs to support FORK", hasCapabilities(adminClient(), List.of(FORK_V9.capabilityName()))); } } diff --git a/x-pack/plugin/esql/qa/testFixtures/src/main/resources/k8s-timeseries-avg-over-time.csv-spec b/x-pack/plugin/esql/qa/testFixtures/src/main/resources/k8s-timeseries-avg-over-time.csv-spec index 31f704a3109d3..ec6b0b60ff1f3 100644 --- a/x-pack/plugin/esql/qa/testFixtures/src/main/resources/k8s-timeseries-avg-over-time.csv-spec +++ b/x-pack/plugin/esql/qa/testFixtures/src/main/resources/k8s-timeseries-avg-over-time.csv-spec @@ -17,6 +17,25 @@ cost:double | time_bucket:datetime 36.375 | 2024-05-10T00:11:00.000Z ; +avg_over_time_of_double_no_grouping_single_bucket +required_capability: ts_command_v0 +required_capability: tbucket +TS k8s +| STATS cost=sum(avg_over_time(network.cost)) BY time_bucket = tbucket(1h); + +cost:double | time_bucket:datetime +56.32254035241995 | 2024-05-10T00:00:00.000Z +; + +avg_over_time_of_double_no_grouping_single_bucket_promql +required_capability: promql_v0 +TS k8s +| PROMQL step 1h (sum(avg_over_time(network.cost[1h]))); + +sum(avg_over_time(network.cost[1h])):double | TBUCKET:date +56.32254035241995 | 2024-05-10T00:00:00.000Z +; + avg_over_time_of_integer required_capability: ts_command_v0 TS k8s | STATS clients = avg(avg_over_time(network.eth0.currently_connected_clients)) BY time_bucket = bucket(@timestamp,1minute) | SORT time_bucket | LIMIT 10; diff --git a/x-pack/plugin/esql/qa/testFixtures/src/main/resources/k8s-timeseries.csv-spec b/x-pack/plugin/esql/qa/testFixtures/src/main/resources/k8s-timeseries.csv-spec index 64cdae20e5635..e720eb73e1dd9 100644 --- a/x-pack/plugin/esql/qa/testFixtures/src/main/resources/k8s-timeseries.csv-spec +++ b/x-pack/plugin/esql/qa/testFixtures/src/main/resources/k8s-timeseries.csv-spec @@ -132,6 +132,25 @@ max(rate(network.total_bytes_in)): double | time_bucket:date 23.702205882352942 | 2024-05-10T00:15:00.000Z ; +oneRateWithSingleTBucket +required_capability: ts_command_v0 +required_capability: tbucket +TS k8s +| STATS max(rate(network.total_bytes_in)) BY time_bucket = tbucket(1h); + +max(rate(network.total_bytes_in)): double | time_bucket:date +4.379885057471264 | 2024-05-10T00:00:00.000Z +; + +oneRateWithSingleTBucketPromql +required_capability: promql_v0 +TS k8s +| PROMQL step 1h (max(rate(network.total_bytes_in[1h]))); + +max(rate(network.total_bytes_in[1h])):double | TBUCKET:date +4.379885057471264 | 2024-05-10T00:00:00.000Z +; + twoRatesWithBucket required_capability: ts_command_v0 TS k8s | STATS max(rate(network.total_bytes_in)), sum(rate(network.total_bytes_in)) BY time_bucket = bucket(@timestamp,5minute) | SORT time_bucket DESC | LIMIT 3; diff --git a/x-pack/plugin/esql/qa/testFixtures/src/main/resources/promql/grammar/queries-invalid.promql b/x-pack/plugin/esql/qa/testFixtures/src/main/resources/promql/grammar/queries-invalid.promql new file mode 100644 index 0000000000000..f20fae5782796 --- /dev/null +++ b/x-pack/plugin/esql/qa/testFixtures/src/main/resources/promql/grammar/queries-invalid.promql @@ -0,0 +1,325 @@ +// +// Invalid PromQL queries that the parser should reject +// +// Extracted from https://github.com/prometheus/prometheus/blob/v3.5.0/promql/parser/parse_test.go +// +// The file contains the failing query on one line, terminated by ; followed by a potential error message that +// starts with | and ends with ; +// The error message is optional and is used to roughly validate the error is as expected. +// +//""; +|no expression found in input; +//"# just a comment\n\n"; +|no expression found in input; +1+; +|unexpected end of input; +.; +|unexpected character: '.'; +2.5.; +|1:1: parse error: bad number or duration syntax: "2.5."; +100..4; +|1:1: parse error: bad number or duration syntax: "100.."; +0deadbeef; +|bad number or duration syntax: "0de"; +1 /; +|unexpected end of input; +//1; +//|unexpected op:*; +(1)); +|unexpected right parenthesis ')'; +((1); +|unclosed left parenthesis; +999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999; +|out of range; +(; +|unclosed left parenthesis; +1 and 1; +|set operator "and" not allowed in binary scalar expression; +1 == 1; +|1:3: parse error: comparisons between scalars must use BOOL modifier; +1 or 1; +|set operator "or" not allowed in binary scalar expression; +1 unless 1; +|set operator "unless" not allowed in binary scalar expression; +1 !~ 1; +|unexpected character after '!': ''; +1 = 1; +|unexpected character after '=': '~'; +-"string"; +|unary expression only allowed on expressions of type scalar or instant vector, got "string"; +-test[5m]; +|unary expression only allowed on expressions of type scalar or instant vector, got "range vector"; +//test; +//|unexpected op:*; +1 offset 1d; +|1:1: parse error: offset modifier must be preceded by an instant vector selector or range vector selector or a subquery; +foo offset 1s offset 2s; +|offset may not be set multiple times; +a - on(b) ignoring(c) d; +|1:11: parse error: unexpected ; + +// +// operators +// +foo and 1; +|set operator "and" not allowed in binary scalar expression; +1 and foo; +|set operator "and" not allowed in binary scalar expression; +foo or 1; +|set operator "or" not allowed in binary scalar expression; +1 or foo; +|set operator "or" not allowed in binary scalar expression; +foo unless 1; +|set operator "unless" not allowed in binary scalar expression; +1 unless foo; +|set operator "unless" not allowed in binary scalar expression; +1 or on(bar) foo; +|vector matching only allowed between instant vectors; +foo == on(bar) 10; +|vector matching only allowed between instant vectors; +foo + group_left(baz) bar; +|unexpected ; +foo and on(bar) group_left(baz) bar; +|no grouping allowed for "and" operation; +foo and on(bar) group_right(baz) bar; +|no grouping allowed for "and" operation; +foo or on(bar) group_left(baz) bar; +|no grouping allowed for "or" operation; +foo or on(bar) group_right(baz) bar; +|no grouping allowed for "or" operation; +foo unless on(bar) group_left(baz) bar; +|no grouping allowed for "unless" operation; +foo unless on(bar) group_right(baz) bar; +|no grouping allowed for "unless" operation; +http_requests{group="production"} + on(instance) group_left(job,instance) cpu_count{type="smp"}; +|label "instance" must not occur in ON and GROUP clause at once; +foo + bool bar; +|bool modifier can only be used on comparison operators; +foo + bool 10; +|bool modifier can only be used on comparison operators; +foo and bool 10; +|bool modifier can only be used on comparison operators; + +// +// evaluation +// +foo @ +Inf; +|1:1: parse error: timestamp out of bounds for @ modifier: +Inf; +foo @ -Inf; +|1:1: parse error: timestamp out of bounds for @ modifier: -Inf; +foo @ NaN; +|1:1: parse error: timestamp out of bounds for @ modifier: NaN; +foo @ 9223372036854775808.000000; +|1:1: parse error: timestamp out of bounds for @ modifier: 9223372036854775808.000000; +foo @ -9223372036854775809.000000; +|1:1: parse error: timestamp out of bounds for @ modifier: -9223372036854775809.000000; +sum by ("foo)(some_metric{}); +|unterminated quoted string; + +// +// selector +// +{; +|unexpected end of input inside braces; +}; +|unexpected character: '}'; +some{; +|unexpected end of input inside braces; +some}; +|unexpected character: '}'; +some_metric{a=b}; +|unexpected identifier "b" in label matching, expected string; +some_metric{a:b="b"}; +|unexpected character inside braces: ':'; +foo{a"b"}; +|unexpected character inside braces: ''; +foo{a>="b"}; +|unexpected character inside braces: '>'; +some_metric{a="\xff"}; +|1:15: parse error: invalid UTF-8 rune; +foo{gibberish}; +|unexpected "}" in label matching, expected label matching operator; +foo{1}; +|unexpected character inside braces: '1'; +{}; +|vector selector must contain at least one non-empty matcher; +{x=""}; +|vector selector must contain at least one non-empty matcher; +{x=~".*"}; +|vector selector must contain at least one non-empty matcher; +{x!~".+"}; +|vector selector must contain at least one non-empty matcher; +{x!="a"}; +|vector selector must contain at least one non-empty matcher; +foo{__name__="bar"}; +|metric name must not be set twice: "foo" or "bar"; +foo{__name__= =}; +|1:15: parse error: unexpected "=" in label matching, expected string; +foo{,}; +|unexpected "," in label matching, expected identifier or "}"; +foo{__name__ == "bar"}; +|1:15: parse error: unexpected "=" in label matching, expected string; +foo{__name__="bar" lol}; +|unexpected identifier "lol" in label matching, expected "," or "}"; +foo{"a"=}; +|unexpected "}" in label matching, expected string; + +// +// range selector +// +foo[5mm]; +|bad number or duration syntax: "5mm"; +foo[5m1]; +|bad number or duration syntax: "5m1"; +foo[5m:1m1]; +|bad number or duration syntax: "1m1"; +foo[5y1hs]; +|unknown unit "hs" in duration "5y1hs"; +foo[5m1h]; +|not a valid duration string: "5m1h"; +foo[5m1m]; +|not a valid duration string: "5m1m"; +foo[0m]; +|duration must be greater than 0; +foo["5m"]; +|1:5: parse error: unexpected in matrix selector, expected number or duration; +foo[]; +|unexpected "]" in subquery selector, expected number or duration; +foo[-1]; +|duration must be greater than 0; +some_metric[5m] OFFSET 1mm; +|bad number or duration syntax: "1mm"; +some_metric[5m] OFFSET; +|unexpected end of input in offset, expected number or duration; +some_metric OFFSET 1m[5m]; +|1:22: parse error: no offset modifiers allowed before range; +some_metric[5m] @; +|1:18: parse error: unexpected end of input in @, expected timestamp; +some_metric @ 1234 [5m]; +|1:20: parse error: no @ modifiers allowed before range; +(foo + bar)[5m]; +|1:12: parse error: ranges only allowed for vector selectors; + +// +// aggregations +// +sum without(==)(some_metric); +|unexpected op:== in grouping opts, expected label; +sum without(,)(some_metric); +|unexpected "," in grouping opts, expected label; +sum without(foo,,)(some_metric); +|unexpected "," in grouping opts, expected label; +sum some_metric by (test); +|unexpected identifier "some_metric"; +sum (some_metric) by test; +|unexpected identifier "test" in grouping opts; +sum (some_metric) by test; +|unexpected identifier "test" in grouping opts; +sum () by (test); +|no arguments for aggregate expression provided; +MIN keep_common (some_metric); +|1:5: parse error: unexpected identifier "keep_common"; +MIN (some_metric) keep_common; +|unexpected identifier "keep_common"; +sum (some_metric) without (test) by (test); +|unexpected ; +sum without (test) (some_metric) by (test); +|unexpected ; +topk(some_metric); +|wrong number of arguments for aggregate expression provided, expected 2, got 1; +topk(some_metric,); +|trailing commas not allowed in function call args; +topk(some_metric, other_metric); +|1:6: parse error: expected type scalar in aggregation parameter, got instant vector; +count_values(5, other_metric); +|1:14: parse error: expected type string in aggregation parameter, got scalar; +rate(some_metric[5m]) @ 1234; +|1:1: parse error: @ modifier must be preceded by an instant vector selector or range vector selector or a subquery; + +// +// functions +// +floor(); +|expected 1 argument(s) in call to "floor", got 0; +floor(some_metric, other_metric); +|expected 1 argument(s) in call to "floor", got 2; +floor(some_metric, 1); +|expected 1 argument(s) in call to "floor", got 2; +floor(1); +|expected type instant vector in call to function "floor", got scalar; +hour(some_metric, some_metric, some_metric); +|expected at most 1 argument(s) in call to "hour", got 3; +time(some_metric); +|expected 0 argument(s) in call to "time", got 1; +non_existent_function_far_bar(); +|unknown function with name "non_existent_function_far_bar"; +rate(some_metric); +|expected type range vector in call to function "rate", got instant vector; +label_replace(a, b, c\xff, d, .*); +|1:23: parse error: invalid UTF-8 rune; +-=; +|unexpected "="; +++-++-+-+-<; +|unexpected ; +e-+=/(0); +|unexpected "="; +a>b(); +|unknown function; +rate(avg); +|expected type range vector; +(-{}-1-{}-1-{}-1-{}-1-{}-1-{}-1-{}-1-{}-1-{}-1-{}-1-{}-1-{}-1-{}-1-{}-1-{}-1-{}-1-{}-1-{}-1-{}-1-{}-1-{}-1-{}-1-{}-1-{}-1-{}-1-{}-1-{}-1-{}-1-{}-1-{}-1-{}-1-{}-1-{}-1-{}-1-{}-1-{}-1-{}-1-{}-1-{}-1-{}-1-{}-1-{}-1-{}-1-{}-1-{}-1-{}-1-{}-1-{}-1-{}-1-{}-1-{}-1-{}-1-{}-1-{}-1-{}-1-{}-1-{}-1-{}-1-{}-1-{}-1-{}-1-{}-1-{}-1-{}-1-{}-1-{}-1-{}-1-{}-1-{}-1-{}-1-{}-1-{}-1-{}-1-{}-1-{}-1-{}-1-{}-1-{}-1-{}-1-{}-1-{}-1-{}-1-{}-1-{}-1-{}-1-{}-1-{}-1-{}-1-{}-1-{}-1-{}-1-{}-1-{}-1-{}-1-{}-1-{}-1-{}-1-{}-1-{}-1-{}-1-{}-1-{}-1-{}-1-{}-1-{}-1-{}-1-{}-1-{}-1-{}-1-{}-1-{}-1-{}-1-{}-1-{}-1-{}-1-{}-1-{}-1-{}-1-{}-1-{}-1-{}-1-{}-1-{}-1-{}-1-{}-1-{}-1-{}-1-{}-1-{}-1-{}-1-{}-1-{}-1-{}-1-{}-1-{}-1-{}-1-{}-1-{}-1-{}-1-{}-1-{}-1-{}-1-{}-1-{}-1-{}-1-{}-1-{}-1-{}-1-{}-1-{}-1-{}-1-{}-1-{}-1-{}-1-{}-1-{}-1-{}-1-{}-1-{}-1-{}-1-{}--1-{}-1-{}-1-{}-1-{}-1-{}-1-{}-1-{}-1-{}-1-{}-1-{}-1-{}-1-{}-1-{}-1-{}-1-{}-1-{}-1-{}-1-{}-1-{}-1-{}-1-{}-1-{}-1-{}-1-{}-1-{}-1-{}-1-{}-1-{}-1-{}-1-{}-1-{}--1-{}-1-{}-1-{}-1-{}-1-{}-1-{}-1-{}-1-{}-1-{}-1-{}-1-{}-1-{}-1-{}-1-{}-1-{}-1-{}-1-{}-1-{}-1-{}-1-{}--1-{}-1-{}-1-{}-1-{}-1-{}-1-{}-1-{}-1-{}-1-{}-1-{}-1-{}-1-{}-1-{}-1-{}-1-{}-1-{}-1-{}-1-{}-1-{}-1-{}-1-{}-1-{}-1-{}-1-{}-1-{}-1-{}-1-{}-1-{}-1-{}-1-{}-1-{}-1-{}-1-{}-1-{}-1-{}-1-{}-1-{}-1-{}-1-{}-1-{}-1-{}-1-{}-1-{}-1-{}-1-{}-1-{}-1-{}-1-{}-1-{}-1-{}-1-{}-1-{}-1-{}-1-{}-1-{}-1-{}-1-{}-1-{}-1-{}-1-{}-1-{}-1-{}-1-{}-1-{}-1-{}-1-{}-1-{}-1-{}-1-{}-1-{}-1-{}-1-{}-1-{}-1-{}-1-{}-1-{}-1-{}-1-{}-1-{}-1-{}-1-{}-1-{}-1-{}-1-{}-1-{}-1-{}-1-{}-1-{}-1-{}-1-{}-1-{}-1-{}-1-{}-1-{}-1-{}-1-{}-1-{}-1-{}-1-{}-1-{}-1-{}-1-{}-1-{}-1-{}-1-{}-1-{}-1-{}-1-{}-1-{}-1-{}-1-{}-1-{}-1-{}-1-{}-1-{}-1-{}-1-{}-1-{}-1-{}-1-{}-1-{}-1-{}-1-{}-1-{}-1-{}-1-{}-1-{}-1-{}-1-{}-1-{}-1-{}-1-{}-1-{}-1-{}-1-{}-1-{}-1-{}-1-{}-1-{}-1-{}-1-{}-1-{}-1-{}-1-{}-1-{}-1-{}-1-{}-1-{}-1-{}-1-{}-1-{}-1-{}-1-{}-1-{}-1-{}-1-{}-1-{}-1-{}-1-{}-1-{}-1-{}-1-{}-1-{}-1-{}-1-{}-1-{}-1-{}-1-{}-1-{}-1-{}-1-{}-1-{}-1-{}-1-{}-1-{}-1-{}-1-{}-1-{}-1-{}-1-{}-1-{}-1-{}-1-{}-1-{}-1-{}-1-{}-1-{}-1-{}-1-{}-1-{}-1-{}-1-{}-1-{}-1-{}-1-{}-1-{}-1-{}-1-{}-1-{}-1-{}-1-{}-1-{}-1-{}-1-{}-1-{}-1-{}-1-{}-1-{}-1-{}-1-{}-1-{}-1-{}-1-{}-1-{}-1-{}-1-{}-1-{}-1-{}-1-{}-1...; +|1:3: parse error: vector selector must contain at least one non-empty matcher; + +// +// strings +// +`\\``; +```; +|unterminated raw string; +"\; +|escape sequence not terminated; +"; +|escape sequence not terminated; +"\c"; +|unknown escape sequence U+0063 'c'; +"\x."; +|illegal character U+002E '.' in escape sequence; + +// +// subqueries +// +foo{bar="baz"}[; +|unexpected end of input in duration expression; +test[5d] OFFSET 10s [10m:5s]; +|1:1: parse error: subquery is only allowed on instant vector, got matrix; +(foo + bar{nm="val"})[5m:][10m:5s]; +|1:1: parse error: subquery is only allowed on instant vector, got matrix; +rate(food[1m])[1h] offset 1h; +|1:15: parse error: ranges only allowed for vector selectors; +rate(food[1m])[1h] @ 100; +|1:15: parse error: ranges only allowed for vector selectors; + +// +// preprocessor +// +start(); +|1:6: parse error: unexpected "("; +end(); +|1:4: parse error: unexpected "("; +info(rate(http_request_counter_total{}[5m]), target_info{foo="bar"}); +|1:46: parse error: expected label selectors only, got vector selector instead; + +// invalid math +foo[5s/0d]; +|division by zero; +foo offset (4d/0); +|division by zero; +foo[5s%0d]; +|modulo by zero; +foo offset 9.5e10; +|duration out of range; +foo[9.5e10]; +|duration out of range; + +sum(rate(; +|unclosed left parenthesis; diff --git a/x-pack/plugin/esql/qa/testFixtures/src/main/resources/promql/grammar/queries-valid-extra.promql b/x-pack/plugin/esql/qa/testFixtures/src/main/resources/promql/grammar/queries-valid-extra.promql new file mode 100644 index 0000000000000..c8babc55ff9aa --- /dev/null +++ b/x-pack/plugin/esql/qa/testFixtures/src/main/resources/promql/grammar/queries-valid-extra.promql @@ -0,0 +1,52 @@ +// +// PromQL queries that the parser should be able to process +// + +// Queries extracted from queries-valid.promql that don't work yet due to missing functionality +// +// aggregations +// +sum without (foo) (some_metric); +sum (some_metric) without (foo); +topk(5, some_metric); +count_values("value", some_metric); +sum without(and, by, avg, count, alert, annotations)(some_metric); + +// +// functions +// +time(); +floor(some_metric{foo!="bar"}); +round(some_metric); +round(some_metric, 5); + +// +// strings +// +"\a\b\f\n\r\t\v\\\" - \xFF\377\u1234\U00010111\U0001011111☺"; +'\a\b\f\n\r\t\v\\\' - \xFF\377\u1234\U00010111\U0001011111☺'; +`\a\b\f\n\r\t\v\\\"\' - \xFF\377\u1234\U00010111\U0001011111☺`; + +// +// subqueries +// +sum without(and, by, avg, count, alert, annotations)(some_metric) [30m:10s]; +some_metric OFFSET 1m [10m:5s]; +some_metric @ 123 offset 1m [10m:5s]; +some_metric offset 1m @ 123 [10m:5s]; +some_metric[10m:5s] offset 1m @ 123; + +// check defined functions don't mask metrics +info(rate(http_request_counter_total{}[5m])); +info(http_request_counter_total{namespace="zzz"}, {foo="bar", bar="baz"}); + +// nested math, added in Prometheus 3.4.0 / May 2025 +// https://github.com/prometheus/prometheus/pull/16249 +foo[-(10s-5s)+20s]; +foo[-10s+15s]; +foo offset (-1^2); +foo[-2^2]; +foo[0+-2^2]; +(sum(foo)); +(sum(foo) by (bar)); +(sum by (bar) (foo)); diff --git a/x-pack/plugin/esql/qa/testFixtures/src/main/resources/promql/grammar/queries-valid.promql b/x-pack/plugin/esql/qa/testFixtures/src/main/resources/promql/grammar/queries-valid.promql new file mode 100644 index 0000000000000..f4855ea686950 --- /dev/null +++ b/x-pack/plugin/esql/qa/testFixtures/src/main/resources/promql/grammar/queries-valid.promql @@ -0,0 +1,251 @@ +// +// PromQL queries that the parser should be able to process +// + +// +// PromQL Documentation examples +// +http_requests_total; +http_requests_total{job="apiserver", handler="/api/comments"}; +http_requests_total{job="apiserver", handler="/api/comments"}[5m]; +http_requests_total{job=~".*server"}; +http_requests_total{status!~"4.."}; +rate(http_requests_total[5m])[30m:1m]; +//max_over_time(deriv(rate(distance_covered_total[5s])[30s:5s])[10m:]); +rate(http_requests_total[5m]); +sum by (job) ( + rate(http_requests_total[5m]) +); +//(instance_memory_limit_bytes - instance_memory_usage_bytes) / 1024 / 1024; +sum by (app, proc) ( + instance_memory_limit_bytes - instance_memory_usage_bytes +) / 1024 / 1024; +//topk(3, sum by (app, proc) (rate(instance_cpu_time_ns[5m]))); +count by (app) (instance_cpu_time_ns); + +// +// Queries inspired by https://github.com/prometheus/prometheus/blob/v3.5.0/promql/parser/parse_test.go +// + +// scalars +1; ++Inf; +-Inf; ++inf; +-inf; +.5; +5.; +123.4567; +5e-3; +5e3; +0xc; +0755; ++5.5e-3; +-0755; +1 + 1; +1 - 1; +1 * 1; +1 % 1; +1 / 1; +1 == bool 1; +1 != bool 1; +1 > bool 1; +1 >= bool 1; +1 < bool 1; +1 <= bool 1; +-1^2; +-1*2; +-1+2; +-1^-2; ++1 + -2 * 1; +1 + 2 / (3 * 1); +1 < bool 2 - 1 * 2; + +// +// metrics +// +-some_metric; ++some_metric; + +some_metric; + +{"some_metric"}; +foo * bar; +foo * sum; +foo == 1; +foo == bool 1; +2.5 / bar; +foo and bar; +foo or bar; +foo unless bar; +foo + bar or bla and blub; +foo and bar unless baz or qux; +bar + on(foo) bla / on(baz, buz) group_right(test) blub; +foo * on(test,blub) bar; +foo * on(test,blub) group_left bar; +foo and on(test,blub) bar; +foo and on() bar; +foo and ignoring(test,blub) bar; +foo and ignoring() bar; +foo unless on(bar) baz; +foo / on(test,blub) group_left(bar) bar; +foo / ignoring(test,blub) group_left(blub) bar; +foo / ignoring(test,blub) group_left(bar) bar; +foo - on(test,blub) group_right(bar,foo) bar; +foo - ignoring(test,blub) group_right(bar,foo) bar; + +// +// evaluation +// +foo; +min; +foo offset 5m; +foo offset -7m; +foo OFFSET 1h30m; +foo OFFSET 1m30ms; +foo @ 1603774568; +foo @ -100; +foo @ .3; +foo @ 3.; +foo @ 3.33; +foo @ 3.3333; +foo @ 3.3335; +foo @ 3e2; +foo @ 3e-1; +foo @ 0xA; +foo @ -3.3e1; + +// +// selector +// +foo:bar{a="bc"}; +{"foo"}; +{'foo\'bar', 'a\\dos\\path'='boo\\urns'}; +{'foo\'bar', `a\dos\path`="boo"}; +{"foo", a="bc"}; +foo{NaN='bc'}; +foo{bar='}'}; +foo{a="b", foo!="bar", test=~"test", bar!~"baz"}; +{a="b", foo!="bar", "foo", test=~"test", bar!~"baz"}; +foo{a="b", foo!="bar", test=~"test", bar!~"baz",}; +{__name__=~"bar", __name__!~"baz"}; +{__name__="bar", __name__="baz"}; +{"bar", __name__="baz"}; +// +// range selector +// +test[1000ms]; +test[1001ms]; +test[1002ms]; +test[5s]; +test[5m]; +foo[5m30s]; +test[5h] OFFSET 5m; +test[5d] OFFSET 10s; +test[5w] offset 2w; +test{a="b"}[5y] OFFSET 3d; +test{a="b"}[5m] OFFSET 3600; +foo[3ms] @ 2.345; +foo[4s180ms] @ 2.345; +foo[4.18] @ 2.345; +foo[4s18ms] @ 2.345; +foo[4.018] @ 2.345; +test{a="b"}[5y] @ 1603774699; +test[5]; +some_metric[5m] @ 1m; + +// +// aggregations +// +sum by (foo)(some_metric); +sum by ("foo bar")({"some.metric"}); +sum by ("foo", bar, 'baz')({"some.metric"}); +avg by (foo)(some_metric); +max by (foo)(some_metric); +// sum without (foo) (some_metric); +// sum (some_metric) without (foo); +stddev(some_metric); +stdvar by (foo)(some_metric); +sum by ()(some_metric); +sum by (foo,bar,)(some_metric); +sum by (foo,)(some_metric); +//topk(5, some_metric); +//count_values("value", some_metric); +//sum without(and, by, avg, count, alert, annotations)(some_metric); + +// +// functions +// +//time(); +//floor(some_metric{foo!="bar"}); +rate(some_metric[5m]); +//round(some_metric); +//round(some_metric, 5); +sum(sum); +a + sum; + +// +// strings +// +"double-quoted string \" with escaped quote"; +'single-quoted string \' with escaped quote'; +`backtick-quoted string`; +//"\a\b\f\n\r\t\v\\\" - \xFF\377\u1234\U00010111\U0001011111☺"; +//'\a\b\f\n\r\t\v\\\' - \xFF\377\u1234\U00010111\U0001011111☺'; +//`\a\b\f\n\r\t\v\\\"\' - \xFF\377\u1234\U00010111\U0001011111☺`; + +// +// subqueries +// +foo{bar="baz"}[10m:6s]; +foo{bar="baz"}[10m5s:1h6ms]; +foo[10m:]; +min_over_time(rate(foo{bar="baz"}[2s])[5m:5s]); +min_over_time(rate(foo{bar="baz"}[2s])[5m:])[4m:3s]; +min_over_time(rate(foo{bar="baz"}[2s])[5m:] offset 4m)[4m:3s]; +min_over_time(rate(foo{bar="baz"}[2s])[5m:] @ 1603775091)[4m:3s]; +min_over_time(rate(foo{bar="baz"}[2s])[5m:] @ -160377509)[4m:3s]; +//sum without(and, by, avg, count, alert, annotations)(some_metric) [30m:10s]; +//some_metric OFFSET 1m [10m:5s]; +some_metric @ 123 [10m:5s]; +//some_metric @ 123 offset 1m [10m:5s]; +some_metric offset 1m @ 123 [10m:5s]; +some_metric[10m:5s] offset 1m @ 123; +(foo + bar{nm="val"})[5m:]; +(foo + bar{nm="val"})[5m:] offset 10m; +(foo + bar{nm="val"} @ 1234)[5m:] @ 1603775019; + +// +// preprocessor +// +foo @ start(); +foo @ end(); +test[5y] @ start(); +test[5y] @ end(); +foo[10m:6s] @ start(); +foo[10m:6s] @ end(); + +// check defined functions don't mask metrics +start; +end; +start{end="foo"}; +end{start="foo"}; +foo unless on(start) bar; +foo unless on(end) bar; +//info(rate(http_request_counter_total{}[5m])); +//info(http_request_counter_total{namespace="zzz"}, {foo="bar", bar="baz"}); + +// nested math, added in Prometheus 3.4.0 / May 2025 +// https://github.com/prometheus/prometheus/pull/16249 +foo[11s+10s-5*2^2]; +//foo[-(10s-5s)+20s]; +//foo[-10s+15s]; +foo[4s+4s:1s*2] offset (5s-8); +foo offset 5s-8; +rate(foo[2m+2m]); +foo offset -1^1; +foo offset -(1^2); +//foo offset (-1^2); +//foo[-2^2]; +//foo[0+-2^2]; +(sum(foo)); +(sum(foo) by (bar)); +(sum by (bar) (foo)); diff --git a/x-pack/plugin/esql/src/main/antlr/EsqlBaseLexer.g4 b/x-pack/plugin/esql/src/main/antlr/EsqlBaseLexer.g4 index 72c9173918012..f0f2dc4e6b576 100644 --- a/x-pack/plugin/esql/src/main/antlr/EsqlBaseLexer.g4 +++ b/x-pack/plugin/esql/src/main/antlr/EsqlBaseLexer.g4 @@ -66,6 +66,7 @@ import ChangePoint, Lookup, MvExpand, Project, + Promql, Rename, Set, Show, diff --git a/x-pack/plugin/esql/src/main/antlr/EsqlBaseLexer.tokens b/x-pack/plugin/esql/src/main/antlr/EsqlBaseLexer.tokens index 2bfe7c40868e7..0caa410c02747 100644 --- a/x-pack/plugin/esql/src/main/antlr/EsqlBaseLexer.tokens +++ b/x-pack/plugin/esql/src/main/antlr/EsqlBaseLexer.tokens @@ -30,125 +30,134 @@ MV_EXPAND=29 DROP=30 KEEP=31 DEV_INSIST=32 -RENAME=33 -SET=34 -SHOW=35 -UNKNOWN_CMD=36 -CHANGE_POINT_LINE_COMMENT=37 -CHANGE_POINT_MULTILINE_COMMENT=38 -CHANGE_POINT_WS=39 -ENRICH_POLICY_NAME=40 -ENRICH_LINE_COMMENT=41 -ENRICH_MULTILINE_COMMENT=42 -ENRICH_WS=43 -ENRICH_FIELD_LINE_COMMENT=44 -ENRICH_FIELD_MULTILINE_COMMENT=45 -ENRICH_FIELD_WS=46 -EXPLAIN_WS=47 -EXPLAIN_LINE_COMMENT=48 -EXPLAIN_MULTILINE_COMMENT=49 -PIPE=50 -QUOTED_STRING=51 -INTEGER_LITERAL=52 -DECIMAL_LITERAL=53 -AND=54 -ASC=55 -ASSIGN=56 -BY=57 -CAST_OP=58 -COLON=59 -SEMICOLON=60 -COMMA=61 -DESC=62 -DOT=63 -FALSE=64 -FIRST=65 -IN=66 -IS=67 -LAST=68 -LIKE=69 -NOT=70 -NULL=71 -NULLS=72 -ON=73 -OR=74 -PARAM=75 -RLIKE=76 -TRUE=77 -WITH=78 -EQ=79 -CIEQ=80 -NEQ=81 -LT=82 -LTE=83 -GT=84 -GTE=85 -PLUS=86 -MINUS=87 -ASTERISK=88 -SLASH=89 -PERCENT=90 -LEFT_BRACES=91 -RIGHT_BRACES=92 -DOUBLE_PARAMS=93 -NAMED_OR_POSITIONAL_PARAM=94 -NAMED_OR_POSITIONAL_DOUBLE_PARAMS=95 -OPENING_BRACKET=96 -CLOSING_BRACKET=97 -LP=98 -RP=99 -UNQUOTED_IDENTIFIER=100 -QUOTED_IDENTIFIER=101 -EXPR_LINE_COMMENT=102 -EXPR_MULTILINE_COMMENT=103 -EXPR_WS=104 -METADATA=105 -UNQUOTED_SOURCE=106 -FROM_LINE_COMMENT=107 -FROM_MULTILINE_COMMENT=108 -FROM_WS=109 -FORK_WS=110 -FORK_LINE_COMMENT=111 -FORK_MULTILINE_COMMENT=112 -GROUP=113 -SCORE=114 -KEY=115 -FUSE_LINE_COMMENT=116 -FUSE_MULTILINE_COMMENT=117 -FUSE_WS=118 -INLINE_STATS=119 -INLINE_LINE_COMMENT=120 -INLINE_MULTILINE_COMMENT=121 -INLINE_WS=122 -JOIN=123 -USING=124 -JOIN_LINE_COMMENT=125 -JOIN_MULTILINE_COMMENT=126 -JOIN_WS=127 -LOOKUP_LINE_COMMENT=128 -LOOKUP_MULTILINE_COMMENT=129 -LOOKUP_WS=130 -LOOKUP_FIELD_LINE_COMMENT=131 -LOOKUP_FIELD_MULTILINE_COMMENT=132 -LOOKUP_FIELD_WS=133 -MVEXPAND_LINE_COMMENT=134 -MVEXPAND_MULTILINE_COMMENT=135 -MVEXPAND_WS=136 -ID_PATTERN=137 -PROJECT_LINE_COMMENT=138 -PROJECT_MULTILINE_COMMENT=139 -PROJECT_WS=140 -AS=141 -RENAME_LINE_COMMENT=142 -RENAME_MULTILINE_COMMENT=143 -RENAME_WS=144 -SET_LINE_COMMENT=145 -SET_MULTILINE_COMMENT=146 -SET_WS=147 -INFO=148 -SHOW_LINE_COMMENT=149 -SHOW_MULTILINE_COMMENT=150 -SHOW_WS=151 +DEV_PROMQL=33 +RENAME=34 +SET=35 +SHOW=36 +UNKNOWN_CMD=37 +CHANGE_POINT_LINE_COMMENT=38 +CHANGE_POINT_MULTILINE_COMMENT=39 +CHANGE_POINT_WS=40 +ENRICH_POLICY_NAME=41 +ENRICH_LINE_COMMENT=42 +ENRICH_MULTILINE_COMMENT=43 +ENRICH_WS=44 +ENRICH_FIELD_LINE_COMMENT=45 +ENRICH_FIELD_MULTILINE_COMMENT=46 +ENRICH_FIELD_WS=47 +EXPLAIN_WS=48 +EXPLAIN_LINE_COMMENT=49 +EXPLAIN_MULTILINE_COMMENT=50 +PIPE=51 +QUOTED_STRING=52 +INTEGER_LITERAL=53 +DECIMAL_LITERAL=54 +AND=55 +ASC=56 +ASSIGN=57 +BY=58 +CAST_OP=59 +COLON=60 +SEMICOLON=61 +COMMA=62 +DESC=63 +DOT=64 +FALSE=65 +FIRST=66 +IN=67 +IS=68 +LAST=69 +LIKE=70 +NOT=71 +NULL=72 +NULLS=73 +ON=74 +OR=75 +PARAM=76 +RLIKE=77 +TRUE=78 +WITH=79 +EQ=80 +CIEQ=81 +NEQ=82 +LT=83 +LTE=84 +GT=85 +GTE=86 +PLUS=87 +MINUS=88 +ASTERISK=89 +SLASH=90 +PERCENT=91 +LEFT_BRACES=92 +RIGHT_BRACES=93 +DOUBLE_PARAMS=94 +NAMED_OR_POSITIONAL_PARAM=95 +NAMED_OR_POSITIONAL_DOUBLE_PARAMS=96 +OPENING_BRACKET=97 +CLOSING_BRACKET=98 +LP=99 +RP=100 +UNQUOTED_IDENTIFIER=101 +QUOTED_IDENTIFIER=102 +EXPR_LINE_COMMENT=103 +EXPR_MULTILINE_COMMENT=104 +EXPR_WS=105 +METADATA=106 +UNQUOTED_SOURCE=107 +FROM_LINE_COMMENT=108 +FROM_MULTILINE_COMMENT=109 +FROM_WS=110 +FORK_WS=111 +FORK_LINE_COMMENT=112 +FORK_MULTILINE_COMMENT=113 +GROUP=114 +SCORE=115 +KEY=116 +FUSE_LINE_COMMENT=117 +FUSE_MULTILINE_COMMENT=118 +FUSE_WS=119 +INLINE_STATS=120 +INLINE_LINE_COMMENT=121 +INLINE_MULTILINE_COMMENT=122 +INLINE_WS=123 +JOIN=124 +USING=125 +JOIN_LINE_COMMENT=126 +JOIN_MULTILINE_COMMENT=127 +JOIN_WS=128 +LOOKUP_LINE_COMMENT=129 +LOOKUP_MULTILINE_COMMENT=130 +LOOKUP_WS=131 +LOOKUP_FIELD_LINE_COMMENT=132 +LOOKUP_FIELD_MULTILINE_COMMENT=133 +LOOKUP_FIELD_WS=134 +MVEXPAND_LINE_COMMENT=135 +MVEXPAND_MULTILINE_COMMENT=136 +MVEXPAND_WS=137 +ID_PATTERN=138 +PROJECT_LINE_COMMENT=139 +PROJECT_MULTILINE_COMMENT=140 +PROJECT_WS=141 +PROMQL_UNQUOTED_IDENTIFIER=142 +PROMQL_PARAMS_LINE_COMMENT=143 +PROMQL_PARAMS_MULTILINE_COMMENT=144 +PROMQL_PARAMS_WS=145 +PROMQL_QUERY_TEXT=146 +PROMQL_QUERY_LINE_COMMENT=147 +PROMQL_QUERY_MULTILINE_COMMENT=148 +PROMQL_QUERY_WS=149 +AS=150 +RENAME_LINE_COMMENT=151 +RENAME_MULTILINE_COMMENT=152 +RENAME_WS=153 +SET_LINE_COMMENT=154 +SET_MULTILINE_COMMENT=155 +SET_WS=156 +INFO=157 +SHOW_LINE_COMMENT=158 +SHOW_MULTILINE_COMMENT=159 +SHOW_WS=160 'change_point'=4 'enrich'=5 'completion'=7 @@ -171,57 +180,57 @@ SHOW_WS=151 'mv_expand'=29 'drop'=30 'keep'=31 -'rename'=33 -'set'=34 -'show'=35 -'|'=50 -'and'=54 -'asc'=55 -'='=56 -'by'=57 -'::'=58 -':'=59 -';'=60 -','=61 -'desc'=62 -'.'=63 -'false'=64 -'first'=65 -'in'=66 -'is'=67 -'last'=68 -'like'=69 -'not'=70 -'null'=71 -'nulls'=72 -'on'=73 -'or'=74 -'?'=75 -'rlike'=76 -'true'=77 -'with'=78 -'=='=79 -'=~'=80 -'!='=81 -'<'=82 -'<='=83 -'>'=84 -'>='=85 -'+'=86 -'-'=87 -'*'=88 -'/'=89 -'%'=90 -'{'=91 -'}'=92 -'??'=93 -']'=97 -')'=99 -'metadata'=105 -'group'=113 -'score'=114 -'key'=115 -'join'=123 -'USING'=124 -'as'=141 -'info'=148 +'rename'=34 +'set'=35 +'show'=36 +'|'=51 +'and'=55 +'asc'=56 +'='=57 +'by'=58 +'::'=59 +':'=60 +';'=61 +','=62 +'desc'=63 +'.'=64 +'false'=65 +'first'=66 +'in'=67 +'is'=68 +'last'=69 +'like'=70 +'not'=71 +'null'=72 +'nulls'=73 +'on'=74 +'or'=75 +'?'=76 +'rlike'=77 +'true'=78 +'with'=79 +'=='=80 +'=~'=81 +'!='=82 +'<'=83 +'<='=84 +'>'=85 +'>='=86 +'+'=87 +'-'=88 +'*'=89 +'/'=90 +'%'=91 +'{'=92 +'}'=93 +'??'=94 +']'=98 +')'=100 +'metadata'=106 +'group'=114 +'score'=115 +'key'=116 +'join'=124 +'USING'=125 +'as'=150 +'info'=157 diff --git a/x-pack/plugin/esql/src/main/antlr/EsqlBaseParser.g4 b/x-pack/plugin/esql/src/main/antlr/EsqlBaseParser.g4 index 28e55632e658a..74947d78bda1e 100644 --- a/x-pack/plugin/esql/src/main/antlr/EsqlBaseParser.g4 +++ b/x-pack/plugin/esql/src/main/antlr/EsqlBaseParser.g4 @@ -21,7 +21,8 @@ options { } import Expression, - Join; + Join, + Promql; statements : setCommand* singleStatement EOF @@ -69,6 +70,7 @@ processingCommand // in development | {this.isDevVersion()}? lookupCommand | {this.isDevVersion()}? insistCommand + | {this.isDevVersion()}? promqlCommand ; whereCommand diff --git a/x-pack/plugin/esql/src/main/antlr/EsqlBaseParser.tokens b/x-pack/plugin/esql/src/main/antlr/EsqlBaseParser.tokens index 2bfe7c40868e7..0caa410c02747 100644 --- a/x-pack/plugin/esql/src/main/antlr/EsqlBaseParser.tokens +++ b/x-pack/plugin/esql/src/main/antlr/EsqlBaseParser.tokens @@ -30,125 +30,134 @@ MV_EXPAND=29 DROP=30 KEEP=31 DEV_INSIST=32 -RENAME=33 -SET=34 -SHOW=35 -UNKNOWN_CMD=36 -CHANGE_POINT_LINE_COMMENT=37 -CHANGE_POINT_MULTILINE_COMMENT=38 -CHANGE_POINT_WS=39 -ENRICH_POLICY_NAME=40 -ENRICH_LINE_COMMENT=41 -ENRICH_MULTILINE_COMMENT=42 -ENRICH_WS=43 -ENRICH_FIELD_LINE_COMMENT=44 -ENRICH_FIELD_MULTILINE_COMMENT=45 -ENRICH_FIELD_WS=46 -EXPLAIN_WS=47 -EXPLAIN_LINE_COMMENT=48 -EXPLAIN_MULTILINE_COMMENT=49 -PIPE=50 -QUOTED_STRING=51 -INTEGER_LITERAL=52 -DECIMAL_LITERAL=53 -AND=54 -ASC=55 -ASSIGN=56 -BY=57 -CAST_OP=58 -COLON=59 -SEMICOLON=60 -COMMA=61 -DESC=62 -DOT=63 -FALSE=64 -FIRST=65 -IN=66 -IS=67 -LAST=68 -LIKE=69 -NOT=70 -NULL=71 -NULLS=72 -ON=73 -OR=74 -PARAM=75 -RLIKE=76 -TRUE=77 -WITH=78 -EQ=79 -CIEQ=80 -NEQ=81 -LT=82 -LTE=83 -GT=84 -GTE=85 -PLUS=86 -MINUS=87 -ASTERISK=88 -SLASH=89 -PERCENT=90 -LEFT_BRACES=91 -RIGHT_BRACES=92 -DOUBLE_PARAMS=93 -NAMED_OR_POSITIONAL_PARAM=94 -NAMED_OR_POSITIONAL_DOUBLE_PARAMS=95 -OPENING_BRACKET=96 -CLOSING_BRACKET=97 -LP=98 -RP=99 -UNQUOTED_IDENTIFIER=100 -QUOTED_IDENTIFIER=101 -EXPR_LINE_COMMENT=102 -EXPR_MULTILINE_COMMENT=103 -EXPR_WS=104 -METADATA=105 -UNQUOTED_SOURCE=106 -FROM_LINE_COMMENT=107 -FROM_MULTILINE_COMMENT=108 -FROM_WS=109 -FORK_WS=110 -FORK_LINE_COMMENT=111 -FORK_MULTILINE_COMMENT=112 -GROUP=113 -SCORE=114 -KEY=115 -FUSE_LINE_COMMENT=116 -FUSE_MULTILINE_COMMENT=117 -FUSE_WS=118 -INLINE_STATS=119 -INLINE_LINE_COMMENT=120 -INLINE_MULTILINE_COMMENT=121 -INLINE_WS=122 -JOIN=123 -USING=124 -JOIN_LINE_COMMENT=125 -JOIN_MULTILINE_COMMENT=126 -JOIN_WS=127 -LOOKUP_LINE_COMMENT=128 -LOOKUP_MULTILINE_COMMENT=129 -LOOKUP_WS=130 -LOOKUP_FIELD_LINE_COMMENT=131 -LOOKUP_FIELD_MULTILINE_COMMENT=132 -LOOKUP_FIELD_WS=133 -MVEXPAND_LINE_COMMENT=134 -MVEXPAND_MULTILINE_COMMENT=135 -MVEXPAND_WS=136 -ID_PATTERN=137 -PROJECT_LINE_COMMENT=138 -PROJECT_MULTILINE_COMMENT=139 -PROJECT_WS=140 -AS=141 -RENAME_LINE_COMMENT=142 -RENAME_MULTILINE_COMMENT=143 -RENAME_WS=144 -SET_LINE_COMMENT=145 -SET_MULTILINE_COMMENT=146 -SET_WS=147 -INFO=148 -SHOW_LINE_COMMENT=149 -SHOW_MULTILINE_COMMENT=150 -SHOW_WS=151 +DEV_PROMQL=33 +RENAME=34 +SET=35 +SHOW=36 +UNKNOWN_CMD=37 +CHANGE_POINT_LINE_COMMENT=38 +CHANGE_POINT_MULTILINE_COMMENT=39 +CHANGE_POINT_WS=40 +ENRICH_POLICY_NAME=41 +ENRICH_LINE_COMMENT=42 +ENRICH_MULTILINE_COMMENT=43 +ENRICH_WS=44 +ENRICH_FIELD_LINE_COMMENT=45 +ENRICH_FIELD_MULTILINE_COMMENT=46 +ENRICH_FIELD_WS=47 +EXPLAIN_WS=48 +EXPLAIN_LINE_COMMENT=49 +EXPLAIN_MULTILINE_COMMENT=50 +PIPE=51 +QUOTED_STRING=52 +INTEGER_LITERAL=53 +DECIMAL_LITERAL=54 +AND=55 +ASC=56 +ASSIGN=57 +BY=58 +CAST_OP=59 +COLON=60 +SEMICOLON=61 +COMMA=62 +DESC=63 +DOT=64 +FALSE=65 +FIRST=66 +IN=67 +IS=68 +LAST=69 +LIKE=70 +NOT=71 +NULL=72 +NULLS=73 +ON=74 +OR=75 +PARAM=76 +RLIKE=77 +TRUE=78 +WITH=79 +EQ=80 +CIEQ=81 +NEQ=82 +LT=83 +LTE=84 +GT=85 +GTE=86 +PLUS=87 +MINUS=88 +ASTERISK=89 +SLASH=90 +PERCENT=91 +LEFT_BRACES=92 +RIGHT_BRACES=93 +DOUBLE_PARAMS=94 +NAMED_OR_POSITIONAL_PARAM=95 +NAMED_OR_POSITIONAL_DOUBLE_PARAMS=96 +OPENING_BRACKET=97 +CLOSING_BRACKET=98 +LP=99 +RP=100 +UNQUOTED_IDENTIFIER=101 +QUOTED_IDENTIFIER=102 +EXPR_LINE_COMMENT=103 +EXPR_MULTILINE_COMMENT=104 +EXPR_WS=105 +METADATA=106 +UNQUOTED_SOURCE=107 +FROM_LINE_COMMENT=108 +FROM_MULTILINE_COMMENT=109 +FROM_WS=110 +FORK_WS=111 +FORK_LINE_COMMENT=112 +FORK_MULTILINE_COMMENT=113 +GROUP=114 +SCORE=115 +KEY=116 +FUSE_LINE_COMMENT=117 +FUSE_MULTILINE_COMMENT=118 +FUSE_WS=119 +INLINE_STATS=120 +INLINE_LINE_COMMENT=121 +INLINE_MULTILINE_COMMENT=122 +INLINE_WS=123 +JOIN=124 +USING=125 +JOIN_LINE_COMMENT=126 +JOIN_MULTILINE_COMMENT=127 +JOIN_WS=128 +LOOKUP_LINE_COMMENT=129 +LOOKUP_MULTILINE_COMMENT=130 +LOOKUP_WS=131 +LOOKUP_FIELD_LINE_COMMENT=132 +LOOKUP_FIELD_MULTILINE_COMMENT=133 +LOOKUP_FIELD_WS=134 +MVEXPAND_LINE_COMMENT=135 +MVEXPAND_MULTILINE_COMMENT=136 +MVEXPAND_WS=137 +ID_PATTERN=138 +PROJECT_LINE_COMMENT=139 +PROJECT_MULTILINE_COMMENT=140 +PROJECT_WS=141 +PROMQL_UNQUOTED_IDENTIFIER=142 +PROMQL_PARAMS_LINE_COMMENT=143 +PROMQL_PARAMS_MULTILINE_COMMENT=144 +PROMQL_PARAMS_WS=145 +PROMQL_QUERY_TEXT=146 +PROMQL_QUERY_LINE_COMMENT=147 +PROMQL_QUERY_MULTILINE_COMMENT=148 +PROMQL_QUERY_WS=149 +AS=150 +RENAME_LINE_COMMENT=151 +RENAME_MULTILINE_COMMENT=152 +RENAME_WS=153 +SET_LINE_COMMENT=154 +SET_MULTILINE_COMMENT=155 +SET_WS=156 +INFO=157 +SHOW_LINE_COMMENT=158 +SHOW_MULTILINE_COMMENT=159 +SHOW_WS=160 'change_point'=4 'enrich'=5 'completion'=7 @@ -171,57 +180,57 @@ SHOW_WS=151 'mv_expand'=29 'drop'=30 'keep'=31 -'rename'=33 -'set'=34 -'show'=35 -'|'=50 -'and'=54 -'asc'=55 -'='=56 -'by'=57 -'::'=58 -':'=59 -';'=60 -','=61 -'desc'=62 -'.'=63 -'false'=64 -'first'=65 -'in'=66 -'is'=67 -'last'=68 -'like'=69 -'not'=70 -'null'=71 -'nulls'=72 -'on'=73 -'or'=74 -'?'=75 -'rlike'=76 -'true'=77 -'with'=78 -'=='=79 -'=~'=80 -'!='=81 -'<'=82 -'<='=83 -'>'=84 -'>='=85 -'+'=86 -'-'=87 -'*'=88 -'/'=89 -'%'=90 -'{'=91 -'}'=92 -'??'=93 -']'=97 -')'=99 -'metadata'=105 -'group'=113 -'score'=114 -'key'=115 -'join'=123 -'USING'=124 -'as'=141 -'info'=148 +'rename'=34 +'set'=35 +'show'=36 +'|'=51 +'and'=55 +'asc'=56 +'='=57 +'by'=58 +'::'=59 +':'=60 +';'=61 +','=62 +'desc'=63 +'.'=64 +'false'=65 +'first'=66 +'in'=67 +'is'=68 +'last'=69 +'like'=70 +'not'=71 +'null'=72 +'nulls'=73 +'on'=74 +'or'=75 +'?'=76 +'rlike'=77 +'true'=78 +'with'=79 +'=='=80 +'=~'=81 +'!='=82 +'<'=83 +'<='=84 +'>'=85 +'>='=86 +'+'=87 +'-'=88 +'*'=89 +'/'=90 +'%'=91 +'{'=92 +'}'=93 +'??'=94 +']'=98 +')'=100 +'metadata'=106 +'group'=114 +'score'=115 +'key'=116 +'join'=124 +'USING'=125 +'as'=150 +'info'=157 diff --git a/x-pack/plugin/esql/src/main/antlr/PromqlBaseLexer.g4 b/x-pack/plugin/esql/src/main/antlr/PromqlBaseLexer.g4 new file mode 100644 index 0000000000000..3342f50af23d0 --- /dev/null +++ b/x-pack/plugin/esql/src/main/antlr/PromqlBaseLexer.g4 @@ -0,0 +1,160 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ +lexer grammar PromqlBaseLexer; + +@header { +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ +} + +options { + superClass=LexerConfig; +} + +// Operators + +// math +PLUS : '+'; +MINUS : '-'; +ASTERISK: '*'; +SLASH : '/'; +PERCENT : '%'; +CARET : '^'; + +// comparison +EQ : '=='; +NEQ: '!='; +GT : '>'; +GTE: '>='; +LT : '<'; +LTE: '<='; + +// Label +LABEL_EQ : '='; +LABEL_RGX : '=~'; +LABEL_RGX_NEQ: '!~'; + +// set +AND : 'and'; +OR : 'or'; +UNLESS: 'unless'; + +// Modifiers + +// aggregration +BY : 'by'; +WITHOUT: 'without'; + +// join +ON : 'on'; +IGNORING : 'ignoring'; +GROUP_LEFT : 'group_left'; +GROUP_RIGHT: 'group_right'; + +// bool +BOOL: 'bool'; + +// evaluation +OFFSET : 'offset' | 'OFFSET'; // the upper-case format seems to be a legacy construct +AT : '@'; +AT_START: 'start()'; +AT_END : 'end()'; + +// brackets +LCB: '{'; +RCB: '}'; +LSB: '['; +RSB: ']'; +LP : '('; +RP : ')'; + +COLON: ':'; +COMMA: ','; + +STRING + : SQ ( '\\' [abfnrtv\\'] | ~'\'' )* SQ + | DQ ( '\\' [abfnrtv\\"] | ~'"' )* DQ + | '`' ( ~'`' )* '`' + ; + +fragment ESC_CHARS + : [abfnrtv\\] + ; + +INTEGER_VALUE + : DIGIT+ + ; + +DECIMAL_VALUE + : DIGIT+ DOT DIGIT* + | DOT DIGIT+ + | DIGIT+ (DOT DIGIT*)? EXPONENT + | DOT DIGIT+ EXPONENT + | [iI][nN][fF] + | [nN][aA][nN] + ; + +HEXADECIMAL + : '0x'[0-9a-fA-F]+ + ; + +// +// Special handling for time values to disambiguate from identifiers +// + +// hack to allow colon as a time unit separator inside subquery duration to avoid the lexer picking it as an identifier +TIME_VALUE_WITH_COLON + : COLON (DIGIT+ [a-zA-Z]+)+ + ; + +// similar to the identifier but without a : +TIME_VALUE + : (DIGIT+ [a-zA-Z]+)+ + ; + +// NB: the parser needs to validates this token based on context +// (metric vs label vs..) as it can include non-supported characters +IDENTIFIER + : [a-zA-Z_:][a-zA-Z0-9_:.]* + ; + +COMMENT + : '#' ~[\r\n]* '\r'? '\n'? -> channel(HIDDEN) + ; + +WS + : [ \r\n\t]+ -> channel(HIDDEN) + ; + +// Catch-all for anything we can't recognize. +UNRECOGNIZED + : . + ; + +fragment SQ + : '\'' + ; + +fragment DQ + : '"' + ; + +fragment EXPONENT + : [Ee] [+-]? DIGIT+ + ; + +fragment DIGIT + : [0-9] + ; + +fragment DOT + : '.' + ; diff --git a/x-pack/plugin/esql/src/main/antlr/PromqlBaseLexer.tokens b/x-pack/plugin/esql/src/main/antlr/PromqlBaseLexer.tokens new file mode 100644 index 0000000000000..e141ecfd35634 --- /dev/null +++ b/x-pack/plugin/esql/src/main/antlr/PromqlBaseLexer.tokens @@ -0,0 +1,83 @@ +PLUS=1 +MINUS=2 +ASTERISK=3 +SLASH=4 +PERCENT=5 +CARET=6 +EQ=7 +NEQ=8 +GT=9 +GTE=10 +LT=11 +LTE=12 +LABEL_EQ=13 +LABEL_RGX=14 +LABEL_RGX_NEQ=15 +AND=16 +OR=17 +UNLESS=18 +BY=19 +WITHOUT=20 +ON=21 +IGNORING=22 +GROUP_LEFT=23 +GROUP_RIGHT=24 +BOOL=25 +OFFSET=26 +AT=27 +AT_START=28 +AT_END=29 +LCB=30 +RCB=31 +LSB=32 +RSB=33 +LP=34 +RP=35 +COLON=36 +COMMA=37 +STRING=38 +INTEGER_VALUE=39 +DECIMAL_VALUE=40 +HEXADECIMAL=41 +TIME_VALUE_WITH_COLON=42 +TIME_VALUE=43 +IDENTIFIER=44 +COMMENT=45 +WS=46 +UNRECOGNIZED=47 +'+'=1 +'-'=2 +'*'=3 +'/'=4 +'%'=5 +'^'=6 +'=='=7 +'!='=8 +'>'=9 +'>='=10 +'<'=11 +'<='=12 +'='=13 +'=~'=14 +'!~'=15 +'and'=16 +'or'=17 +'unless'=18 +'by'=19 +'without'=20 +'on'=21 +'ignoring'=22 +'group_left'=23 +'group_right'=24 +'bool'=25 +'@'=27 +'start()'=28 +'end()'=29 +'{'=30 +'}'=31 +'['=32 +']'=33 +'('=34 +')'=35 +':'=36 +','=37 diff --git a/x-pack/plugin/esql/src/main/antlr/PromqlBaseParser.g4 b/x-pack/plugin/esql/src/main/antlr/PromqlBaseParser.g4 new file mode 100644 index 0000000000000..6c34daccf79ed --- /dev/null +++ b/x-pack/plugin/esql/src/main/antlr/PromqlBaseParser.g4 @@ -0,0 +1,169 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ +parser grammar PromqlBaseParser; + +@header { +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ +} + +options { + superClass=ParserConfig; + tokenVocab=PromqlBaseLexer; +} + +singleStatement + : expression EOF + ; + +// operator precedence defined in Promql at +// https://prometheus.io/docs/prometheus/latest/querying/operators/#binary-operator-precedence + +expression + : left=expression op=CARET modifier? right=expression #arithmeticBinary + | operator=(PLUS | MINUS) expression #arithmeticUnary + | left=expression op=(ASTERISK | PERCENT | SLASH) modifier? right=expression #arithmeticBinary + | left=expression op=(MINUS | PLUS) modifier? right=expression #arithmeticBinary + | left=expression op=(EQ | NEQ | GT | GTE | LT | LTE) BOOL? modifier? right=expression #arithmeticBinary + | left=expression op=(AND | UNLESS) modifier? right=expression #arithmeticBinary + | left=expression op=OR modifier? right=expression #arithmeticBinary + | value #valueExpression + | LP expression RP #parenthesized + | expression LSB range=duration subqueryResolution RSB evaluation? #subquery + ; + +subqueryResolution + : COLON (resolution=duration)? + | TIME_VALUE_WITH_COLON op=CARET expression + | TIME_VALUE_WITH_COLON op=(ASTERISK | SLASH) expression + | TIME_VALUE_WITH_COLON op=(MINUS|PLUS) expression + | TIME_VALUE_WITH_COLON + ; + +value + : function + | selector + | constant + ; + +function + : IDENTIFIER LP functionParams? RP + | IDENTIFIER LP functionParams RP grouping + | IDENTIFIER grouping LP functionParams RP + ; + +functionParams + : expression (COMMA expression)* + ; + +grouping + : (BY | WITHOUT) labelList + ; + +selector + : seriesMatcher (LSB duration RSB)? evaluation? + ; + +seriesMatcher + : identifier (LCB labels? RCB)? + | LCB labels RCB + ; + +modifier + : matching=(IGNORING | ON) modifierLabels=labelList (joining=(GROUP_LEFT | GROUP_RIGHT) groupLabels=labelList?)? + ; + +// NB: PromQL explicitly allows a trailing comma for label enumeration +// both inside aggregation functions and metric labels. +labelList + : LP (labelName COMMA?)* RP + ; + +labels + : label (COMMA label?)* + ; + +label + : labelName (kind=(LABEL_EQ | NEQ | LABEL_RGX | LABEL_RGX_NEQ) STRING)? + ; + +labelName + : identifier + | STRING + | number + ; + +identifier + : IDENTIFIER + | nonReserved + ; + +evaluation + : offset at? + | at offset? + ; + +offset + : OFFSET MINUS? duration + ; + +// do timeunit validation and break-down inside the parser +// this helps deal with ambiguities for multi-unit declarations (1d3m) +// and give better error messages +// support arithmetic for duration with partial support added in Prometheus 3.4 +// https://github.com/prometheus/prometheus/issues/12318 +// https://github.com/prometheus/prometheus/pull/16249 +duration + //: time_value + : expression + ; +at + : AT MINUS? timeValue + | AT (AT_START | AT_END) + ; + +constant + : number + | string + | timeValue + ; + +number + : DECIMAL_VALUE #decimalLiteral + | INTEGER_VALUE #integerLiteral + | HEXADECIMAL #hexLiteral + ; + +string + : STRING + ; + +timeValue + : TIME_VALUE_WITH_COLON + | TIME_VALUE + | number + ; + +// declared tokens that can be used without special escaping +// in PromQL this applies to all keywords +nonReserved + : AND + | BOOL + | BY + | GROUP_LEFT + | GROUP_RIGHT + | IGNORING + | OFFSET + | OR + | ON + | UNLESS + | WITHOUT + ; diff --git a/x-pack/plugin/esql/src/main/antlr/PromqlBaseParser.tokens b/x-pack/plugin/esql/src/main/antlr/PromqlBaseParser.tokens new file mode 100644 index 0000000000000..e141ecfd35634 --- /dev/null +++ b/x-pack/plugin/esql/src/main/antlr/PromqlBaseParser.tokens @@ -0,0 +1,83 @@ +PLUS=1 +MINUS=2 +ASTERISK=3 +SLASH=4 +PERCENT=5 +CARET=6 +EQ=7 +NEQ=8 +GT=9 +GTE=10 +LT=11 +LTE=12 +LABEL_EQ=13 +LABEL_RGX=14 +LABEL_RGX_NEQ=15 +AND=16 +OR=17 +UNLESS=18 +BY=19 +WITHOUT=20 +ON=21 +IGNORING=22 +GROUP_LEFT=23 +GROUP_RIGHT=24 +BOOL=25 +OFFSET=26 +AT=27 +AT_START=28 +AT_END=29 +LCB=30 +RCB=31 +LSB=32 +RSB=33 +LP=34 +RP=35 +COLON=36 +COMMA=37 +STRING=38 +INTEGER_VALUE=39 +DECIMAL_VALUE=40 +HEXADECIMAL=41 +TIME_VALUE_WITH_COLON=42 +TIME_VALUE=43 +IDENTIFIER=44 +COMMENT=45 +WS=46 +UNRECOGNIZED=47 +'+'=1 +'-'=2 +'*'=3 +'/'=4 +'%'=5 +'^'=6 +'=='=7 +'!='=8 +'>'=9 +'>='=10 +'<'=11 +'<='=12 +'='=13 +'=~'=14 +'!~'=15 +'and'=16 +'or'=17 +'unless'=18 +'by'=19 +'without'=20 +'on'=21 +'ignoring'=22 +'group_left'=23 +'group_right'=24 +'bool'=25 +'@'=27 +'start()'=28 +'end()'=29 +'{'=30 +'}'=31 +'['=32 +']'=33 +'('=34 +')'=35 +':'=36 +','=37 diff --git a/x-pack/plugin/esql/src/main/antlr/lexer/Promql.g4 b/x-pack/plugin/esql/src/main/antlr/lexer/Promql.g4 new file mode 100644 index 0000000000000..f460d7f415cae --- /dev/null +++ b/x-pack/plugin/esql/src/main/antlr/lexer/Promql.g4 @@ -0,0 +1,77 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ +lexer grammar Promql; + +// +// PromQL command with optional parameters and query text +// +DEV_PROMQL : {this.isDevVersion()}? 'promql' -> pushMode(PROMQL_PARAMS_MODE); + +mode PROMQL_PARAMS_MODE; + +// Simple unquoted identifier for parameter names and values +PROMQL_UNQUOTED_IDENTIFIER + : [a-z0-9][a-z0-9_]* // Starts with letter/digit, followed by letters/digits/underscores + | [_@][a-z0-9_]+ // OR starts with _/@ followed by at least one alphanumeric/underscore + ; + +// Also support quoted identifiers and named parameters +PROMQL_QUOTED_IDENTIFIER: QUOTED_IDENTIFIER -> type(QUOTED_IDENTIFIER); +PROMQL_NAMED_PARAMS: NAMED_OR_POSITIONAL_PARAM -> type(NAMED_OR_POSITIONAL_PARAM); + +PROMQL_QUOTED_STRING: QUOTED_STRING -> type(QUOTED_STRING); + +// Exit back to default mode on pipe +PROMQL_PARAMS_PIPE : PIPE -> type(PIPE), popMode; + +// Opening paren starts query text capture +PROMQL_LP : LP {this.incPromqlDepth();} -> type(LP), pushMode(PROMQL_QUERY_MODE); + +// Comments and whitespace +PROMQL_PARAMS_LINE_COMMENT : LINE_COMMENT -> channel(HIDDEN); +PROMQL_PARAMS_MULTILINE_COMMENT : MULTILINE_COMMENT -> channel(HIDDEN); +PROMQL_PARAMS_WS : WS -> channel(HIDDEN); + +mode PROMQL_QUERY_MODE; + +// Nested opening parens - increment depth and emit LP token +PROMQL_NESTED_LP + : '(' {this.incPromqlDepth();} -> type(LP) + ; + +// Query text - everything except parens and special characters +PROMQL_QUERY_TEXT + : ( PROMQL_STRING_LITERAL | PROMQL_QUERY_COMMENT | ~[|()"'`#\r\n] )+ // Exclude both ( and ) from text + ; + +// String literals (preserved with quotes as part of text) +fragment PROMQL_STRING_LITERAL + : '"' ( '\\' . | ~[\\"] )* '"' + | '\'' ( '\\' . | ~[\\'] )* '\'' + | '`' ~'`'* '`' + ; + +// PromQL-style comments (#) +fragment PROMQL_QUERY_COMMENT + : '#' ~[\r\n]* '\r'? '\n'? + ; + +PROMQL_NESTED_RP + : ')' {this.isPromqlQuery()}? {this.decPromqlDepth();} -> type(RP) + ; + +PROMQL_QUERY_RP + : ')' {!this.isPromqlQuery()}? {this.resetPromqlDepth();} -> type(RP), popMode, popMode + ; + +// Pipe exits both modes +PROMQL_QUERY_PIPE : PIPE -> type(PIPE), popMode, popMode; + +// ESQL-style comments +PROMQL_QUERY_LINE_COMMENT : LINE_COMMENT -> channel(HIDDEN); +PROMQL_QUERY_MULTILINE_COMMENT : MULTILINE_COMMENT -> channel(HIDDEN); +PROMQL_QUERY_WS : WS -> channel(HIDDEN); diff --git a/x-pack/plugin/esql/src/main/antlr/parser/Promql.g4 b/x-pack/plugin/esql/src/main/antlr/parser/Promql.g4 new file mode 100644 index 0000000000000..ffa9628f2dcf8 --- /dev/null +++ b/x-pack/plugin/esql/src/main/antlr/parser/Promql.g4 @@ -0,0 +1,27 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ +parser grammar Promql; + +promqlCommand + : DEV_PROMQL promqlParam+ LP promqlQueryPart* RP + ; + +promqlParam + : name=promqlParamContent value=promqlParamContent + ; + +promqlParamContent + : PROMQL_UNQUOTED_IDENTIFIER + | QUOTED_IDENTIFIER + | QUOTED_STRING + | NAMED_OR_POSITIONAL_PARAM + ; + +promqlQueryPart + : PROMQL_QUERY_TEXT // Regular text + | LP promqlQueryPart* RP // Nested parens (recursive!) + ; diff --git a/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/action/EsqlCapabilities.java b/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/action/EsqlCapabilities.java index 580876ee05c8d..bd6d90d6d4960 100644 --- a/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/action/EsqlCapabilities.java +++ b/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/action/EsqlCapabilities.java @@ -1684,6 +1684,11 @@ public enum Cap { */ TIME_SERIES_WINDOW_V0, + /** + * PromQL support in ESQL + */ + PROMQL_V0(Build.current().isSnapshot()), + // Last capability should still have a comma for fewer merge conflicts when adding new ones :) // This comment prevents the semicolon from being on the previous capability when Spotless formats the file. ; diff --git a/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/action/PromqlFeatures.java b/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/action/PromqlFeatures.java new file mode 100644 index 0000000000000..048396d46a7d5 --- /dev/null +++ b/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/action/PromqlFeatures.java @@ -0,0 +1,26 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +package org.elasticsearch.xpack.esql.action; + +/** + * Utility class for PromQL-related functionality. + */ +public final class PromqlFeatures { + + private PromqlFeatures() { + // Utility class - no instances + } + + /** + * Returns whether PromQL functionality is enabled. + * Exists to provide a single point of change and minimize noise when upgrading capability versions. + */ + public static boolean isEnabled() { + return EsqlCapabilities.Cap.TS_COMMAND_V0.isEnabled() && EsqlCapabilities.Cap.PROMQL_V0.isEnabled(); + } +} diff --git a/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/analysis/Analyzer.java b/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/analysis/Analyzer.java index db3fe2eba9d77..bb8d87715364e 100644 --- a/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/analysis/Analyzer.java +++ b/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/analysis/Analyzer.java @@ -140,6 +140,7 @@ import org.elasticsearch.xpack.esql.plan.logical.local.EsqlProject; import org.elasticsearch.xpack.esql.plan.logical.local.LocalRelation; import org.elasticsearch.xpack.esql.plan.logical.local.LocalSupplier; +import org.elasticsearch.xpack.esql.plan.logical.promql.PromqlCommand; import org.elasticsearch.xpack.esql.rule.ParameterizedRule; import org.elasticsearch.xpack.esql.rule.ParameterizedRuleExecutor; import org.elasticsearch.xpack.esql.rule.Rule; @@ -517,6 +518,7 @@ protected LogicalPlan rule(LogicalPlan plan, AnalyzerContext context) { case Insist i -> resolveInsist(i, childrenOutput, context); case Fuse fuse -> resolveFuse(fuse, childrenOutput); case Rerank r -> resolveRerank(r, childrenOutput); + case PromqlCommand promql -> resolvePromql(promql, childrenOutput); default -> plan.transformExpressionsOnly(UnresolvedAttribute.class, ua -> maybeResolveAttribute(ua, childrenOutput)); }; } @@ -1105,6 +1107,15 @@ private LogicalPlan resolveFuse(Fuse fuse, List childrenOutput) { return resolveAggregate(new Aggregate(source, scoreEval, new ArrayList<>(keys), aggregates), childrenOutput); } + private LogicalPlan resolvePromql(PromqlCommand promql, List childrenOutput) { + LogicalPlan promqlPlan = promql.promqlPlan(); + Function lambda = ua -> maybeResolveAttribute(ua, childrenOutput); + // resolve the nested plan + return promql.withPromqlPlan(promqlPlan.transformExpressionsDown(UnresolvedAttribute.class, lambda)) + // but also any unresolved expressions + .transformExpressionsOnly(UnresolvedAttribute.class, lambda); + } + private Attribute maybeResolveAttribute(UnresolvedAttribute ua, List childrenOutput) { return maybeResolveAttribute(ua, childrenOutput, log); } diff --git a/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/capabilities/ConfigurationAware.java b/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/capabilities/ConfigurationAware.java new file mode 100644 index 0000000000000..ae4463dd1a626 --- /dev/null +++ b/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/capabilities/ConfigurationAware.java @@ -0,0 +1,42 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +package org.elasticsearch.xpack.esql.capabilities; + +import org.elasticsearch.xpack.esql.core.util.StringUtils; +import org.elasticsearch.xpack.esql.plugin.QueryPragmas; +import org.elasticsearch.xpack.esql.session.Configuration; + +import java.time.ZoneOffset; +import java.util.Locale; +import java.util.Map; + +// See https://github.com/elastic/elasticsearch/issues/138203 +public interface ConfigurationAware { + + // Configuration placeholder used by the Analyzer to replace + Configuration CONFIGURATION_MARKER = new Configuration( + ZoneOffset.UTC, + Locale.ROOT, + StringUtils.EMPTY, + StringUtils.EMPTY, + QueryPragmas.EMPTY, + 0, + 0, + StringUtils.EMPTY, + false, + Map.of(), + 0, + false, + 0, + 0 + ); + + Configuration configuration(); + + T withConfiguration(Configuration configuration); +} diff --git a/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/expression/promql/function/FunctionType.java b/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/expression/promql/function/FunctionType.java new file mode 100644 index 0000000000000..7a25e4eabc5a2 --- /dev/null +++ b/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/expression/promql/function/FunctionType.java @@ -0,0 +1,129 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +package org.elasticsearch.xpack.esql.expression.promql.function; + +/** + * Classifies PromQL functions by their input vector type and aggregation behavior. + * This classification is independent of how the function is transformed to ESQL. + */ +public enum FunctionType { + /** + * Aggregates data within each time series over a time window. + * + * Input: Range vector (multiple samples per series over time range) + * Output: Instant vector (one aggregated value per series) + * Grouping: Implicit by time series (_tsid) + * + * Examples: + * - Rate functions: rate(), irate(), increase(), delta(), idelta() + * - Aggregations: avg_over_time(), sum_over_time(), max_over_time(), min_over_time(), count_over_time() + * - Selection: first_over_time(), last_over_time() + * - Presence: present_over_time(), absent_over_time() + */ + WITHIN_SERIES_AGGREGATION, + + /** + * Aggregates data across multiple time series at a single point in time. + * + * Input: Instant vector (one sample per series at evaluation time) + * Output: Instant vector (aggregated across series) + * Grouping: Explicit by labels (by/without) + * + * Examples: + * - Basic: sum(), avg(), max(), min(), count() + * - Statistical: stddev(), stdvar(), quantile() + * - Top-k: topk(), bottomk() + * - Grouping: group(), count_values() + */ + ACROSS_SERIES_AGGREGATION, + + /** + * Transforms each sample in a vector independently (element-wise operations). + * + * Input: Instant vector + * Output: Instant vector (same cardinality, transformed values) + * + * Examples: + * - Math: abs(), ceil(), floor(), round(), sqrt(), exp(), ln(), log2(), log10() + * - Trigonometric: sin(), cos(), tan(), asin(), acos(), atan(), sinh(), cosh(), tanh() + * - Clamping: clamp(), clamp_max(), clamp_min() + * - Sign: sgn() + */ + VALUE_TRANSFORMATION, + + /** + * Manipulates or queries the label set of time series. + * + * Input: Instant vector + * Output: Instant vector (modified labels or label-based filtering) + * + * Examples: + * - Manipulation: label_replace(), label_join() + * - Querying: absent() + */ + METADATA_MANIPULATION, + + /** + * Extracts or computes time-based values from timestamps. + * + * Input: Instant vector + * Output: Instant vector (timestamp replaced with time component) + * + * Examples: day_of_month(), day_of_week(), hour(), minute(), month(), year(), timestamp() + */ + TIME_EXTRACTION, + + /** + * Operates on histogram data types. + * + * Input: Instant vector (histogram samples) + * Output: Instant vector or scalar + * + * Examples: histogram_quantile(), histogram_avg(), histogram_count(), histogram_sum() + */ + HISTOGRAM, + + /** + * Special functions that don't fit standard patterns. + * + * Examples: + * - vector() - converts scalar to vector + * - scalar() - converts single-element vector to scalar + * - time() - current timestamp as scalar + * - pi() - mathematical constant + */ + SPECIAL; + + /** + * Returns whether this function operates on range vectors. + */ + public boolean isRangeVector() { + return this == WITHIN_SERIES_AGGREGATION; + } + + /** + * Returns whether this function operates on instant vectors. + */ + public boolean isInstantVector() { + return this != WITHIN_SERIES_AGGREGATION; + } + + /** + * Returns whether this function performs aggregation. + */ + public boolean isAggregation() { + return this == WITHIN_SERIES_AGGREGATION || this == ACROSS_SERIES_AGGREGATION; + } + + /** + * Returns whether this function transforms values element-wise. + */ + public boolean isElementWise() { + return this == VALUE_TRANSFORMATION || this == TIME_EXTRACTION || this == METADATA_MANIPULATION; + } +} diff --git a/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/expression/promql/function/PromqlFunctionRegistry.java b/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/expression/promql/function/PromqlFunctionRegistry.java new file mode 100644 index 0000000000000..9d14c5891993e --- /dev/null +++ b/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/expression/promql/function/PromqlFunctionRegistry.java @@ -0,0 +1,374 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +package org.elasticsearch.xpack.esql.expression.promql.function; + +import org.elasticsearch.xpack.esql.core.expression.Expression; +import org.elasticsearch.xpack.esql.core.expression.function.Function; +import org.elasticsearch.xpack.esql.core.tree.Source; +import org.elasticsearch.xpack.esql.expression.function.aggregate.AbsentOverTime; +import org.elasticsearch.xpack.esql.expression.function.aggregate.AggregateFunction; +import org.elasticsearch.xpack.esql.expression.function.aggregate.Avg; +import org.elasticsearch.xpack.esql.expression.function.aggregate.AvgOverTime; +import org.elasticsearch.xpack.esql.expression.function.aggregate.Count; +import org.elasticsearch.xpack.esql.expression.function.aggregate.CountOverTime; +import org.elasticsearch.xpack.esql.expression.function.aggregate.Delta; +import org.elasticsearch.xpack.esql.expression.function.aggregate.FirstOverTime; +import org.elasticsearch.xpack.esql.expression.function.aggregate.Idelta; +import org.elasticsearch.xpack.esql.expression.function.aggregate.Increase; +import org.elasticsearch.xpack.esql.expression.function.aggregate.Irate; +import org.elasticsearch.xpack.esql.expression.function.aggregate.LastOverTime; +import org.elasticsearch.xpack.esql.expression.function.aggregate.Max; +import org.elasticsearch.xpack.esql.expression.function.aggregate.MaxOverTime; +import org.elasticsearch.xpack.esql.expression.function.aggregate.Min; +import org.elasticsearch.xpack.esql.expression.function.aggregate.MinOverTime; +import org.elasticsearch.xpack.esql.expression.function.aggregate.Percentile; +import org.elasticsearch.xpack.esql.expression.function.aggregate.PercentileOverTime; +import org.elasticsearch.xpack.esql.expression.function.aggregate.PresentOverTime; +import org.elasticsearch.xpack.esql.expression.function.aggregate.Rate; +import org.elasticsearch.xpack.esql.expression.function.aggregate.StdDev; +import org.elasticsearch.xpack.esql.expression.function.aggregate.StdDevOverTime; +import org.elasticsearch.xpack.esql.expression.function.aggregate.Sum; +import org.elasticsearch.xpack.esql.expression.function.aggregate.SumOverTime; +import org.elasticsearch.xpack.esql.expression.function.aggregate.TimeSeriesAggregateFunction; +import org.elasticsearch.xpack.esql.expression.function.aggregate.Variance; +import org.elasticsearch.xpack.esql.expression.function.aggregate.VarianceOverTime; +import org.elasticsearch.xpack.esql.parser.ParsingException; + +import java.util.HashMap; +import java.util.List; +import java.util.Locale; +import java.util.Map; +import java.util.Objects; +import java.util.Set; +import java.util.function.BiFunction; + +public class PromqlFunctionRegistry { + public static final PromqlFunctionRegistry INSTANCE = new PromqlFunctionRegistry(); + private final Map promqlFunctions = new HashMap<>(); + + public PromqlFunctionRegistry() { + register(functionDefinitions()); + } + + /** + * Define all PromQL functions with their metadata and ESQL constructors. + * This centralizes function definitions and enables proper validation. + */ + private static FunctionDefinition[][] functionDefinitions() { + return new FunctionDefinition[][] { + // Counter-based range functions (require timestamp for rate calculations) + new FunctionDefinition[] { + withinSeries("delta", Delta::new), + withinSeries("idelta", Idelta::new), + withinSeries("increase", Increase::new), + withinSeries("irate", Irate::new), + withinSeries("rate", Rate::new) }, + // Aggregation range functions + new FunctionDefinition[] { + withinSeriesOverTimeWithWindow("avg_over_time", AvgOverTime::new), + withinSeriesOverTime("count_over_time", CountOverTime::new), + withinSeriesOverTime("max_over_time", MaxOverTime::new), + withinSeriesOverTime("min_over_time", MinOverTime::new), + withinSeriesOverTime("sum_over_time", SumOverTime::new), + withinSeriesOverTime("stddev_over_time", StdDevOverTime::new), + withinSeriesOverTime("stdvar_over_time", VarianceOverTime::new) }, + // Selection range functions (require timestamp) + new FunctionDefinition[] { + withinSeries("first_over_time", FirstOverTime::new), + withinSeries("last_over_time", LastOverTime::new) }, + // Presence range functions + new FunctionDefinition[] { + withinSeriesOverTime("absent_over_time", AbsentOverTime::new), + withinSeriesOverTime("present_over_time", PresentOverTime::new) }, + // Range functions with parameters + new FunctionDefinition[] { withinSeriesOverTime("quantile_over_time", PercentileOverTime::new) }, + // Across-series aggregations (basic - single field parameter) + new FunctionDefinition[] { + acrossSeries("avg", Avg::new), + acrossSeries("count", Count::new), + acrossSeries("max", Max::new), + acrossSeries("min", Min::new), + acrossSeries("sum", Sum::new), + acrossSeries("stddev", StdDev::new), + acrossSeries("stdvar", Variance::new) }, + // Across-series aggregations with parameters + new FunctionDefinition[] { acrossSeriesBinary("quantile", Percentile::new) } }; + } + + /** + * Represents the parameter count constraints for a PromQL function. + */ + public record Arity(int min, int max) { + // Common arity patterns as constants + public static final Arity NONE = new Arity(0, 0); + public static final Arity ONE = new Arity(1, 1); + public static final Arity TWO = new Arity(2, 2); + public static final Arity VARIADIC = new Arity(1, Integer.MAX_VALUE); + + public Arity { + if (min < 0) { + throw new IllegalArgumentException("min must be non-negative"); + } + if (max < min) { + throw new IllegalArgumentException("max must be >= min"); + } + } + + public static Arity fixed(int count) { + return switch (count) { + case 0 -> NONE; + case 1 -> ONE; + case 2 -> TWO; + default -> new Arity(count, count); + }; + } + + public static Arity range(int min, int max) { + return min == max ? fixed(min) : new Arity(min, max); + } + + public static Arity atLeast(int min) { + return min == 1 ? VARIADIC : new Arity(min, Integer.MAX_VALUE); + } + + public static Arity optional(int max) { + return new Arity(0, max); + } + + public boolean validate(int paramCount) { + return paramCount >= min && paramCount <= max; + } + } + + /** + * Function definition record for registration and metadata. + */ + public record FunctionDefinition( + String name, + FunctionType functionType, + Arity arity, + BiFunction, Function> esqlBuilder + ) { + public FunctionDefinition { + Objects.requireNonNull(name, "name cannot be null"); + Objects.requireNonNull(functionType, "functionType cannot be null"); + Objects.requireNonNull(arity, "arity cannot be null"); + Objects.requireNonNull(esqlBuilder, "esqlBuilder cannot be null"); + } + } + + @FunctionalInterface + protected interface WithinSeries { + T build(Source source, Expression field, Expression timestamp); + } + + @FunctionalInterface + protected interface WithinSeriesWindow { + T build(Source source, Expression field, Expression window, Expression timestamp); + } + + @FunctionalInterface + protected interface OverTimeWithinSeries { + T build(Source source, Expression valueField); + } + + @FunctionalInterface + protected interface OverTimeWithinSeriesBinary { + T build(Source source, Expression valueField, Expression param); + } + + @FunctionalInterface + protected interface AcrossSeriesUnary { + T build(Source source, Expression field); + } + + @FunctionalInterface + protected interface AcrossSeriesBinary { + T build(Source source, Expression field, Expression param); + } + + private static FunctionDefinition withinSeriesOverTime(String name, OverTimeWithinSeries builder) { + return new FunctionDefinition( + name, + FunctionType.WITHIN_SERIES_AGGREGATION, + Arity.ONE, + (source, params) -> builder.build(source, params.get(0)) + ); + } + + private static FunctionDefinition withinSeriesOverTime(String name, OverTimeWithinSeriesBinary builder) { + return new FunctionDefinition( + name, + FunctionType.WITHIN_SERIES_AGGREGATION, + Arity.TWO, + (source, params) -> builder.build(source, params.get(0), params.get(1)) + ); + } + + // NB: There's no longer a single argument constructor so accept the dual one while passing on a NO_WINDOW + private static FunctionDefinition withinSeriesOverTimeWithWindow(String name, OverTimeWithinSeriesBinary builder) { + return new FunctionDefinition( + name, + FunctionType.WITHIN_SERIES_AGGREGATION, + Arity.ONE, + (source, params) -> builder.build(source, params.get(0), AggregateFunction.NO_WINDOW) + ); + } + + private static FunctionDefinition withinSeries(String name, WithinSeries builder) { + return new FunctionDefinition(name, FunctionType.WITHIN_SERIES_AGGREGATION, Arity.ONE, (source, params) -> { + Expression valueField = params.get(0); + Expression timestampField = params.get(1); + return builder.build(source, valueField, timestampField); + }); + } + + private static FunctionDefinition withinSeries(String name, WithinSeriesWindow builder) { + return new FunctionDefinition(name, FunctionType.WITHIN_SERIES_AGGREGATION, Arity.ONE, (source, params) -> { + Expression valueField = params.get(0); + Expression timestampField = params.get(1); + return builder.build(source, valueField, AggregateFunction.NO_WINDOW, timestampField); + }); + } + + private static FunctionDefinition acrossSeries(String name, AcrossSeriesUnary builder) { + return new FunctionDefinition( + name, + FunctionType.ACROSS_SERIES_AGGREGATION, + Arity.ONE, + (source, params) -> builder.build(source, params.get(0)) + ); + } + + private static FunctionDefinition acrossSeriesBinary(String name, AcrossSeriesBinary builder) { + return new FunctionDefinition(name, FunctionType.ACROSS_SERIES_AGGREGATION, Arity.TWO, (source, params) -> { + Expression param = params.get(0); // First param (k, quantile, etc.) + Expression field = params.get(1); // Second param (the vector field) + return builder.build(source, field, param); + }); + } + + private void register(FunctionDefinition[][] definitionGroups) { + for (FunctionDefinition[] group : definitionGroups) { + for (FunctionDefinition def : group) { + String normalized = normalize(def.name()); + promqlFunctions.put(normalized, def); + } + } + } + + // PromQL function names not yet implemented + private static final Set NOT_IMPLEMENTED = Set.of( + // Across-series aggregations (not yet available in ESQL) + "bottomk", + "topk", + "group", + "count_values", + + // Range vector functions (not yet implemented) + "changes", + "deriv", + "holt_winters", + "mad_over_time", + "predict_linear", + "resets", + + // Instant vector functions + "abs", + "absent", + "ceil", + "clamp", + "clamp_max", + "clamp_min", + "exp", + "floor", + "ln", + "log2", + "log10", + "round", + "scalar", + "sgn", + "sort", + "sort_desc", + "sqrt", + + // Trigonometric functions + "acos", + "acosh", + "asin", + "asinh", + "atan", + "atanh", + "cos", + "cosh", + "deg", + "rad", + "sin", + "sinh", + "tan", + "tanh", + + // Time functions + "day_of_month", + "day_of_week", + "day_of_year", + "days_in_month", + "hour", + "minute", + "month", + "timestamp", + "year", + + // Label manipulation functions + "label_join", + "label_replace", + + // Special functions + "histogram_avg", + "histogram_count", + "histogram_fraction", + "histogram_quantile", + "histogram_stddev", + "histogram_stdvar", + "histogram_sum", + "pi", + "time", + "vector" + ); + + private String normalize(String name) { + return name.toLowerCase(Locale.ROOT); + } + + public Boolean functionExists(String name) { + String normalized = normalize(name); + if (promqlFunctions.containsKey(normalized)) { + return true; + } + if (NOT_IMPLEMENTED.contains(normalized)) { + return null; + } + return false; + } + + public FunctionDefinition functionMetadata(String name) { + String normalized = normalize(name); + FunctionDefinition metadata = promqlFunctions.get(normalized); + return metadata; + } + + public Function buildEsqlFunction(String name, Source source, List params) { + FunctionDefinition metadata = functionMetadata(name); + + try { + return metadata.esqlBuilder().apply(source, params); + } catch (Exception e) { + throw new ParsingException(source, "Error building ESQL function for [{}]: {}", name, e.getMessage()); + } + } +} diff --git a/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/expression/promql/subquery/Subquery.java b/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/expression/promql/subquery/Subquery.java new file mode 100644 index 0000000000000..06a0ad3fc7dce --- /dev/null +++ b/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/expression/promql/subquery/Subquery.java @@ -0,0 +1,90 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +package org.elasticsearch.xpack.esql.expression.promql.subquery; + +import org.elasticsearch.common.io.stream.StreamOutput; +import org.elasticsearch.xpack.esql.EsqlIllegalArgumentException; +import org.elasticsearch.xpack.esql.core.expression.Literal; +import org.elasticsearch.xpack.esql.core.tree.NodeInfo; +import org.elasticsearch.xpack.esql.core.tree.Source; +import org.elasticsearch.xpack.esql.plan.logical.LogicalPlan; +import org.elasticsearch.xpack.esql.plan.logical.UnaryPlan; +import org.elasticsearch.xpack.esql.plan.logical.promql.selector.Evaluation; + +import java.io.IOException; +import java.util.Objects; + +public class Subquery extends UnaryPlan { + private final Literal range; + private final Literal resolution; + private final Evaluation evaluation; + + public Subquery(Source source, LogicalPlan child, Literal range, Literal resolution, Evaluation evaluation) { + super(source, child); + this.range = range; + this.resolution = resolution; + this.evaluation = evaluation; + } + + public Literal range() { + return range; + } + + public Literal resolution() { + return resolution; + } + + public Evaluation evaluation() { + return evaluation; + } + + @Override + public boolean expressionsResolved() { + return true; + } + + @Override + protected NodeInfo info() { + return NodeInfo.create(this, Subquery::new, child(), range, resolution, evaluation); + } + + @Override + public Subquery replaceChild(LogicalPlan newChild) { + return new Subquery(source(), newChild, range, resolution, evaluation); + } + + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } + Subquery subquery = (Subquery) o; + return Objects.equals(range, subquery.range) + && Objects.equals(resolution, subquery.resolution) + && Objects.equals(evaluation, subquery.evaluation) + && Objects.equals(child(), subquery.child()); + } + + @Override + public int hashCode() { + return Objects.hash(super.hashCode(), child(), range, resolution, evaluation); + } + + @Override + public String getWriteableName() { + throw new EsqlIllegalArgumentException("should not be serialized"); + } + + @Override + public void writeTo(StreamOutput out) throws IOException { + throw new EsqlIllegalArgumentException("should not be serialized"); + } +} diff --git a/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/optimizer/LogicalPlanOptimizer.java b/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/optimizer/LogicalPlanOptimizer.java index 020694210e327..c02f58b234dd8 100644 --- a/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/optimizer/LogicalPlanOptimizer.java +++ b/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/optimizer/LogicalPlanOptimizer.java @@ -8,6 +8,7 @@ package org.elasticsearch.xpack.esql.optimizer; import org.elasticsearch.xpack.esql.VerificationException; +import org.elasticsearch.xpack.esql.action.PromqlFeatures; import org.elasticsearch.xpack.esql.common.Failures; import org.elasticsearch.xpack.esql.core.type.DataType; import org.elasticsearch.xpack.esql.optimizer.rules.PruneInlineJoinOnEmptyRightSide; @@ -73,7 +74,9 @@ import org.elasticsearch.xpack.esql.optimizer.rules.logical.SubstituteSurrogatePlans; import org.elasticsearch.xpack.esql.optimizer.rules.logical.TranslateTimeSeriesAggregate; import org.elasticsearch.xpack.esql.optimizer.rules.logical.local.PruneLeftJoinOnNullMatchingField; +import org.elasticsearch.xpack.esql.optimizer.rules.logical.promql.TranslatePromqlToTimeSeriesAggregate; import org.elasticsearch.xpack.esql.plan.logical.LogicalPlan; +import org.elasticsearch.xpack.esql.plan.logical.promql.PromqlCommand; import org.elasticsearch.xpack.esql.rule.ParameterizedRuleExecutor; import org.elasticsearch.xpack.esql.rule.RuleExecutor; @@ -122,7 +125,11 @@ public LogicalPlan optimize(LogicalPlan verified) { Failures failures = verifier.verify(optimized, verified.output()); if (failures.hasFailures()) { - throw new VerificationException(failures); + // TODO re-enable verification for PromQL once we make sure the output columns don't change + // Throw exception unless we have PromQL with the feature enabled + if (PromqlFeatures.isEnabled() == false || verified.anyMatch(PromqlCommand.class::isInstance) == false) { + throw new VerificationException(failures); + } } optimized.setOptimized(); return optimized; @@ -149,6 +156,8 @@ protected static Batch substitutions() { new ReplaceAggregateAggExpressionWithEval(), // lastly replace surrogate functions new SubstituteSurrogateAggregations(), + // translate PromQL plans to time-series aggregates before TranslateTimeSeriesAggregate + new TranslatePromqlToTimeSeriesAggregate(), // translate metric aggregates after surrogate substitution and replace nested expressions with eval (again) new TranslateTimeSeriesAggregate(), new PruneUnusedIndexMode(), diff --git a/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/optimizer/rules/logical/promql/AutomatonUtils.java b/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/optimizer/rules/logical/promql/AutomatonUtils.java new file mode 100644 index 0000000000000..1638e5f04fe67 --- /dev/null +++ b/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/optimizer/rules/logical/promql/AutomatonUtils.java @@ -0,0 +1,273 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +package org.elasticsearch.xpack.esql.optimizer.rules.logical.promql; + +import org.apache.lucene.util.IntsRef; +import org.apache.lucene.util.UnicodeUtil; +import org.apache.lucene.util.automaton.Automaton; +import org.apache.lucene.util.automaton.Operations; + +import java.util.ArrayList; +import java.util.List; + +/** + * Utility class for analyzing Lucene Automaton patterns to extract optimization opportunities. + * + * This class provides methods to detect common patterns in regex automatons that can be + * optimized into simpler query predicates like equality, prefix matching, or IN clauses. + */ +public final class AutomatonUtils { + + /** + * Maximum number of values to extract for IN clause optimization. + * Beyond this threshold, fall back to regex matching. + */ + private static final int MAX_IN_VALUES = 256; + + /** + * Maximum pattern length for string analysis. + * Very long patterns are kept as-is to avoid excessive processing. + */ + private static final int MAX_PATTERN_LENGTH = 1000; + + private AutomatonUtils() { + // Utility class + } + + /** + * Checks if the automaton matches all possible strings. + * + * @param automaton the automaton to check + * @return true if it matches everything + */ + public static boolean matchesAll(Automaton automaton) { + return Operations.isTotal(automaton); + } + + /** + * Checks if the automaton matches no strings. + * + * @param automaton the automaton to check + * @return true if it matches nothing + */ + public static boolean matchesNone(Automaton automaton) { + return Operations.isEmpty(automaton); + } + + /** + * Checks if the automaton matches the empty string. + * + * @param automaton the automaton to check + * @return true if it matches the empty string + */ + public static boolean matchesEmpty(Automaton automaton) { + return Operations.run(automaton, ""); + } + + /** + * Extracts an exact match if the automaton matches only a single string. + * + * @param automaton the automaton to analyze + * @return the single matched string, or null if it matches zero or multiple strings + */ + public static String matchesExact(Automaton automaton) { + if (automaton.getNumStates() == 0) { + return null; // Empty automaton + } + IntsRef singleton = Operations.getSingleton(automaton); + if (singleton == null) { + return null; + } + return UnicodeUtil.newString(singleton.ints, singleton.offset, singleton.length); + } + + /** + * Checks if a string is a literal (no regex metacharacters). + * + * @param s the string to check + * @return true if the string contains no regex metacharacters + */ + private static boolean isLiteral(String s) { + if (s == null || s.isEmpty()) { + return true; + } + + for (int i = 0; i < s.length(); i++) { + char c = s.charAt(i); + switch (c) { + case '.': + case '*': + case '+': + case '?': + case '[': + case ']': + case '{': + case '}': + case '(': + case ')': + case '|': + case '^': + case '$': + case '\\': + return false; + } + } + return true; + } + + private static String removeStartingAnchor(String normalized) { + return normalized.startsWith("^") ? normalized.substring(1) : normalized; + } + + private static String removeEndingAnchor(String normalized) { + return normalized.endsWith("$") ? normalized.substring(0, normalized.length() - 1) : normalized; + } + + /** + * Represents a pattern fragment that can be optimized. + */ + public static class PatternFragment { + public enum Type { + EXACT, // Exact literal match + PREFIX, // Starts with literal + PROPER_PREFIX, // Starts with literal but not the literal itself + SUFFIX, // Ends with literal + PROPER_SUFFIX, // Ends with literal but not the literal itself + REGEX // Complex regex pattern + } + + private final Type type; + private final String value; + + public PatternFragment(Type type, String value) { + this.type = type; + this.value = value; + } + + public Type type() { + return type; + } + + public String value() { + return value; + } + } + + /** + * Analyzes a single alternation part and classifies it into a pattern fragment. + * + * @param part the alternation part to analyze + * @return PatternFragment with appropriate type (EXACT, PREFIX, SUFFIX, or REGEX) + */ + private static PatternFragment classifyPart(String part) { + String trimmed = removeStartingAnchor(removeEndingAnchor(part.trim())); + + // Empty pattern + if (trimmed.isEmpty()) { + return new PatternFragment(PatternFragment.Type.EXACT, ""); + } + + // Check for contains pattern: .*substring.* + boolean startsWithWildcard = trimmed.startsWith(".*") || trimmed.startsWith(".+"); + boolean endsWithWildcard = trimmed.endsWith(".*") || trimmed.endsWith(".+"); + + if (startsWithWildcard && endsWithWildcard) { + // Contains pattern - fallback to REGEX + return new PatternFragment(PatternFragment.Type.REGEX, part.trim()); + } + + if (startsWithWildcard) { + // Suffix pattern: .*suffix + String suffix = trimmed.substring(2); + if (isLiteral(suffix)) { + return new PatternFragment( + trimmed.startsWith(".*") ? PatternFragment.Type.SUFFIX : PatternFragment.Type.PROPER_SUFFIX, + suffix + ); + } + // Complex suffix pattern - fallback to REGEX + return new PatternFragment(PatternFragment.Type.REGEX, part.trim()); + } + + if (endsWithWildcard) { + // Prefix pattern: prefix.* + String prefix = trimmed.substring(0, trimmed.length() - 2); + if (isLiteral(prefix)) { + return new PatternFragment( + trimmed.endsWith(".*") ? PatternFragment.Type.PREFIX : PatternFragment.Type.PROPER_PREFIX, + prefix + ); + } + // Complex prefix pattern - fallback to REGEX + return new PatternFragment(PatternFragment.Type.REGEX, part.trim()); + } + + // Exact literal match + if (isLiteral(trimmed)) { + return new PatternFragment(PatternFragment.Type.EXACT, trimmed); + } + + // Complex pattern - fallback to REGEX + return new PatternFragment(PatternFragment.Type.REGEX, part.trim()); + } + + /** + * Extracts potentially mixed disjoint pattern within the given regex. + * Handles disjunctions if specified with | operator. + * + * This handles mixed patterns like: + * - prod-.*|staging|.*-dev|.*test.* - mix of prefix, exact, suffix, contains + * - http://.*|https://.*|ftp - mix of prefixes and exact + * - *.txt|*.csv|readme - mix of suffixes and exact + * + * Each part is classified and can be optimized independently, then combined with OR. + * + * @param pattern the regex pattern string + * @return list of pattern fragments, or null if any part cannot be optimized + */ + public static List extractFragments(String pattern) { + if (pattern == null || pattern.length() > MAX_PATTERN_LENGTH) { + return null; + } + + String normalized = pattern; + + // Remove anchors + normalized = removeStartingAnchor(normalized); + normalized = removeEndingAnchor(normalized); + + // Check for alternation pattern + + // Avoid nested groups + if (normalized.contains("(") || normalized.contains(")")) { + return null; + } + + // Split by | (watch for escaped pipes) + // this string is NOT a regex pattern and thus looks for \| + if (normalized.contains("\\|")) { + return null; // Contains escaped pipe, too complex + } + + // same string IS a regex pattern and thus search for | + // which gets optimized internally by the JVM + String[] parts = normalized.split("\\|"); + if (parts.length > MAX_IN_VALUES) { + return null; // too many parts + } + + // Classify each part + List fragments = new ArrayList<>(parts.length); + for (String part : parts) { + PatternFragment fragment = classifyPart(part); + fragments.add(fragment); + } + + return fragments; + } +} diff --git a/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/optimizer/rules/logical/promql/TranslatePromqlToTimeSeriesAggregate.java b/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/optimizer/rules/logical/promql/TranslatePromqlToTimeSeriesAggregate.java new file mode 100644 index 0000000000000..fb5d5049dd052 --- /dev/null +++ b/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/optimizer/rules/logical/promql/TranslatePromqlToTimeSeriesAggregate.java @@ -0,0 +1,379 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +package org.elasticsearch.xpack.esql.optimizer.rules.logical.promql; + +import org.elasticsearch.xpack.esql.EsqlIllegalArgumentException; +import org.elasticsearch.xpack.esql.action.PromqlFeatures; +import org.elasticsearch.xpack.esql.capabilities.ConfigurationAware; +import org.elasticsearch.xpack.esql.core.QlIllegalArgumentException; +import org.elasticsearch.xpack.esql.core.expression.Alias; +import org.elasticsearch.xpack.esql.core.expression.Expression; +import org.elasticsearch.xpack.esql.core.expression.Literal; +import org.elasticsearch.xpack.esql.core.expression.NamedExpression; +import org.elasticsearch.xpack.esql.core.expression.function.Function; +import org.elasticsearch.xpack.esql.core.expression.predicate.regex.RLikePattern; +import org.elasticsearch.xpack.esql.core.tree.Source; +import org.elasticsearch.xpack.esql.expression.Order; +import org.elasticsearch.xpack.esql.expression.function.grouping.Bucket; +import org.elasticsearch.xpack.esql.expression.function.scalar.string.EndsWith; +import org.elasticsearch.xpack.esql.expression.function.scalar.string.StartsWith; +import org.elasticsearch.xpack.esql.expression.function.scalar.string.regex.RLike; +import org.elasticsearch.xpack.esql.expression.predicate.Predicates; +import org.elasticsearch.xpack.esql.expression.predicate.logical.And; +import org.elasticsearch.xpack.esql.expression.predicate.nulls.IsNotNull; +import org.elasticsearch.xpack.esql.expression.predicate.operator.comparison.Equals; +import org.elasticsearch.xpack.esql.expression.predicate.operator.comparison.In; +import org.elasticsearch.xpack.esql.expression.predicate.operator.comparison.NotEquals; +import org.elasticsearch.xpack.esql.expression.promql.function.PromqlFunctionRegistry; +import org.elasticsearch.xpack.esql.optimizer.rules.logical.OptimizerRules; +import org.elasticsearch.xpack.esql.optimizer.rules.logical.TranslateTimeSeriesAggregate; +import org.elasticsearch.xpack.esql.plan.logical.Eval; +import org.elasticsearch.xpack.esql.plan.logical.Filter; +import org.elasticsearch.xpack.esql.plan.logical.LogicalPlan; +import org.elasticsearch.xpack.esql.plan.logical.OrderBy; +import org.elasticsearch.xpack.esql.plan.logical.TimeSeriesAggregate; +import org.elasticsearch.xpack.esql.plan.logical.promql.AcrossSeriesAggregate; +import org.elasticsearch.xpack.esql.plan.logical.promql.PlaceholderRelation; +import org.elasticsearch.xpack.esql.plan.logical.promql.PromqlCommand; +import org.elasticsearch.xpack.esql.plan.logical.promql.PromqlFunctionCall; +import org.elasticsearch.xpack.esql.plan.logical.promql.WithinSeriesAggregate; +import org.elasticsearch.xpack.esql.plan.logical.promql.selector.LabelMatcher; +import org.elasticsearch.xpack.esql.plan.logical.promql.selector.LabelMatchers; +import org.elasticsearch.xpack.esql.plan.logical.promql.selector.Selector; + +import java.time.Duration; +import java.util.ArrayList; +import java.util.Comparator; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import static java.util.Arrays.asList; + +/** + * Translates PromQL logical plans into ESQL TimeSeriesAggregate nodes. + * + * This rule runs before {@link TranslateTimeSeriesAggregate} to convert PromQL-specific + * plans (WithinSeriesAggregate, AcrossSeriesAggregate) into standard ESQL TimeSeriesAggregate + * nodes that can then be further optimized by the existing time-series translation pipeline. + * + * Translation examples: + *
+ * PromQL: rate(http_requests[5m])
+ *
+ * PromQL Plan:
+ *   WithinSeriesAggregate(name="rate")
+ *     └── RangeSelector(http_requests, range=5m)
+ *
+ * Translated to:
+ *   TimeSeriesAggregate(groupBy=[_tsid], aggs=[rate(value, @timestamp)])
+ *     └── Filter(__name__ == "http_requests")
+ *           └── EsRelation(*, mode=TIME_SERIES)
+ * 
+ */ +public final class TranslatePromqlToTimeSeriesAggregate extends OptimizerRules.OptimizerRule { + + public static final Duration DEFAULT_LOOKBACK = Duration.ofMinutes(5); + + public TranslatePromqlToTimeSeriesAggregate() { + super(OptimizerRules.TransformDirection.UP); + } + + @Override + protected LogicalPlan rule(PromqlCommand promqlCommand) { + // Safety check: this should never occur as the parser should reject PromQL when disabled, + // but we check here as an additional safety measure + if (PromqlFeatures.isEnabled() == false) { + throw new EsqlIllegalArgumentException( + "PromQL translation attempted but feature is disabled. This should have been caught by the parser." + ); + } + + // Extract the promqlPlan from the container + LogicalPlan promqlPlan = promqlCommand.promqlPlan(); + + // first replace the Placeholder relation with the child plan + promqlPlan = promqlPlan.transformUp(PlaceholderRelation.class, pr -> promqlCommand.child()); + + // Translate based on plan type + return translate(promqlCommand, promqlPlan); + } + + private LogicalPlan translate(PromqlCommand promqlCommand, LogicalPlan promqlPlan) { + // convert the plan bottom-up + MapResult result = map(promqlCommand, promqlPlan); + return result.plan(); + } + + private record MapResult(LogicalPlan plan, Map extras) {} + + // Will pattern match on PromQL plan types: + // - AcrossSeriesAggregate -> Aggregate over TimeSeriesAggregate + // - WithinSeriesAggregate -> TimeSeriesAggregate + // - Selector -> EsRelation + Filter + private static MapResult map(PromqlCommand promqlCommand, LogicalPlan p) { + if (p instanceof Selector selector) { + return map(promqlCommand, selector); + } + if (p instanceof PromqlFunctionCall functionCall) { + return map(promqlCommand, functionCall); + } + throw new QlIllegalArgumentException("Unsupported PromQL plan node: {}", p); + } + + private static MapResult map(PromqlCommand promqlCommand, Selector selector) { + // Create a placeholder relation to be replaced later + var matchers = selector.labelMatchers(); + Expression matcherCondition = translateLabelMatchers(selector.source(), selector.labels(), matchers); + + List selectorConditions = new ArrayList<>(); + // name into is not null + selectorConditions.add(new IsNotNull(selector.source(), selector.series())); + // convert the matchers into a filter expression + if (matcherCondition != null) { + selectorConditions.add(matcherCondition); + } + + Map extras = new HashMap<>(); + extras.put("field", selector.series()); + + // return the condition as filter + LogicalPlan p = new Filter(selector.source(), selector.child(), Predicates.combineAnd(selectorConditions)); + + return new MapResult(p, extras); + } + + private static MapResult map(PromqlCommand promqlCommand, PromqlFunctionCall functionCall) { + MapResult childResult = map(promqlCommand, functionCall.child()); + Map extras = childResult.extras; + + MapResult result; + Expression target = extras.get("field"); // nested expression + + if (functionCall instanceof WithinSeriesAggregate withinAggregate) { + // expects selector + Function esqlFunction = PromqlFunctionRegistry.INSTANCE.buildEsqlFunction( + withinAggregate.functionName(), + withinAggregate.source(), + List.of(target, promqlCommand.timestamp()) + ); + + extras.put("field", esqlFunction); + result = new MapResult(childResult.plan, extras); + } else if (functionCall instanceof AcrossSeriesAggregate acrossAggregate) { + // expects + Function esqlFunction = PromqlFunctionRegistry.INSTANCE.buildEsqlFunction( + acrossAggregate.functionName(), + acrossAggregate.source(), + List.of(target) + ); + + List aggs = new ArrayList<>(); + aggs.add(new Alias(acrossAggregate.source(), acrossAggregate.sourceText(), esqlFunction)); + + List groupings = new ArrayList<>(acrossAggregate.groupings().size()); + + // add groupings + for (Expression grouping : acrossAggregate.groupings()) { + NamedExpression named; + if (grouping instanceof NamedExpression ne) { + named = ne; + } else { + named = new Alias(grouping.source(), grouping.sourceText(), grouping); + } + aggs.add(named); + groupings.add(named.toAttribute()); + } + + Expression timeBucketSize; + if (promqlCommand.isRangeQuery()) { + timeBucketSize = promqlCommand.step(); + } else { + // use default lookback for instant queries + timeBucketSize = Literal.timeDuration(promqlCommand.source(), DEFAULT_LOOKBACK); + } + Bucket b = new Bucket( + promqlCommand.source(), + promqlCommand.timestamp(), + timeBucketSize, + null, + null, + ConfigurationAware.CONFIGURATION_MARKER + ); + String bucketName = "TBUCKET"; + Alias tbucket = new Alias(b.source(), bucketName, b); + aggs.add(tbucket.toAttribute()); + groupings.add(tbucket.toAttribute()); + + LogicalPlan p = childResult.plan; + p = new Eval(tbucket.source(), p, List.of(tbucket)); + p = new TimeSeriesAggregate(acrossAggregate.source(), p, groupings, aggs, null); + // sort the data ascending by time bucket + p = new OrderBy( + acrossAggregate.source(), + p, + asList(new Order(acrossAggregate.source(), tbucket.toAttribute(), Order.OrderDirection.ASC, Order.NullsPosition.FIRST)) + ); + result = new MapResult(p, extras); + } else { + throw new QlIllegalArgumentException("Unsupported PromQL function call: {}", functionCall); + } + + return result; + } + + /** + * Translates PromQL label matchers into ESQL filter expressions. + * + * Uses AutomatonUtils to detect optimizable patterns: + * - Exact match → field == "value" + * - Prefix pattern (prefix.*) → field STARTS_WITH "prefix" + * - Suffix pattern (.*suffix) → field ENDS_WITH "suffix" + * - Simple alternation (a|b|c) → field IN ("a", "b", "c") + * - Disjoint prefixes → field STARTS_WITH "p1" OR field STARTS_WITH "p2" + * - Disjoint suffixes → field ENDS_WITH "s1" OR field ENDS_WITH "s2" + * - Complex patterns → field RLIKE "pattern" + * + * @param source the source location for error reporting + * @param labelMatchers the PromQL label matchers to translate + * @return an ESQL Expression combining all label matcher conditions with AND + */ + static Expression translateLabelMatchers(Source source, List fields, LabelMatchers labelMatchers) { + List conditions = new ArrayList<>(); + boolean hasNameMatcher = false; + var matchers = labelMatchers.matchers(); + for (int i = 0, s = matchers.size(); i < s; i++) { + LabelMatcher matcher = matchers.get(i); + // special handling for name label + if (LabelMatcher.NAME.equals(matcher.name())) { + hasNameMatcher = true; + } else { + Expression field = fields.get(hasNameMatcher ? i - 1 : i); // adjust index if name matcher was seen + Expression condition = translateLabelMatcher(source, field, matcher); + if (condition != null) { + conditions.add(condition); + } + } + } + + // could happen in case of an optimization that removes all matchers + if (conditions.isEmpty()) { + return null; + } + + return Predicates.combineAnd(conditions); + } + + /** + * Translates a single PromQL label matcher into an ESQL filter expression. + * + * @param source the source location + * @param matcher the label matcher to translate + * @return the ESQL Expression, or null if the matcher matches all or none + */ + private static Expression translateLabelMatcher(Source source, Expression field, LabelMatcher matcher) { + // Check for universal matchers + if (matcher.matchesAll()) { + return Literal.fromBoolean(source, true); // No filter needed (matches everything) + } + + if (matcher.matchesNone()) { + // This is effectively FALSE - could use a constant false expression + return Literal.fromBoolean(source, false); + } + + // Try to extract exact match + String exactMatch = AutomatonUtils.matchesExact(matcher.automaton()); + if (exactMatch != null) { + return new Equals(source, field, Literal.keyword(source, exactMatch)); + } + + // Try to extract disjoint patterns (handles mixed prefix/suffix/exact) + List fragments = AutomatonUtils.extractFragments(matcher.value()); + if (fragments != null && fragments.isEmpty() == false) { + return translateDisjointPatterns(source, field, fragments); + } + + // Fallback to RLIKE with the full automaton pattern + // Note: We need to ensure the pattern is properly anchored for PromQL semantics + return new RLike(source, field, new RLikePattern(matcher.toString())); + } + + /** + * Translates disjoint pattern fragments into optimized ESQL expressions. + * + * Homogeneous patterns (all same type): + * - All EXACT → field IN ("a", "b", "c") + * - All PREFIX → field STARTS_WITH "p1" OR field STARTS_WITH "p2" ... + * - All SUFFIX → field ENDS_WITH "s1" OR field ENDS_WITH "s2" ... + * + * Heterogeneous patterns: + * - Mixed → (field == "exact") OR (field STARTS_WITH "prefix") OR (field ENDS_WITH "suffix") OR (field RLIKE "regex") + * + * Fragments are sorted by type for optimal query execution order: + * 1. EXACT (most selective, can use IN clause) + * 2. PREFIX (index-friendly) + * 3. SUFFIX (index-friendly) + * 4. REGEX (least selective, fallback) + * + * @param source the source location + * @param field the field attribute + * @param fragments the list of pattern fragments + * @return the ESQL Expression combining all fragments + */ + private static Expression translateDisjointPatterns(Source source, Expression field, List fragments) { + // Sort fragments by type priority using enum ordinal: EXACT -> PREFIX -> SUFFIX -> REGEX + List sortedFragments = new ArrayList<>(fragments); + sortedFragments.sort(Comparator.comparingInt(a -> a.type().ordinal())); + + // Check if all fragments are of the same type + AutomatonUtils.PatternFragment.Type firstType = sortedFragments.get(0).type(); + boolean homogeneous = true; + for (AutomatonUtils.PatternFragment fragment : sortedFragments) { + if (fragment.type() != firstType) { + homogeneous = false; + break; + } + } + + if (homogeneous && firstType == AutomatonUtils.PatternFragment.Type.EXACT) { + // Optimize to IN clause + List values = new ArrayList<>(sortedFragments.size()); + for (AutomatonUtils.PatternFragment fragment : sortedFragments) { + values.add(Literal.keyword(source, fragment.value())); + } + return new In(source, field, values); + } + + // For non-exact homogeneous or heterogeneous patterns, create OR of conditions + List conditions = new ArrayList<>(sortedFragments.size()); + for (AutomatonUtils.PatternFragment fragment : sortedFragments) { + Expression condition = translatePatternFragment(source, field, fragment); + conditions.add(condition); + } + + // Combine with OR + return Predicates.combineOr(conditions); + } + + /** + * Translates a single pattern fragment into an ESQL expression. + */ + private static Expression translatePatternFragment(Source source, Expression field, AutomatonUtils.PatternFragment fragment) { + Literal value = Literal.keyword(source, fragment.value()); + + return switch (fragment.type()) { + case EXACT -> new Equals(source, field, value); + case PREFIX -> new StartsWith(source, field, value); + case PROPER_PREFIX -> new And(source, new NotEquals(source, field, value), new StartsWith(source, field, value)); + case SUFFIX -> new EndsWith(source, field, value); + case PROPER_SUFFIX -> new And(source, new NotEquals(source, field, value), new EndsWith(source, field, value)); + case REGEX -> new RLike(source, field, new RLikePattern(fragment.value())); + }; + } +} diff --git a/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/parser/EsqlBaseLexer.interp b/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/parser/EsqlBaseLexer.interp index 232043030159a..02f38b0a1c081 100644 --- a/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/parser/EsqlBaseLexer.interp +++ b/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/parser/EsqlBaseLexer.interp @@ -32,6 +32,7 @@ null 'drop' 'keep' null +null 'rename' 'set' 'show' @@ -140,6 +141,14 @@ null null null null +null +null +null +null +null +null +null +null 'as' null null @@ -186,6 +195,7 @@ MV_EXPAND DROP KEEP DEV_INSIST +DEV_PROMQL RENAME SET SHOW @@ -294,6 +304,14 @@ ID_PATTERN PROJECT_LINE_COMMENT PROJECT_MULTILINE_COMMENT PROJECT_WS +PROMQL_UNQUOTED_IDENTIFIER +PROMQL_PARAMS_LINE_COMMENT +PROMQL_PARAMS_MULTILINE_COMMENT +PROMQL_PARAMS_WS +PROMQL_QUERY_TEXT +PROMQL_QUERY_LINE_COMMENT +PROMQL_QUERY_MULTILINE_COMMENT +PROMQL_QUERY_WS AS RENAME_LINE_COMMENT RENAME_MULTILINE_COMMENT @@ -339,6 +357,7 @@ MV_EXPAND DROP KEEP DEV_INSIST +DEV_PROMQL RENAME SET SHOW @@ -559,6 +578,25 @@ ID_PATTERN PROJECT_LINE_COMMENT PROJECT_MULTILINE_COMMENT PROJECT_WS +PROMQL_UNQUOTED_IDENTIFIER +PROMQL_QUOTED_STRING +PROMQL_QUOTED_IDENTIFIER +PROMQL_NAMED_PARAMS +PROMQL_PARAMS_PIPE +PROMQL_LP +PROMQL_PARAMS_LINE_COMMENT +PROMQL_PARAMS_MULTILINE_COMMENT +PROMQL_PARAMS_WS +PROMQL_NESTED_LP +PROMQL_QUERY_TEXT +PROMQL_STRING_LITERAL +PROMQL_QUERY_COMMENT +PROMQL_NESTED_RP +PROMQL_QUERY_RP +PROMQL_QUERY_PIPE +PROMQL_QUERY_LINE_COMMENT +PROMQL_QUERY_MULTILINE_COMMENT +PROMQL_QUERY_WS RENAME_PIPE RENAME_RP RENAME_OPENING_BRACKET @@ -623,9 +661,11 @@ LOOKUP_MODE LOOKUP_FIELD_MODE MVEXPAND_MODE PROJECT_MODE +PROMQL_PARAMS_MODE +PROMQL_QUERY_MODE RENAME_MODE SET_MODE SHOW_MODE atn: -[4, 0, 151, 2158, 6, -1, 6, -1, 6, -1, 6, -1, 6, -1, 6, -1, 6, -1, 6, -1, 6, -1, 6, -1, 6, -1, 6, -1, 6, -1, 6, -1, 6, -1, 6, -1, 6, -1, 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, 2, 26, 7, 26, 2, 27, 7, 27, 2, 28, 7, 28, 2, 29, 7, 29, 2, 30, 7, 30, 2, 31, 7, 31, 2, 32, 7, 32, 2, 33, 7, 33, 2, 34, 7, 34, 2, 35, 7, 35, 2, 36, 7, 36, 2, 37, 7, 37, 2, 38, 7, 38, 2, 39, 7, 39, 2, 40, 7, 40, 2, 41, 7, 41, 2, 42, 7, 42, 2, 43, 7, 43, 2, 44, 7, 44, 2, 45, 7, 45, 2, 46, 7, 46, 2, 47, 7, 47, 2, 48, 7, 48, 2, 49, 7, 49, 2, 50, 7, 50, 2, 51, 7, 51, 2, 52, 7, 52, 2, 53, 7, 53, 2, 54, 7, 54, 2, 55, 7, 55, 2, 56, 7, 56, 2, 57, 7, 57, 2, 58, 7, 58, 2, 59, 7, 59, 2, 60, 7, 60, 2, 61, 7, 61, 2, 62, 7, 62, 2, 63, 7, 63, 2, 64, 7, 64, 2, 65, 7, 65, 2, 66, 7, 66, 2, 67, 7, 67, 2, 68, 7, 68, 2, 69, 7, 69, 2, 70, 7, 70, 2, 71, 7, 71, 2, 72, 7, 72, 2, 73, 7, 73, 2, 74, 7, 74, 2, 75, 7, 75, 2, 76, 7, 76, 2, 77, 7, 77, 2, 78, 7, 78, 2, 79, 7, 79, 2, 80, 7, 80, 2, 81, 7, 81, 2, 82, 7, 82, 2, 83, 7, 83, 2, 84, 7, 84, 2, 85, 7, 85, 2, 86, 7, 86, 2, 87, 7, 87, 2, 88, 7, 88, 2, 89, 7, 89, 2, 90, 7, 90, 2, 91, 7, 91, 2, 92, 7, 92, 2, 93, 7, 93, 2, 94, 7, 94, 2, 95, 7, 95, 2, 96, 7, 96, 2, 97, 7, 97, 2, 98, 7, 98, 2, 99, 7, 99, 2, 100, 7, 100, 2, 101, 7, 101, 2, 102, 7, 102, 2, 103, 7, 103, 2, 104, 7, 104, 2, 105, 7, 105, 2, 106, 7, 106, 2, 107, 7, 107, 2, 108, 7, 108, 2, 109, 7, 109, 2, 110, 7, 110, 2, 111, 7, 111, 2, 112, 7, 112, 2, 113, 7, 113, 2, 114, 7, 114, 2, 115, 7, 115, 2, 116, 7, 116, 2, 117, 7, 117, 2, 118, 7, 118, 2, 119, 7, 119, 2, 120, 7, 120, 2, 121, 7, 121, 2, 122, 7, 122, 2, 123, 7, 123, 2, 124, 7, 124, 2, 125, 7, 125, 2, 126, 7, 126, 2, 127, 7, 127, 2, 128, 7, 128, 2, 129, 7, 129, 2, 130, 7, 130, 2, 131, 7, 131, 2, 132, 7, 132, 2, 133, 7, 133, 2, 134, 7, 134, 2, 135, 7, 135, 2, 136, 7, 136, 2, 137, 7, 137, 2, 138, 7, 138, 2, 139, 7, 139, 2, 140, 7, 140, 2, 141, 7, 141, 2, 142, 7, 142, 2, 143, 7, 143, 2, 144, 7, 144, 2, 145, 7, 145, 2, 146, 7, 146, 2, 147, 7, 147, 2, 148, 7, 148, 2, 149, 7, 149, 2, 150, 7, 150, 2, 151, 7, 151, 2, 152, 7, 152, 2, 153, 7, 153, 2, 154, 7, 154, 2, 155, 7, 155, 2, 156, 7, 156, 2, 157, 7, 157, 2, 158, 7, 158, 2, 159, 7, 159, 2, 160, 7, 160, 2, 161, 7, 161, 2, 162, 7, 162, 2, 163, 7, 163, 2, 164, 7, 164, 2, 165, 7, 165, 2, 166, 7, 166, 2, 167, 7, 167, 2, 168, 7, 168, 2, 169, 7, 169, 2, 170, 7, 170, 2, 171, 7, 171, 2, 172, 7, 172, 2, 173, 7, 173, 2, 174, 7, 174, 2, 175, 7, 175, 2, 176, 7, 176, 2, 177, 7, 177, 2, 178, 7, 178, 2, 179, 7, 179, 2, 180, 7, 180, 2, 181, 7, 181, 2, 182, 7, 182, 2, 183, 7, 183, 2, 184, 7, 184, 2, 185, 7, 185, 2, 186, 7, 186, 2, 187, 7, 187, 2, 188, 7, 188, 2, 189, 7, 189, 2, 190, 7, 190, 2, 191, 7, 191, 2, 192, 7, 192, 2, 193, 7, 193, 2, 194, 7, 194, 2, 195, 7, 195, 2, 196, 7, 196, 2, 197, 7, 197, 2, 198, 7, 198, 2, 199, 7, 199, 2, 200, 7, 200, 2, 201, 7, 201, 2, 202, 7, 202, 2, 203, 7, 203, 2, 204, 7, 204, 2, 205, 7, 205, 2, 206, 7, 206, 2, 207, 7, 207, 2, 208, 7, 208, 2, 209, 7, 209, 2, 210, 7, 210, 2, 211, 7, 211, 2, 212, 7, 212, 2, 213, 7, 213, 2, 214, 7, 214, 2, 215, 7, 215, 2, 216, 7, 216, 2, 217, 7, 217, 2, 218, 7, 218, 2, 219, 7, 219, 2, 220, 7, 220, 2, 221, 7, 221, 2, 222, 7, 222, 2, 223, 7, 223, 2, 224, 7, 224, 2, 225, 7, 225, 2, 226, 7, 226, 2, 227, 7, 227, 2, 228, 7, 228, 2, 229, 7, 229, 2, 230, 7, 230, 2, 231, 7, 231, 2, 232, 7, 232, 2, 233, 7, 233, 2, 234, 7, 234, 2, 235, 7, 235, 2, 236, 7, 236, 2, 237, 7, 237, 2, 238, 7, 238, 2, 239, 7, 239, 2, 240, 7, 240, 2, 241, 7, 241, 2, 242, 7, 242, 2, 243, 7, 243, 2, 244, 7, 244, 2, 245, 7, 245, 2, 246, 7, 246, 2, 247, 7, 247, 2, 248, 7, 248, 2, 249, 7, 249, 2, 250, 7, 250, 2, 251, 7, 251, 2, 252, 7, 252, 2, 253, 7, 253, 2, 254, 7, 254, 2, 255, 7, 255, 2, 256, 7, 256, 2, 257, 7, 257, 2, 258, 7, 258, 2, 259, 7, 259, 2, 260, 7, 260, 2, 261, 7, 261, 2, 262, 7, 262, 2, 263, 7, 263, 2, 264, 7, 264, 2, 265, 7, 265, 2, 266, 7, 266, 2, 267, 7, 267, 2, 268, 7, 268, 2, 269, 7, 269, 2, 270, 7, 270, 2, 271, 7, 271, 2, 272, 7, 272, 2, 273, 7, 273, 2, 274, 7, 274, 2, 275, 7, 275, 2, 276, 7, 276, 2, 277, 7, 277, 2, 278, 7, 278, 2, 279, 7, 279, 2, 280, 7, 280, 2, 281, 7, 281, 2, 282, 7, 282, 2, 283, 7, 283, 2, 284, 7, 284, 2, 285, 7, 285, 2, 286, 7, 286, 2, 287, 7, 287, 2, 288, 7, 288, 2, 289, 7, 289, 2, 290, 7, 290, 2, 291, 7, 291, 2, 292, 7, 292, 2, 293, 7, 293, 2, 294, 7, 294, 1, 0, 1, 0, 1, 0, 1, 0, 5, 0, 613, 8, 0, 10, 0, 12, 0, 616, 9, 0, 1, 0, 3, 0, 619, 8, 0, 1, 0, 3, 0, 622, 8, 0, 1, 0, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 5, 1, 631, 8, 1, 10, 1, 12, 1, 634, 9, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 4, 2, 642, 8, 2, 11, 2, 12, 2, 643, 1, 2, 1, 2, 1, 3, 1, 3, 1, 3, 1, 3, 1, 3, 1, 3, 1, 3, 1, 3, 1, 3, 1, 3, 1, 3, 1, 3, 1, 3, 1, 3, 1, 3, 1, 4, 1, 4, 1, 4, 1, 4, 1, 4, 1, 4, 1, 4, 1, 4, 1, 4, 1, 5, 1, 5, 1, 5, 1, 5, 1, 5, 1, 5, 1, 5, 1, 5, 1, 5, 1, 5, 1, 5, 1, 6, 1, 6, 1, 6, 1, 6, 1, 6, 1, 6, 1, 6, 1, 6, 1, 6, 1, 6, 1, 6, 1, 6, 1, 6, 1, 7, 1, 7, 1, 7, 1, 7, 1, 7, 1, 7, 1, 7, 1, 7, 1, 7, 1, 7, 1, 8, 1, 8, 1, 8, 1, 8, 1, 8, 1, 8, 1, 8, 1, 9, 1, 9, 1, 9, 1, 9, 1, 9, 1, 9, 1, 9, 1, 10, 1, 10, 1, 10, 1, 10, 1, 10, 1, 10, 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, 12, 1, 12, 1, 13, 1, 13, 1, 13, 1, 13, 1, 13, 1, 13, 1, 13, 1, 13, 1, 13, 1, 14, 1, 14, 1, 14, 1, 14, 1, 14, 1, 14, 1, 14, 1, 15, 1, 15, 1, 15, 1, 15, 1, 15, 1, 15, 1, 15, 1, 15, 1, 16, 1, 16, 1, 16, 1, 16, 1, 16, 1, 16, 1, 16, 1, 16, 1, 17, 1, 17, 1, 17, 1, 17, 1, 17, 1, 17, 1, 17, 1, 18, 1, 18, 1, 18, 1, 18, 1, 18, 1, 19, 1, 19, 1, 19, 1, 19, 1, 19, 1, 19, 1, 19, 1, 20, 1, 20, 1, 20, 1, 20, 1, 20, 1, 20, 1, 20, 1, 21, 1, 21, 1, 21, 1, 21, 1, 21, 1, 21, 1, 21, 1, 21, 1, 21, 1, 22, 1, 22, 1, 22, 1, 22, 1, 22, 1, 22, 1, 22, 1, 22, 1, 22, 1, 22, 1, 22, 1, 22, 1, 22, 1, 22, 1, 23, 1, 23, 1, 23, 1, 23, 1, 23, 1, 23, 1, 23, 1, 23, 1, 23, 1, 24, 1, 24, 1, 24, 1, 24, 1, 24, 1, 24, 1, 24, 1, 24, 1, 25, 1, 25, 1, 25, 1, 25, 1, 25, 1, 25, 1, 25, 1, 25, 1, 26, 1, 26, 1, 26, 1, 26, 1, 26, 1, 26, 1, 26, 1, 26, 1, 26, 1, 27, 1, 27, 1, 27, 1, 27, 1, 27, 1, 27, 1, 27, 1, 27, 1, 27, 1, 27, 1, 27, 1, 27, 1, 28, 1, 28, 1, 28, 1, 28, 1, 28, 1, 28, 1, 28, 1, 28, 1, 28, 1, 28, 1, 28, 1, 28, 1, 29, 1, 29, 1, 29, 1, 29, 1, 29, 1, 29, 1, 29, 1, 30, 1, 30, 1, 30, 1, 30, 1, 30, 1, 30, 1, 30, 1, 31, 1, 31, 1, 31, 1, 31, 1, 31, 1, 31, 1, 31, 1, 31, 1, 31, 1, 31, 1, 31, 1, 31, 1, 32, 1, 32, 1, 32, 1, 32, 1, 32, 1, 32, 1, 32, 1, 32, 1, 32, 1, 33, 1, 33, 1, 33, 1, 33, 1, 33, 1, 33, 1, 34, 1, 34, 1, 34, 1, 34, 1, 34, 1, 34, 1, 34, 1, 35, 4, 35, 931, 8, 35, 11, 35, 12, 35, 932, 1, 35, 1, 35, 1, 36, 1, 36, 1, 36, 1, 36, 1, 36, 1, 37, 1, 37, 1, 37, 1, 37, 1, 37, 1, 37, 1, 38, 1, 38, 1, 38, 1, 38, 1, 39, 1, 39, 1, 39, 1, 39, 1, 40, 1, 40, 1, 40, 1, 40, 1, 41, 1, 41, 1, 41, 1, 41, 1, 42, 1, 42, 1, 42, 1, 42, 1, 43, 1, 43, 1, 43, 1, 43, 1, 44, 1, 44, 1, 44, 1, 44, 1, 45, 1, 45, 1, 45, 1, 45, 1, 46, 1, 46, 1, 46, 1, 46, 1, 47, 1, 47, 1, 47, 1, 47, 1, 48, 1, 48, 1, 48, 1, 48, 1, 49, 1, 49, 1, 49, 1, 49, 1, 49, 1, 50, 1, 50, 1, 50, 1, 50, 1, 50, 1, 50, 1, 51, 1, 51, 1, 51, 1, 51, 1, 51, 1, 52, 1, 52, 1, 52, 1, 52, 1, 52, 1, 53, 1, 53, 1, 54, 4, 54, 1016, 8, 54, 11, 54, 12, 54, 1017, 1, 54, 1, 54, 3, 54, 1022, 8, 54, 1, 54, 4, 54, 1025, 8, 54, 11, 54, 12, 54, 1026, 1, 55, 1, 55, 1, 55, 1, 55, 1, 56, 1, 56, 1, 56, 1, 56, 1, 57, 1, 57, 1, 57, 1, 57, 1, 58, 1, 58, 1, 58, 1, 58, 1, 59, 1, 59, 1, 59, 1, 59, 1, 60, 1, 60, 1, 60, 1, 60, 1, 60, 1, 60, 1, 61, 1, 61, 1, 61, 1, 61, 1, 61, 1, 61, 1, 61, 1, 62, 1, 62, 1, 62, 1, 62, 1, 63, 1, 63, 1, 63, 1, 63, 1, 64, 1, 64, 1, 64, 1, 64, 1, 65, 1, 65, 1, 65, 1, 65, 1, 66, 1, 66, 1, 66, 1, 66, 1, 67, 1, 67, 1, 67, 1, 67, 1, 68, 1, 68, 1, 68, 1, 68, 1, 69, 1, 69, 1, 69, 1, 69, 1, 70, 1, 70, 1, 70, 1, 70, 1, 71, 1, 71, 1, 71, 1, 71, 1, 72, 1, 72, 1, 72, 1, 72, 1, 73, 1, 73, 1, 73, 1, 73, 1, 74, 1, 74, 1, 74, 1, 74, 1, 75, 1, 75, 1, 75, 1, 75, 1, 76, 1, 76, 1, 76, 1, 76, 1, 77, 1, 77, 1, 77, 1, 77, 1, 77, 1, 78, 1, 78, 1, 78, 1, 78, 1, 78, 1, 79, 1, 79, 1, 79, 1, 79, 1, 80, 1, 80, 1, 80, 1, 80, 1, 81, 1, 81, 1, 81, 1, 81, 1, 82, 1, 82, 1, 82, 1, 82, 1, 83, 1, 83, 1, 84, 1, 84, 1, 85, 1, 85, 1, 85, 1, 86, 1, 86, 1, 87, 1, 87, 3, 87, 1159, 8, 87, 1, 87, 4, 87, 1162, 8, 87, 11, 87, 12, 87, 1163, 1, 88, 1, 88, 1, 89, 1, 89, 1, 90, 1, 90, 1, 90, 3, 90, 1173, 8, 90, 1, 91, 1, 91, 1, 92, 1, 92, 1, 92, 3, 92, 1180, 8, 92, 1, 93, 1, 93, 1, 93, 5, 93, 1185, 8, 93, 10, 93, 12, 93, 1188, 9, 93, 1, 93, 1, 93, 1, 93, 1, 93, 1, 93, 1, 93, 5, 93, 1196, 8, 93, 10, 93, 12, 93, 1199, 9, 93, 1, 93, 1, 93, 1, 93, 1, 93, 1, 93, 3, 93, 1206, 8, 93, 1, 93, 3, 93, 1209, 8, 93, 3, 93, 1211, 8, 93, 1, 94, 4, 94, 1214, 8, 94, 11, 94, 12, 94, 1215, 1, 95, 4, 95, 1219, 8, 95, 11, 95, 12, 95, 1220, 1, 95, 1, 95, 5, 95, 1225, 8, 95, 10, 95, 12, 95, 1228, 9, 95, 1, 95, 1, 95, 4, 95, 1232, 8, 95, 11, 95, 12, 95, 1233, 1, 95, 4, 95, 1237, 8, 95, 11, 95, 12, 95, 1238, 1, 95, 1, 95, 5, 95, 1243, 8, 95, 10, 95, 12, 95, 1246, 9, 95, 3, 95, 1248, 8, 95, 1, 95, 1, 95, 1, 95, 1, 95, 4, 95, 1254, 8, 95, 11, 95, 12, 95, 1255, 1, 95, 1, 95, 3, 95, 1260, 8, 95, 1, 96, 1, 96, 1, 96, 1, 96, 1, 97, 1, 97, 1, 97, 1, 97, 1, 98, 1, 98, 1, 99, 1, 99, 1, 99, 1, 100, 1, 100, 1, 100, 1, 101, 1, 101, 1, 102, 1, 102, 1, 103, 1, 103, 1, 104, 1, 104, 1, 104, 1, 104, 1, 104, 1, 105, 1, 105, 1, 106, 1, 106, 1, 106, 1, 106, 1, 106, 1, 106, 1, 107, 1, 107, 1, 107, 1, 107, 1, 107, 1, 107, 1, 108, 1, 108, 1, 108, 1, 109, 1, 109, 1, 109, 1, 110, 1, 110, 1, 110, 1, 110, 1, 110, 1, 111, 1, 111, 1, 111, 1, 111, 1, 111, 1, 112, 1, 112, 1, 112, 1, 112, 1, 113, 1, 113, 1, 113, 1, 113, 1, 113, 1, 114, 1, 114, 1, 114, 1, 114, 1, 114, 1, 114, 1, 115, 1, 115, 1, 115, 1, 116, 1, 116, 1, 116, 1, 117, 1, 117, 1, 118, 1, 118, 1, 118, 1, 118, 1, 118, 1, 118, 1, 119, 1, 119, 1, 119, 1, 119, 1, 119, 1, 120, 1, 120, 1, 120, 1, 120, 1, 120, 1, 121, 1, 121, 1, 121, 1, 122, 1, 122, 1, 122, 1, 123, 1, 123, 1, 123, 1, 124, 1, 124, 1, 125, 1, 125, 1, 125, 1, 126, 1, 126, 1, 127, 1, 127, 1, 127, 1, 128, 1, 128, 1, 129, 1, 129, 1, 130, 1, 130, 1, 131, 1, 131, 1, 132, 1, 132, 1, 133, 1, 133, 1, 134, 1, 134, 1, 135, 1, 135, 1, 135, 1, 136, 1, 136, 1, 136, 1, 136, 1, 137, 1, 137, 1, 137, 3, 137, 1401, 8, 137, 1, 137, 5, 137, 1404, 8, 137, 10, 137, 12, 137, 1407, 9, 137, 1, 137, 1, 137, 4, 137, 1411, 8, 137, 11, 137, 12, 137, 1412, 3, 137, 1415, 8, 137, 1, 138, 1, 138, 1, 138, 3, 138, 1420, 8, 138, 1, 138, 5, 138, 1423, 8, 138, 10, 138, 12, 138, 1426, 9, 138, 1, 138, 1, 138, 4, 138, 1430, 8, 138, 11, 138, 12, 138, 1431, 3, 138, 1434, 8, 138, 1, 139, 1, 139, 1, 139, 1, 139, 1, 139, 1, 140, 1, 140, 1, 140, 1, 140, 1, 140, 1, 141, 1, 141, 1, 141, 1, 141, 1, 141, 1, 142, 1, 142, 1, 142, 1, 142, 1, 142, 1, 143, 1, 143, 5, 143, 1458, 8, 143, 10, 143, 12, 143, 1461, 9, 143, 1, 143, 1, 143, 3, 143, 1465, 8, 143, 1, 143, 4, 143, 1468, 8, 143, 11, 143, 12, 143, 1469, 3, 143, 1472, 8, 143, 1, 144, 1, 144, 4, 144, 1476, 8, 144, 11, 144, 12, 144, 1477, 1, 144, 1, 144, 1, 145, 1, 145, 1, 146, 1, 146, 1, 146, 1, 146, 1, 147, 1, 147, 1, 147, 1, 147, 1, 148, 1, 148, 1, 148, 1, 148, 1, 149, 1, 149, 1, 149, 1, 149, 1, 149, 1, 150, 1, 150, 1, 150, 1, 150, 1, 151, 1, 151, 1, 151, 1, 151, 1, 152, 1, 152, 1, 152, 1, 152, 1, 153, 1, 153, 1, 153, 1, 153, 1, 154, 1, 154, 1, 154, 1, 154, 1, 154, 1, 154, 1, 154, 1, 154, 1, 154, 1, 155, 1, 155, 1, 155, 1, 155, 1, 155, 1, 155, 1, 156, 1, 156, 1, 156, 1, 156, 1, 156, 1, 157, 1, 157, 1, 157, 3, 157, 1540, 8, 157, 1, 158, 4, 158, 1543, 8, 158, 11, 158, 12, 158, 1544, 1, 159, 1, 159, 1, 159, 1, 159, 1, 160, 1, 160, 1, 160, 1, 160, 1, 161, 1, 161, 1, 161, 1, 161, 1, 162, 1, 162, 1, 162, 1, 162, 1, 163, 1, 163, 1, 163, 1, 163, 1, 164, 1, 164, 1, 164, 1, 164, 1, 164, 1, 165, 1, 165, 1, 165, 1, 165, 1, 165, 1, 165, 1, 166, 1, 166, 1, 166, 1, 166, 1, 166, 1, 167, 1, 167, 1, 167, 1, 167, 1, 168, 1, 168, 1, 168, 1, 168, 1, 169, 1, 169, 1, 169, 1, 169, 1, 170, 1, 170, 1, 170, 1, 170, 1, 170, 1, 171, 1, 171, 1, 171, 1, 171, 1, 171, 1, 171, 1, 172, 1, 172, 1, 172, 1, 172, 1, 172, 1, 172, 1, 173, 1, 173, 1, 173, 1, 173, 1, 173, 1, 173, 1, 174, 1, 174, 1, 174, 1, 174, 1, 175, 1, 175, 1, 175, 1, 175, 1, 175, 1, 175, 1, 176, 1, 176, 1, 176, 1, 176, 1, 177, 1, 177, 1, 177, 1, 177, 1, 178, 1, 178, 1, 178, 1, 178, 1, 179, 1, 179, 1, 179, 1, 179, 1, 180, 1, 180, 1, 180, 1, 180, 1, 181, 1, 181, 1, 181, 1, 181, 1, 182, 1, 182, 1, 182, 1, 182, 1, 183, 1, 183, 1, 183, 1, 183, 1, 184, 1, 184, 1, 184, 1, 184, 1, 185, 1, 185, 1, 185, 1, 185, 1, 186, 1, 186, 1, 186, 1, 186, 1, 187, 1, 187, 1, 187, 1, 187, 1, 188, 1, 188, 1, 188, 1, 188, 1, 188, 1, 188, 1, 188, 1, 188, 1, 188, 1, 189, 1, 189, 1, 189, 1, 189, 1, 190, 1, 190, 1, 190, 1, 190, 1, 191, 1, 191, 1, 191, 1, 191, 1, 192, 1, 192, 1, 192, 1, 192, 1, 192, 1, 193, 1, 193, 1, 193, 1, 193, 1, 193, 1, 194, 1, 194, 1, 194, 1, 194, 1, 195, 1, 195, 1, 195, 1, 195, 1, 195, 1, 195, 1, 196, 1, 196, 1, 196, 1, 196, 1, 196, 1, 196, 1, 196, 1, 196, 1, 196, 1, 197, 1, 197, 1, 197, 1, 197, 1, 198, 1, 198, 1, 198, 1, 198, 1, 199, 1, 199, 1, 199, 1, 199, 1, 200, 1, 200, 1, 200, 1, 200, 1, 201, 1, 201, 1, 201, 1, 201, 1, 202, 1, 202, 1, 202, 1, 202, 1, 203, 1, 203, 1, 203, 1, 203, 1, 203, 1, 204, 1, 204, 1, 204, 1, 204, 1, 204, 1, 204, 1, 205, 1, 205, 1, 205, 1, 205, 1, 206, 1, 206, 1, 206, 1, 206, 1, 207, 1, 207, 1, 207, 1, 207, 1, 208, 1, 208, 1, 208, 1, 208, 1, 208, 1, 209, 1, 209, 1, 209, 1, 209, 1, 210, 1, 210, 1, 210, 1, 210, 1, 211, 1, 211, 1, 211, 1, 211, 1, 212, 1, 212, 1, 212, 1, 212, 1, 213, 1, 213, 1, 213, 1, 213, 1, 214, 1, 214, 1, 214, 1, 214, 1, 214, 1, 214, 1, 215, 1, 215, 1, 215, 1, 215, 1, 215, 1, 215, 1, 215, 1, 216, 1, 216, 1, 216, 1, 216, 1, 217, 1, 217, 1, 217, 1, 217, 1, 218, 1, 218, 1, 218, 1, 218, 1, 219, 1, 219, 1, 219, 1, 219, 1, 220, 1, 220, 1, 220, 1, 220, 1, 221, 1, 221, 1, 221, 1, 221, 1, 222, 1, 222, 1, 222, 1, 222, 1, 222, 1, 223, 1, 223, 1, 223, 1, 223, 1, 223, 1, 223, 1, 224, 1, 224, 1, 224, 1, 224, 1, 225, 1, 225, 1, 225, 1, 225, 1, 226, 1, 226, 1, 226, 1, 226, 1, 227, 1, 227, 1, 227, 1, 227, 1, 228, 1, 228, 1, 228, 1, 228, 1, 229, 1, 229, 1, 229, 1, 229, 1, 230, 1, 230, 1, 230, 1, 230, 1, 231, 1, 231, 1, 231, 1, 231, 1, 232, 1, 232, 1, 232, 1, 232, 1, 233, 1, 233, 1, 233, 1, 233, 1, 234, 1, 234, 1, 234, 1, 234, 1, 235, 1, 235, 1, 235, 1, 235, 1, 236, 1, 236, 1, 236, 1, 236, 1, 236, 1, 237, 1, 237, 1, 237, 1, 237, 1, 237, 1, 237, 1, 238, 1, 238, 1, 238, 1, 238, 1, 239, 1, 239, 1, 239, 1, 239, 1, 240, 1, 240, 1, 240, 1, 240, 1, 241, 1, 241, 1, 241, 1, 241, 1, 242, 1, 242, 1, 242, 1, 242, 1, 243, 1, 243, 1, 243, 1, 243, 1, 244, 1, 244, 1, 244, 1, 244, 1, 245, 1, 245, 1, 245, 1, 245, 1, 246, 1, 246, 1, 246, 1, 246, 3, 246, 1941, 8, 246, 1, 247, 1, 247, 3, 247, 1945, 8, 247, 1, 247, 5, 247, 1948, 8, 247, 10, 247, 12, 247, 1951, 9, 247, 1, 247, 1, 247, 3, 247, 1955, 8, 247, 1, 247, 4, 247, 1958, 8, 247, 11, 247, 12, 247, 1959, 3, 247, 1962, 8, 247, 1, 248, 1, 248, 4, 248, 1966, 8, 248, 11, 248, 12, 248, 1967, 1, 249, 1, 249, 1, 249, 1, 249, 1, 250, 1, 250, 1, 250, 1, 250, 1, 251, 1, 251, 1, 251, 1, 251, 1, 252, 1, 252, 1, 252, 1, 252, 1, 252, 1, 253, 1, 253, 1, 253, 1, 253, 1, 253, 1, 253, 1, 254, 1, 254, 1, 254, 1, 254, 1, 255, 1, 255, 1, 255, 1, 255, 1, 256, 1, 256, 1, 256, 1, 256, 1, 257, 1, 257, 1, 257, 1, 257, 1, 258, 1, 258, 1, 258, 1, 258, 1, 259, 1, 259, 1, 259, 1, 259, 1, 260, 1, 260, 1, 260, 1, 260, 1, 261, 1, 261, 1, 261, 1, 261, 1, 262, 1, 262, 1, 262, 1, 262, 1, 263, 1, 263, 1, 263, 1, 264, 1, 264, 1, 264, 1, 264, 1, 265, 1, 265, 1, 265, 1, 265, 1, 266, 1, 266, 1, 266, 1, 266, 1, 267, 1, 267, 1, 267, 1, 267, 1, 268, 1, 268, 1, 268, 1, 268, 1, 269, 1, 269, 1, 269, 1, 269, 1, 270, 1, 270, 1, 270, 1, 270, 1, 271, 1, 271, 1, 271, 1, 271, 1, 271, 1, 272, 1, 272, 1, 272, 1, 272, 1, 273, 1, 273, 1, 273, 1, 273, 1, 274, 1, 274, 1, 274, 1, 274, 1, 275, 1, 275, 1, 275, 1, 275, 1, 276, 1, 276, 1, 276, 1, 276, 1, 277, 1, 277, 1, 277, 1, 277, 1, 278, 1, 278, 1, 278, 1, 278, 1, 279, 1, 279, 1, 279, 1, 279, 1, 280, 1, 280, 1, 280, 1, 280, 1, 281, 1, 281, 1, 281, 1, 281, 1, 282, 1, 282, 1, 282, 1, 282, 1, 283, 1, 283, 1, 283, 1, 283, 1, 284, 1, 284, 1, 284, 1, 284, 1, 285, 1, 285, 1, 285, 1, 285, 1, 286, 1, 286, 1, 286, 1, 286, 1, 287, 1, 287, 1, 287, 1, 287, 1, 288, 1, 288, 1, 288, 1, 288, 1, 289, 1, 289, 1, 289, 1, 289, 1, 290, 1, 290, 1, 290, 1, 290, 1, 290, 1, 291, 1, 291, 1, 291, 1, 291, 1, 291, 1, 292, 1, 292, 1, 292, 1, 292, 1, 293, 1, 293, 1, 293, 1, 293, 1, 294, 1, 294, 1, 294, 1, 294, 2, 632, 1197, 0, 295, 18, 1, 20, 2, 22, 3, 24, 4, 26, 5, 28, 6, 30, 7, 32, 8, 34, 9, 36, 10, 38, 11, 40, 12, 42, 13, 44, 14, 46, 15, 48, 16, 50, 17, 52, 18, 54, 19, 56, 20, 58, 21, 60, 22, 62, 23, 64, 24, 66, 25, 68, 26, 70, 27, 72, 28, 74, 29, 76, 30, 78, 31, 80, 32, 82, 33, 84, 34, 86, 35, 88, 36, 90, 0, 92, 0, 94, 0, 96, 0, 98, 0, 100, 0, 102, 0, 104, 0, 106, 0, 108, 0, 110, 37, 112, 38, 114, 39, 116, 0, 118, 0, 120, 0, 122, 0, 124, 0, 126, 40, 128, 0, 130, 0, 132, 41, 134, 42, 136, 43, 138, 0, 140, 0, 142, 0, 144, 0, 146, 0, 148, 0, 150, 0, 152, 0, 154, 0, 156, 0, 158, 0, 160, 0, 162, 0, 164, 0, 166, 44, 168, 45, 170, 46, 172, 0, 174, 0, 176, 47, 178, 48, 180, 49, 182, 50, 184, 0, 186, 0, 188, 0, 190, 0, 192, 0, 194, 0, 196, 0, 198, 0, 200, 0, 202, 0, 204, 51, 206, 52, 208, 53, 210, 54, 212, 55, 214, 56, 216, 57, 218, 58, 220, 59, 222, 60, 224, 61, 226, 62, 228, 63, 230, 64, 232, 65, 234, 66, 236, 67, 238, 68, 240, 69, 242, 70, 244, 71, 246, 72, 248, 73, 250, 74, 252, 75, 254, 76, 256, 77, 258, 78, 260, 79, 262, 80, 264, 81, 266, 82, 268, 83, 270, 84, 272, 85, 274, 86, 276, 87, 278, 88, 280, 89, 282, 90, 284, 91, 286, 92, 288, 93, 290, 0, 292, 94, 294, 95, 296, 96, 298, 97, 300, 98, 302, 99, 304, 100, 306, 0, 308, 101, 310, 102, 312, 103, 314, 104, 316, 0, 318, 0, 320, 0, 322, 0, 324, 0, 326, 105, 328, 0, 330, 0, 332, 0, 334, 106, 336, 0, 338, 0, 340, 107, 342, 108, 344, 109, 346, 0, 348, 0, 350, 0, 352, 110, 354, 111, 356, 112, 358, 0, 360, 0, 362, 113, 364, 114, 366, 115, 368, 0, 370, 0, 372, 0, 374, 0, 376, 0, 378, 0, 380, 0, 382, 0, 384, 0, 386, 0, 388, 116, 390, 117, 392, 118, 394, 119, 396, 120, 398, 121, 400, 122, 402, 0, 404, 123, 406, 0, 408, 0, 410, 124, 412, 0, 414, 0, 416, 0, 418, 125, 420, 126, 422, 127, 424, 0, 426, 0, 428, 0, 430, 0, 432, 0, 434, 0, 436, 0, 438, 0, 440, 128, 442, 129, 444, 130, 446, 0, 448, 0, 450, 0, 452, 0, 454, 0, 456, 131, 458, 132, 460, 133, 462, 0, 464, 0, 466, 0, 468, 0, 470, 0, 472, 0, 474, 0, 476, 0, 478, 0, 480, 0, 482, 0, 484, 134, 486, 135, 488, 136, 490, 0, 492, 0, 494, 0, 496, 0, 498, 0, 500, 0, 502, 0, 504, 0, 506, 0, 508, 0, 510, 0, 512, 0, 514, 137, 516, 138, 518, 139, 520, 140, 522, 0, 524, 0, 526, 0, 528, 0, 530, 0, 532, 0, 534, 0, 536, 0, 538, 0, 540, 0, 542, 0, 544, 141, 546, 0, 548, 142, 550, 143, 552, 144, 554, 0, 556, 0, 558, 0, 560, 0, 562, 0, 564, 0, 566, 0, 568, 0, 570, 0, 572, 0, 574, 0, 576, 0, 578, 0, 580, 0, 582, 0, 584, 0, 586, 0, 588, 0, 590, 0, 592, 145, 594, 146, 596, 147, 598, 0, 600, 148, 602, 149, 604, 150, 606, 151, 18, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 36, 2, 0, 10, 10, 13, 13, 3, 0, 9, 10, 13, 13, 32, 32, 2, 0, 67, 67, 99, 99, 2, 0, 72, 72, 104, 104, 2, 0, 65, 65, 97, 97, 2, 0, 78, 78, 110, 110, 2, 0, 71, 71, 103, 103, 2, 0, 69, 69, 101, 101, 2, 0, 80, 80, 112, 112, 2, 0, 79, 79, 111, 111, 2, 0, 73, 73, 105, 105, 2, 0, 84, 84, 116, 116, 2, 0, 82, 82, 114, 114, 2, 0, 88, 88, 120, 120, 2, 0, 76, 76, 108, 108, 2, 0, 77, 77, 109, 109, 2, 0, 68, 68, 100, 100, 2, 0, 83, 83, 115, 115, 2, 0, 86, 86, 118, 118, 2, 0, 75, 75, 107, 107, 2, 0, 87, 87, 119, 119, 2, 0, 70, 70, 102, 102, 2, 0, 85, 85, 117, 117, 6, 0, 9, 10, 13, 13, 32, 32, 47, 47, 91, 91, 93, 93, 12, 0, 9, 10, 13, 13, 32, 32, 34, 35, 40, 41, 44, 44, 47, 47, 58, 58, 60, 60, 62, 63, 92, 92, 124, 124, 1, 0, 48, 57, 2, 0, 65, 90, 97, 122, 8, 0, 34, 34, 78, 78, 82, 82, 84, 84, 92, 92, 110, 110, 114, 114, 116, 116, 4, 0, 10, 10, 13, 13, 34, 34, 92, 92, 2, 0, 43, 43, 45, 45, 1, 0, 96, 96, 2, 0, 66, 66, 98, 98, 2, 0, 89, 89, 121, 121, 12, 0, 9, 10, 13, 13, 32, 32, 34, 34, 40, 41, 44, 44, 47, 47, 58, 58, 61, 61, 91, 91, 93, 93, 124, 124, 2, 0, 42, 42, 47, 47, 2, 0, 74, 74, 106, 106, 2182, 0, 18, 1, 0, 0, 0, 0, 20, 1, 0, 0, 0, 0, 22, 1, 0, 0, 0, 0, 24, 1, 0, 0, 0, 0, 26, 1, 0, 0, 0, 0, 28, 1, 0, 0, 0, 0, 30, 1, 0, 0, 0, 0, 32, 1, 0, 0, 0, 0, 34, 1, 0, 0, 0, 0, 36, 1, 0, 0, 0, 0, 38, 1, 0, 0, 0, 0, 40, 1, 0, 0, 0, 0, 42, 1, 0, 0, 0, 0, 44, 1, 0, 0, 0, 0, 46, 1, 0, 0, 0, 0, 48, 1, 0, 0, 0, 0, 50, 1, 0, 0, 0, 0, 52, 1, 0, 0, 0, 0, 54, 1, 0, 0, 0, 0, 56, 1, 0, 0, 0, 0, 58, 1, 0, 0, 0, 0, 60, 1, 0, 0, 0, 0, 62, 1, 0, 0, 0, 0, 64, 1, 0, 0, 0, 0, 66, 1, 0, 0, 0, 0, 68, 1, 0, 0, 0, 0, 70, 1, 0, 0, 0, 0, 72, 1, 0, 0, 0, 0, 74, 1, 0, 0, 0, 0, 76, 1, 0, 0, 0, 0, 78, 1, 0, 0, 0, 0, 80, 1, 0, 0, 0, 0, 82, 1, 0, 0, 0, 0, 84, 1, 0, 0, 0, 0, 86, 1, 0, 0, 0, 0, 88, 1, 0, 0, 0, 1, 90, 1, 0, 0, 0, 1, 92, 1, 0, 0, 0, 1, 94, 1, 0, 0, 0, 1, 96, 1, 0, 0, 0, 1, 98, 1, 0, 0, 0, 1, 100, 1, 0, 0, 0, 1, 102, 1, 0, 0, 0, 1, 104, 1, 0, 0, 0, 1, 106, 1, 0, 0, 0, 1, 108, 1, 0, 0, 0, 1, 110, 1, 0, 0, 0, 1, 112, 1, 0, 0, 0, 1, 114, 1, 0, 0, 0, 2, 116, 1, 0, 0, 0, 2, 118, 1, 0, 0, 0, 2, 120, 1, 0, 0, 0, 2, 122, 1, 0, 0, 0, 2, 126, 1, 0, 0, 0, 2, 128, 1, 0, 0, 0, 2, 130, 1, 0, 0, 0, 2, 132, 1, 0, 0, 0, 2, 134, 1, 0, 0, 0, 2, 136, 1, 0, 0, 0, 3, 138, 1, 0, 0, 0, 3, 140, 1, 0, 0, 0, 3, 142, 1, 0, 0, 0, 3, 144, 1, 0, 0, 0, 3, 146, 1, 0, 0, 0, 3, 148, 1, 0, 0, 0, 3, 150, 1, 0, 0, 0, 3, 152, 1, 0, 0, 0, 3, 154, 1, 0, 0, 0, 3, 156, 1, 0, 0, 0, 3, 158, 1, 0, 0, 0, 3, 160, 1, 0, 0, 0, 3, 162, 1, 0, 0, 0, 3, 164, 1, 0, 0, 0, 3, 166, 1, 0, 0, 0, 3, 168, 1, 0, 0, 0, 3, 170, 1, 0, 0, 0, 4, 172, 1, 0, 0, 0, 4, 174, 1, 0, 0, 0, 4, 176, 1, 0, 0, 0, 4, 178, 1, 0, 0, 0, 4, 180, 1, 0, 0, 0, 5, 182, 1, 0, 0, 0, 5, 204, 1, 0, 0, 0, 5, 206, 1, 0, 0, 0, 5, 208, 1, 0, 0, 0, 5, 210, 1, 0, 0, 0, 5, 212, 1, 0, 0, 0, 5, 214, 1, 0, 0, 0, 5, 216, 1, 0, 0, 0, 5, 218, 1, 0, 0, 0, 5, 220, 1, 0, 0, 0, 5, 222, 1, 0, 0, 0, 5, 224, 1, 0, 0, 0, 5, 226, 1, 0, 0, 0, 5, 228, 1, 0, 0, 0, 5, 230, 1, 0, 0, 0, 5, 232, 1, 0, 0, 0, 5, 234, 1, 0, 0, 0, 5, 236, 1, 0, 0, 0, 5, 238, 1, 0, 0, 0, 5, 240, 1, 0, 0, 0, 5, 242, 1, 0, 0, 0, 5, 244, 1, 0, 0, 0, 5, 246, 1, 0, 0, 0, 5, 248, 1, 0, 0, 0, 5, 250, 1, 0, 0, 0, 5, 252, 1, 0, 0, 0, 5, 254, 1, 0, 0, 0, 5, 256, 1, 0, 0, 0, 5, 258, 1, 0, 0, 0, 5, 260, 1, 0, 0, 0, 5, 262, 1, 0, 0, 0, 5, 264, 1, 0, 0, 0, 5, 266, 1, 0, 0, 0, 5, 268, 1, 0, 0, 0, 5, 270, 1, 0, 0, 0, 5, 272, 1, 0, 0, 0, 5, 274, 1, 0, 0, 0, 5, 276, 1, 0, 0, 0, 5, 278, 1, 0, 0, 0, 5, 280, 1, 0, 0, 0, 5, 282, 1, 0, 0, 0, 5, 284, 1, 0, 0, 0, 5, 286, 1, 0, 0, 0, 5, 288, 1, 0, 0, 0, 5, 290, 1, 0, 0, 0, 5, 292, 1, 0, 0, 0, 5, 294, 1, 0, 0, 0, 5, 296, 1, 0, 0, 0, 5, 298, 1, 0, 0, 0, 5, 300, 1, 0, 0, 0, 5, 302, 1, 0, 0, 0, 5, 304, 1, 0, 0, 0, 5, 308, 1, 0, 0, 0, 5, 310, 1, 0, 0, 0, 5, 312, 1, 0, 0, 0, 5, 314, 1, 0, 0, 0, 6, 316, 1, 0, 0, 0, 6, 318, 1, 0, 0, 0, 6, 320, 1, 0, 0, 0, 6, 322, 1, 0, 0, 0, 6, 324, 1, 0, 0, 0, 6, 326, 1, 0, 0, 0, 6, 328, 1, 0, 0, 0, 6, 330, 1, 0, 0, 0, 6, 334, 1, 0, 0, 0, 6, 336, 1, 0, 0, 0, 6, 338, 1, 0, 0, 0, 6, 340, 1, 0, 0, 0, 6, 342, 1, 0, 0, 0, 6, 344, 1, 0, 0, 0, 7, 346, 1, 0, 0, 0, 7, 348, 1, 0, 0, 0, 7, 350, 1, 0, 0, 0, 7, 352, 1, 0, 0, 0, 7, 354, 1, 0, 0, 0, 7, 356, 1, 0, 0, 0, 8, 358, 1, 0, 0, 0, 8, 360, 1, 0, 0, 0, 8, 362, 1, 0, 0, 0, 8, 364, 1, 0, 0, 0, 8, 366, 1, 0, 0, 0, 8, 368, 1, 0, 0, 0, 8, 370, 1, 0, 0, 0, 8, 372, 1, 0, 0, 0, 8, 374, 1, 0, 0, 0, 8, 376, 1, 0, 0, 0, 8, 378, 1, 0, 0, 0, 8, 380, 1, 0, 0, 0, 8, 382, 1, 0, 0, 0, 8, 384, 1, 0, 0, 0, 8, 386, 1, 0, 0, 0, 8, 388, 1, 0, 0, 0, 8, 390, 1, 0, 0, 0, 8, 392, 1, 0, 0, 0, 9, 394, 1, 0, 0, 0, 9, 396, 1, 0, 0, 0, 9, 398, 1, 0, 0, 0, 9, 400, 1, 0, 0, 0, 10, 402, 1, 0, 0, 0, 10, 404, 1, 0, 0, 0, 10, 406, 1, 0, 0, 0, 10, 408, 1, 0, 0, 0, 10, 410, 1, 0, 0, 0, 10, 412, 1, 0, 0, 0, 10, 414, 1, 0, 0, 0, 10, 416, 1, 0, 0, 0, 10, 418, 1, 0, 0, 0, 10, 420, 1, 0, 0, 0, 10, 422, 1, 0, 0, 0, 11, 424, 1, 0, 0, 0, 11, 426, 1, 0, 0, 0, 11, 428, 1, 0, 0, 0, 11, 430, 1, 0, 0, 0, 11, 432, 1, 0, 0, 0, 11, 434, 1, 0, 0, 0, 11, 436, 1, 0, 0, 0, 11, 438, 1, 0, 0, 0, 11, 440, 1, 0, 0, 0, 11, 442, 1, 0, 0, 0, 11, 444, 1, 0, 0, 0, 12, 446, 1, 0, 0, 0, 12, 448, 1, 0, 0, 0, 12, 450, 1, 0, 0, 0, 12, 452, 1, 0, 0, 0, 12, 454, 1, 0, 0, 0, 12, 456, 1, 0, 0, 0, 12, 458, 1, 0, 0, 0, 12, 460, 1, 0, 0, 0, 13, 462, 1, 0, 0, 0, 13, 464, 1, 0, 0, 0, 13, 466, 1, 0, 0, 0, 13, 468, 1, 0, 0, 0, 13, 470, 1, 0, 0, 0, 13, 472, 1, 0, 0, 0, 13, 474, 1, 0, 0, 0, 13, 476, 1, 0, 0, 0, 13, 478, 1, 0, 0, 0, 13, 480, 1, 0, 0, 0, 13, 482, 1, 0, 0, 0, 13, 484, 1, 0, 0, 0, 13, 486, 1, 0, 0, 0, 13, 488, 1, 0, 0, 0, 14, 490, 1, 0, 0, 0, 14, 492, 1, 0, 0, 0, 14, 494, 1, 0, 0, 0, 14, 496, 1, 0, 0, 0, 14, 498, 1, 0, 0, 0, 14, 500, 1, 0, 0, 0, 14, 502, 1, 0, 0, 0, 14, 504, 1, 0, 0, 0, 14, 506, 1, 0, 0, 0, 14, 508, 1, 0, 0, 0, 14, 514, 1, 0, 0, 0, 14, 516, 1, 0, 0, 0, 14, 518, 1, 0, 0, 0, 14, 520, 1, 0, 0, 0, 15, 522, 1, 0, 0, 0, 15, 524, 1, 0, 0, 0, 15, 526, 1, 0, 0, 0, 15, 528, 1, 0, 0, 0, 15, 530, 1, 0, 0, 0, 15, 532, 1, 0, 0, 0, 15, 534, 1, 0, 0, 0, 15, 536, 1, 0, 0, 0, 15, 538, 1, 0, 0, 0, 15, 540, 1, 0, 0, 0, 15, 542, 1, 0, 0, 0, 15, 544, 1, 0, 0, 0, 15, 546, 1, 0, 0, 0, 15, 548, 1, 0, 0, 0, 15, 550, 1, 0, 0, 0, 15, 552, 1, 0, 0, 0, 16, 554, 1, 0, 0, 0, 16, 556, 1, 0, 0, 0, 16, 558, 1, 0, 0, 0, 16, 560, 1, 0, 0, 0, 16, 562, 1, 0, 0, 0, 16, 564, 1, 0, 0, 0, 16, 566, 1, 0, 0, 0, 16, 568, 1, 0, 0, 0, 16, 570, 1, 0, 0, 0, 16, 572, 1, 0, 0, 0, 16, 574, 1, 0, 0, 0, 16, 576, 1, 0, 0, 0, 16, 578, 1, 0, 0, 0, 16, 580, 1, 0, 0, 0, 16, 582, 1, 0, 0, 0, 16, 584, 1, 0, 0, 0, 16, 586, 1, 0, 0, 0, 16, 588, 1, 0, 0, 0, 16, 590, 1, 0, 0, 0, 16, 592, 1, 0, 0, 0, 16, 594, 1, 0, 0, 0, 16, 596, 1, 0, 0, 0, 17, 598, 1, 0, 0, 0, 17, 600, 1, 0, 0, 0, 17, 602, 1, 0, 0, 0, 17, 604, 1, 0, 0, 0, 17, 606, 1, 0, 0, 0, 18, 608, 1, 0, 0, 0, 20, 625, 1, 0, 0, 0, 22, 641, 1, 0, 0, 0, 24, 647, 1, 0, 0, 0, 26, 662, 1, 0, 0, 0, 28, 671, 1, 0, 0, 0, 30, 682, 1, 0, 0, 0, 32, 695, 1, 0, 0, 0, 34, 705, 1, 0, 0, 0, 36, 712, 1, 0, 0, 0, 38, 719, 1, 0, 0, 0, 40, 727, 1, 0, 0, 0, 42, 736, 1, 0, 0, 0, 44, 742, 1, 0, 0, 0, 46, 751, 1, 0, 0, 0, 48, 758, 1, 0, 0, 0, 50, 766, 1, 0, 0, 0, 52, 774, 1, 0, 0, 0, 54, 781, 1, 0, 0, 0, 56, 786, 1, 0, 0, 0, 58, 793, 1, 0, 0, 0, 60, 800, 1, 0, 0, 0, 62, 809, 1, 0, 0, 0, 64, 823, 1, 0, 0, 0, 66, 832, 1, 0, 0, 0, 68, 840, 1, 0, 0, 0, 70, 848, 1, 0, 0, 0, 72, 857, 1, 0, 0, 0, 74, 869, 1, 0, 0, 0, 76, 881, 1, 0, 0, 0, 78, 888, 1, 0, 0, 0, 80, 895, 1, 0, 0, 0, 82, 907, 1, 0, 0, 0, 84, 916, 1, 0, 0, 0, 86, 922, 1, 0, 0, 0, 88, 930, 1, 0, 0, 0, 90, 936, 1, 0, 0, 0, 92, 941, 1, 0, 0, 0, 94, 947, 1, 0, 0, 0, 96, 951, 1, 0, 0, 0, 98, 955, 1, 0, 0, 0, 100, 959, 1, 0, 0, 0, 102, 963, 1, 0, 0, 0, 104, 967, 1, 0, 0, 0, 106, 971, 1, 0, 0, 0, 108, 975, 1, 0, 0, 0, 110, 979, 1, 0, 0, 0, 112, 983, 1, 0, 0, 0, 114, 987, 1, 0, 0, 0, 116, 991, 1, 0, 0, 0, 118, 996, 1, 0, 0, 0, 120, 1002, 1, 0, 0, 0, 122, 1007, 1, 0, 0, 0, 124, 1012, 1, 0, 0, 0, 126, 1021, 1, 0, 0, 0, 128, 1028, 1, 0, 0, 0, 130, 1032, 1, 0, 0, 0, 132, 1036, 1, 0, 0, 0, 134, 1040, 1, 0, 0, 0, 136, 1044, 1, 0, 0, 0, 138, 1048, 1, 0, 0, 0, 140, 1054, 1, 0, 0, 0, 142, 1061, 1, 0, 0, 0, 144, 1065, 1, 0, 0, 0, 146, 1069, 1, 0, 0, 0, 148, 1073, 1, 0, 0, 0, 150, 1077, 1, 0, 0, 0, 152, 1081, 1, 0, 0, 0, 154, 1085, 1, 0, 0, 0, 156, 1089, 1, 0, 0, 0, 158, 1093, 1, 0, 0, 0, 160, 1097, 1, 0, 0, 0, 162, 1101, 1, 0, 0, 0, 164, 1105, 1, 0, 0, 0, 166, 1109, 1, 0, 0, 0, 168, 1113, 1, 0, 0, 0, 170, 1117, 1, 0, 0, 0, 172, 1121, 1, 0, 0, 0, 174, 1126, 1, 0, 0, 0, 176, 1131, 1, 0, 0, 0, 178, 1135, 1, 0, 0, 0, 180, 1139, 1, 0, 0, 0, 182, 1143, 1, 0, 0, 0, 184, 1147, 1, 0, 0, 0, 186, 1149, 1, 0, 0, 0, 188, 1151, 1, 0, 0, 0, 190, 1154, 1, 0, 0, 0, 192, 1156, 1, 0, 0, 0, 194, 1165, 1, 0, 0, 0, 196, 1167, 1, 0, 0, 0, 198, 1172, 1, 0, 0, 0, 200, 1174, 1, 0, 0, 0, 202, 1179, 1, 0, 0, 0, 204, 1210, 1, 0, 0, 0, 206, 1213, 1, 0, 0, 0, 208, 1259, 1, 0, 0, 0, 210, 1261, 1, 0, 0, 0, 212, 1265, 1, 0, 0, 0, 214, 1269, 1, 0, 0, 0, 216, 1271, 1, 0, 0, 0, 218, 1274, 1, 0, 0, 0, 220, 1277, 1, 0, 0, 0, 222, 1279, 1, 0, 0, 0, 224, 1281, 1, 0, 0, 0, 226, 1283, 1, 0, 0, 0, 228, 1288, 1, 0, 0, 0, 230, 1290, 1, 0, 0, 0, 232, 1296, 1, 0, 0, 0, 234, 1302, 1, 0, 0, 0, 236, 1305, 1, 0, 0, 0, 238, 1308, 1, 0, 0, 0, 240, 1313, 1, 0, 0, 0, 242, 1318, 1, 0, 0, 0, 244, 1322, 1, 0, 0, 0, 246, 1327, 1, 0, 0, 0, 248, 1333, 1, 0, 0, 0, 250, 1336, 1, 0, 0, 0, 252, 1339, 1, 0, 0, 0, 254, 1341, 1, 0, 0, 0, 256, 1347, 1, 0, 0, 0, 258, 1352, 1, 0, 0, 0, 260, 1357, 1, 0, 0, 0, 262, 1360, 1, 0, 0, 0, 264, 1363, 1, 0, 0, 0, 266, 1366, 1, 0, 0, 0, 268, 1368, 1, 0, 0, 0, 270, 1371, 1, 0, 0, 0, 272, 1373, 1, 0, 0, 0, 274, 1376, 1, 0, 0, 0, 276, 1378, 1, 0, 0, 0, 278, 1380, 1, 0, 0, 0, 280, 1382, 1, 0, 0, 0, 282, 1384, 1, 0, 0, 0, 284, 1386, 1, 0, 0, 0, 286, 1388, 1, 0, 0, 0, 288, 1390, 1, 0, 0, 0, 290, 1393, 1, 0, 0, 0, 292, 1414, 1, 0, 0, 0, 294, 1433, 1, 0, 0, 0, 296, 1435, 1, 0, 0, 0, 298, 1440, 1, 0, 0, 0, 300, 1445, 1, 0, 0, 0, 302, 1450, 1, 0, 0, 0, 304, 1471, 1, 0, 0, 0, 306, 1473, 1, 0, 0, 0, 308, 1481, 1, 0, 0, 0, 310, 1483, 1, 0, 0, 0, 312, 1487, 1, 0, 0, 0, 314, 1491, 1, 0, 0, 0, 316, 1495, 1, 0, 0, 0, 318, 1500, 1, 0, 0, 0, 320, 1504, 1, 0, 0, 0, 322, 1508, 1, 0, 0, 0, 324, 1512, 1, 0, 0, 0, 326, 1516, 1, 0, 0, 0, 328, 1525, 1, 0, 0, 0, 330, 1531, 1, 0, 0, 0, 332, 1539, 1, 0, 0, 0, 334, 1542, 1, 0, 0, 0, 336, 1546, 1, 0, 0, 0, 338, 1550, 1, 0, 0, 0, 340, 1554, 1, 0, 0, 0, 342, 1558, 1, 0, 0, 0, 344, 1562, 1, 0, 0, 0, 346, 1566, 1, 0, 0, 0, 348, 1571, 1, 0, 0, 0, 350, 1577, 1, 0, 0, 0, 352, 1582, 1, 0, 0, 0, 354, 1586, 1, 0, 0, 0, 356, 1590, 1, 0, 0, 0, 358, 1594, 1, 0, 0, 0, 360, 1599, 1, 0, 0, 0, 362, 1605, 1, 0, 0, 0, 364, 1611, 1, 0, 0, 0, 366, 1617, 1, 0, 0, 0, 368, 1621, 1, 0, 0, 0, 370, 1627, 1, 0, 0, 0, 372, 1631, 1, 0, 0, 0, 374, 1635, 1, 0, 0, 0, 376, 1639, 1, 0, 0, 0, 378, 1643, 1, 0, 0, 0, 380, 1647, 1, 0, 0, 0, 382, 1651, 1, 0, 0, 0, 384, 1655, 1, 0, 0, 0, 386, 1659, 1, 0, 0, 0, 388, 1663, 1, 0, 0, 0, 390, 1667, 1, 0, 0, 0, 392, 1671, 1, 0, 0, 0, 394, 1675, 1, 0, 0, 0, 396, 1684, 1, 0, 0, 0, 398, 1688, 1, 0, 0, 0, 400, 1692, 1, 0, 0, 0, 402, 1696, 1, 0, 0, 0, 404, 1701, 1, 0, 0, 0, 406, 1706, 1, 0, 0, 0, 408, 1710, 1, 0, 0, 0, 410, 1716, 1, 0, 0, 0, 412, 1725, 1, 0, 0, 0, 414, 1729, 1, 0, 0, 0, 416, 1733, 1, 0, 0, 0, 418, 1737, 1, 0, 0, 0, 420, 1741, 1, 0, 0, 0, 422, 1745, 1, 0, 0, 0, 424, 1749, 1, 0, 0, 0, 426, 1754, 1, 0, 0, 0, 428, 1760, 1, 0, 0, 0, 430, 1764, 1, 0, 0, 0, 432, 1768, 1, 0, 0, 0, 434, 1772, 1, 0, 0, 0, 436, 1777, 1, 0, 0, 0, 438, 1781, 1, 0, 0, 0, 440, 1785, 1, 0, 0, 0, 442, 1789, 1, 0, 0, 0, 444, 1793, 1, 0, 0, 0, 446, 1797, 1, 0, 0, 0, 448, 1803, 1, 0, 0, 0, 450, 1810, 1, 0, 0, 0, 452, 1814, 1, 0, 0, 0, 454, 1818, 1, 0, 0, 0, 456, 1822, 1, 0, 0, 0, 458, 1826, 1, 0, 0, 0, 460, 1830, 1, 0, 0, 0, 462, 1834, 1, 0, 0, 0, 464, 1839, 1, 0, 0, 0, 466, 1845, 1, 0, 0, 0, 468, 1849, 1, 0, 0, 0, 470, 1853, 1, 0, 0, 0, 472, 1857, 1, 0, 0, 0, 474, 1861, 1, 0, 0, 0, 476, 1865, 1, 0, 0, 0, 478, 1869, 1, 0, 0, 0, 480, 1873, 1, 0, 0, 0, 482, 1877, 1, 0, 0, 0, 484, 1881, 1, 0, 0, 0, 486, 1885, 1, 0, 0, 0, 488, 1889, 1, 0, 0, 0, 490, 1893, 1, 0, 0, 0, 492, 1898, 1, 0, 0, 0, 494, 1904, 1, 0, 0, 0, 496, 1908, 1, 0, 0, 0, 498, 1912, 1, 0, 0, 0, 500, 1916, 1, 0, 0, 0, 502, 1920, 1, 0, 0, 0, 504, 1924, 1, 0, 0, 0, 506, 1928, 1, 0, 0, 0, 508, 1932, 1, 0, 0, 0, 510, 1940, 1, 0, 0, 0, 512, 1961, 1, 0, 0, 0, 514, 1965, 1, 0, 0, 0, 516, 1969, 1, 0, 0, 0, 518, 1973, 1, 0, 0, 0, 520, 1977, 1, 0, 0, 0, 522, 1981, 1, 0, 0, 0, 524, 1986, 1, 0, 0, 0, 526, 1992, 1, 0, 0, 0, 528, 1996, 1, 0, 0, 0, 530, 2000, 1, 0, 0, 0, 532, 2004, 1, 0, 0, 0, 534, 2008, 1, 0, 0, 0, 536, 2012, 1, 0, 0, 0, 538, 2016, 1, 0, 0, 0, 540, 2020, 1, 0, 0, 0, 542, 2024, 1, 0, 0, 0, 544, 2028, 1, 0, 0, 0, 546, 2031, 1, 0, 0, 0, 548, 2035, 1, 0, 0, 0, 550, 2039, 1, 0, 0, 0, 552, 2043, 1, 0, 0, 0, 554, 2047, 1, 0, 0, 0, 556, 2051, 1, 0, 0, 0, 558, 2055, 1, 0, 0, 0, 560, 2059, 1, 0, 0, 0, 562, 2064, 1, 0, 0, 0, 564, 2068, 1, 0, 0, 0, 566, 2072, 1, 0, 0, 0, 568, 2076, 1, 0, 0, 0, 570, 2080, 1, 0, 0, 0, 572, 2084, 1, 0, 0, 0, 574, 2088, 1, 0, 0, 0, 576, 2092, 1, 0, 0, 0, 578, 2096, 1, 0, 0, 0, 580, 2100, 1, 0, 0, 0, 582, 2104, 1, 0, 0, 0, 584, 2108, 1, 0, 0, 0, 586, 2112, 1, 0, 0, 0, 588, 2116, 1, 0, 0, 0, 590, 2120, 1, 0, 0, 0, 592, 2124, 1, 0, 0, 0, 594, 2128, 1, 0, 0, 0, 596, 2132, 1, 0, 0, 0, 598, 2136, 1, 0, 0, 0, 600, 2141, 1, 0, 0, 0, 602, 2146, 1, 0, 0, 0, 604, 2150, 1, 0, 0, 0, 606, 2154, 1, 0, 0, 0, 608, 609, 5, 47, 0, 0, 609, 610, 5, 47, 0, 0, 610, 614, 1, 0, 0, 0, 611, 613, 8, 0, 0, 0, 612, 611, 1, 0, 0, 0, 613, 616, 1, 0, 0, 0, 614, 612, 1, 0, 0, 0, 614, 615, 1, 0, 0, 0, 615, 618, 1, 0, 0, 0, 616, 614, 1, 0, 0, 0, 617, 619, 5, 13, 0, 0, 618, 617, 1, 0, 0, 0, 618, 619, 1, 0, 0, 0, 619, 621, 1, 0, 0, 0, 620, 622, 5, 10, 0, 0, 621, 620, 1, 0, 0, 0, 621, 622, 1, 0, 0, 0, 622, 623, 1, 0, 0, 0, 623, 624, 6, 0, 0, 0, 624, 19, 1, 0, 0, 0, 625, 626, 5, 47, 0, 0, 626, 627, 5, 42, 0, 0, 627, 632, 1, 0, 0, 0, 628, 631, 3, 20, 1, 0, 629, 631, 9, 0, 0, 0, 630, 628, 1, 0, 0, 0, 630, 629, 1, 0, 0, 0, 631, 634, 1, 0, 0, 0, 632, 633, 1, 0, 0, 0, 632, 630, 1, 0, 0, 0, 633, 635, 1, 0, 0, 0, 634, 632, 1, 0, 0, 0, 635, 636, 5, 42, 0, 0, 636, 637, 5, 47, 0, 0, 637, 638, 1, 0, 0, 0, 638, 639, 6, 1, 0, 0, 639, 21, 1, 0, 0, 0, 640, 642, 7, 1, 0, 0, 641, 640, 1, 0, 0, 0, 642, 643, 1, 0, 0, 0, 643, 641, 1, 0, 0, 0, 643, 644, 1, 0, 0, 0, 644, 645, 1, 0, 0, 0, 645, 646, 6, 2, 0, 0, 646, 23, 1, 0, 0, 0, 647, 648, 7, 2, 0, 0, 648, 649, 7, 3, 0, 0, 649, 650, 7, 4, 0, 0, 650, 651, 7, 5, 0, 0, 651, 652, 7, 6, 0, 0, 652, 653, 7, 7, 0, 0, 653, 654, 5, 95, 0, 0, 654, 655, 7, 8, 0, 0, 655, 656, 7, 9, 0, 0, 656, 657, 7, 10, 0, 0, 657, 658, 7, 5, 0, 0, 658, 659, 7, 11, 0, 0, 659, 660, 1, 0, 0, 0, 660, 661, 6, 3, 1, 0, 661, 25, 1, 0, 0, 0, 662, 663, 7, 7, 0, 0, 663, 664, 7, 5, 0, 0, 664, 665, 7, 12, 0, 0, 665, 666, 7, 10, 0, 0, 666, 667, 7, 2, 0, 0, 667, 668, 7, 3, 0, 0, 668, 669, 1, 0, 0, 0, 669, 670, 6, 4, 2, 0, 670, 27, 1, 0, 0, 0, 671, 672, 4, 5, 0, 0, 672, 673, 7, 7, 0, 0, 673, 674, 7, 13, 0, 0, 674, 675, 7, 8, 0, 0, 675, 676, 7, 14, 0, 0, 676, 677, 7, 4, 0, 0, 677, 678, 7, 10, 0, 0, 678, 679, 7, 5, 0, 0, 679, 680, 1, 0, 0, 0, 680, 681, 6, 5, 3, 0, 681, 29, 1, 0, 0, 0, 682, 683, 7, 2, 0, 0, 683, 684, 7, 9, 0, 0, 684, 685, 7, 15, 0, 0, 685, 686, 7, 8, 0, 0, 686, 687, 7, 14, 0, 0, 687, 688, 7, 7, 0, 0, 688, 689, 7, 11, 0, 0, 689, 690, 7, 10, 0, 0, 690, 691, 7, 9, 0, 0, 691, 692, 7, 5, 0, 0, 692, 693, 1, 0, 0, 0, 693, 694, 6, 6, 4, 0, 694, 31, 1, 0, 0, 0, 695, 696, 7, 16, 0, 0, 696, 697, 7, 10, 0, 0, 697, 698, 7, 17, 0, 0, 698, 699, 7, 17, 0, 0, 699, 700, 7, 7, 0, 0, 700, 701, 7, 2, 0, 0, 701, 702, 7, 11, 0, 0, 702, 703, 1, 0, 0, 0, 703, 704, 6, 7, 4, 0, 704, 33, 1, 0, 0, 0, 705, 706, 7, 7, 0, 0, 706, 707, 7, 18, 0, 0, 707, 708, 7, 4, 0, 0, 708, 709, 7, 14, 0, 0, 709, 710, 1, 0, 0, 0, 710, 711, 6, 8, 4, 0, 711, 35, 1, 0, 0, 0, 712, 713, 7, 6, 0, 0, 713, 714, 7, 12, 0, 0, 714, 715, 7, 9, 0, 0, 715, 716, 7, 19, 0, 0, 716, 717, 1, 0, 0, 0, 717, 718, 6, 9, 4, 0, 718, 37, 1, 0, 0, 0, 719, 720, 7, 14, 0, 0, 720, 721, 7, 10, 0, 0, 721, 722, 7, 15, 0, 0, 722, 723, 7, 10, 0, 0, 723, 724, 7, 11, 0, 0, 724, 725, 1, 0, 0, 0, 725, 726, 6, 10, 4, 0, 726, 39, 1, 0, 0, 0, 727, 728, 7, 12, 0, 0, 728, 729, 7, 7, 0, 0, 729, 730, 7, 12, 0, 0, 730, 731, 7, 4, 0, 0, 731, 732, 7, 5, 0, 0, 732, 733, 7, 19, 0, 0, 733, 734, 1, 0, 0, 0, 734, 735, 6, 11, 4, 0, 735, 41, 1, 0, 0, 0, 736, 737, 7, 12, 0, 0, 737, 738, 7, 9, 0, 0, 738, 739, 7, 20, 0, 0, 739, 740, 1, 0, 0, 0, 740, 741, 6, 12, 4, 0, 741, 43, 1, 0, 0, 0, 742, 743, 7, 17, 0, 0, 743, 744, 7, 4, 0, 0, 744, 745, 7, 15, 0, 0, 745, 746, 7, 8, 0, 0, 746, 747, 7, 14, 0, 0, 747, 748, 7, 7, 0, 0, 748, 749, 1, 0, 0, 0, 749, 750, 6, 13, 4, 0, 750, 45, 1, 0, 0, 0, 751, 752, 7, 17, 0, 0, 752, 753, 7, 9, 0, 0, 753, 754, 7, 12, 0, 0, 754, 755, 7, 11, 0, 0, 755, 756, 1, 0, 0, 0, 756, 757, 6, 14, 4, 0, 757, 47, 1, 0, 0, 0, 758, 759, 7, 17, 0, 0, 759, 760, 7, 11, 0, 0, 760, 761, 7, 4, 0, 0, 761, 762, 7, 11, 0, 0, 762, 763, 7, 17, 0, 0, 763, 764, 1, 0, 0, 0, 764, 765, 6, 15, 4, 0, 765, 49, 1, 0, 0, 0, 766, 767, 7, 20, 0, 0, 767, 768, 7, 3, 0, 0, 768, 769, 7, 7, 0, 0, 769, 770, 7, 12, 0, 0, 770, 771, 7, 7, 0, 0, 771, 772, 1, 0, 0, 0, 772, 773, 6, 16, 4, 0, 773, 51, 1, 0, 0, 0, 774, 775, 7, 21, 0, 0, 775, 776, 7, 12, 0, 0, 776, 777, 7, 9, 0, 0, 777, 778, 7, 15, 0, 0, 778, 779, 1, 0, 0, 0, 779, 780, 6, 17, 5, 0, 780, 53, 1, 0, 0, 0, 781, 782, 7, 11, 0, 0, 782, 783, 7, 17, 0, 0, 783, 784, 1, 0, 0, 0, 784, 785, 6, 18, 5, 0, 785, 55, 1, 0, 0, 0, 786, 787, 7, 21, 0, 0, 787, 788, 7, 9, 0, 0, 788, 789, 7, 12, 0, 0, 789, 790, 7, 19, 0, 0, 790, 791, 1, 0, 0, 0, 791, 792, 6, 19, 6, 0, 792, 57, 1, 0, 0, 0, 793, 794, 7, 21, 0, 0, 794, 795, 7, 22, 0, 0, 795, 796, 7, 17, 0, 0, 796, 797, 7, 7, 0, 0, 797, 798, 1, 0, 0, 0, 798, 799, 6, 20, 7, 0, 799, 59, 1, 0, 0, 0, 800, 801, 7, 10, 0, 0, 801, 802, 7, 5, 0, 0, 802, 803, 7, 14, 0, 0, 803, 804, 7, 10, 0, 0, 804, 805, 7, 5, 0, 0, 805, 806, 7, 7, 0, 0, 806, 807, 1, 0, 0, 0, 807, 808, 6, 21, 8, 0, 808, 61, 1, 0, 0, 0, 809, 810, 7, 10, 0, 0, 810, 811, 7, 5, 0, 0, 811, 812, 7, 14, 0, 0, 812, 813, 7, 10, 0, 0, 813, 814, 7, 5, 0, 0, 814, 815, 7, 7, 0, 0, 815, 816, 7, 17, 0, 0, 816, 817, 7, 11, 0, 0, 817, 818, 7, 4, 0, 0, 818, 819, 7, 11, 0, 0, 819, 820, 7, 17, 0, 0, 820, 821, 1, 0, 0, 0, 821, 822, 6, 22, 4, 0, 822, 63, 1, 0, 0, 0, 823, 824, 7, 14, 0, 0, 824, 825, 7, 9, 0, 0, 825, 826, 7, 9, 0, 0, 826, 827, 7, 19, 0, 0, 827, 828, 7, 22, 0, 0, 828, 829, 7, 8, 0, 0, 829, 830, 1, 0, 0, 0, 830, 831, 6, 23, 9, 0, 831, 65, 1, 0, 0, 0, 832, 833, 4, 24, 1, 0, 833, 834, 7, 21, 0, 0, 834, 835, 7, 22, 0, 0, 835, 836, 7, 14, 0, 0, 836, 837, 7, 14, 0, 0, 837, 838, 1, 0, 0, 0, 838, 839, 6, 24, 9, 0, 839, 67, 1, 0, 0, 0, 840, 841, 4, 25, 2, 0, 841, 842, 7, 14, 0, 0, 842, 843, 7, 7, 0, 0, 843, 844, 7, 21, 0, 0, 844, 845, 7, 11, 0, 0, 845, 846, 1, 0, 0, 0, 846, 847, 6, 25, 9, 0, 847, 69, 1, 0, 0, 0, 848, 849, 4, 26, 3, 0, 849, 850, 7, 12, 0, 0, 850, 851, 7, 10, 0, 0, 851, 852, 7, 6, 0, 0, 852, 853, 7, 3, 0, 0, 853, 854, 7, 11, 0, 0, 854, 855, 1, 0, 0, 0, 855, 856, 6, 26, 9, 0, 856, 71, 1, 0, 0, 0, 857, 858, 4, 27, 4, 0, 858, 859, 7, 14, 0, 0, 859, 860, 7, 9, 0, 0, 860, 861, 7, 9, 0, 0, 861, 862, 7, 19, 0, 0, 862, 863, 7, 22, 0, 0, 863, 864, 7, 8, 0, 0, 864, 865, 5, 95, 0, 0, 865, 866, 5, 128020, 0, 0, 866, 867, 1, 0, 0, 0, 867, 868, 6, 27, 10, 0, 868, 73, 1, 0, 0, 0, 869, 870, 7, 15, 0, 0, 870, 871, 7, 18, 0, 0, 871, 872, 5, 95, 0, 0, 872, 873, 7, 7, 0, 0, 873, 874, 7, 13, 0, 0, 874, 875, 7, 8, 0, 0, 875, 876, 7, 4, 0, 0, 876, 877, 7, 5, 0, 0, 877, 878, 7, 16, 0, 0, 878, 879, 1, 0, 0, 0, 879, 880, 6, 28, 11, 0, 880, 75, 1, 0, 0, 0, 881, 882, 7, 16, 0, 0, 882, 883, 7, 12, 0, 0, 883, 884, 7, 9, 0, 0, 884, 885, 7, 8, 0, 0, 885, 886, 1, 0, 0, 0, 886, 887, 6, 29, 12, 0, 887, 77, 1, 0, 0, 0, 888, 889, 7, 19, 0, 0, 889, 890, 7, 7, 0, 0, 890, 891, 7, 7, 0, 0, 891, 892, 7, 8, 0, 0, 892, 893, 1, 0, 0, 0, 893, 894, 6, 30, 12, 0, 894, 79, 1, 0, 0, 0, 895, 896, 4, 31, 5, 0, 896, 897, 7, 10, 0, 0, 897, 898, 7, 5, 0, 0, 898, 899, 7, 17, 0, 0, 899, 900, 7, 10, 0, 0, 900, 901, 7, 17, 0, 0, 901, 902, 7, 11, 0, 0, 902, 903, 5, 95, 0, 0, 903, 904, 5, 128020, 0, 0, 904, 905, 1, 0, 0, 0, 905, 906, 6, 31, 12, 0, 906, 81, 1, 0, 0, 0, 907, 908, 7, 12, 0, 0, 908, 909, 7, 7, 0, 0, 909, 910, 7, 5, 0, 0, 910, 911, 7, 4, 0, 0, 911, 912, 7, 15, 0, 0, 912, 913, 7, 7, 0, 0, 913, 914, 1, 0, 0, 0, 914, 915, 6, 32, 13, 0, 915, 83, 1, 0, 0, 0, 916, 917, 7, 17, 0, 0, 917, 918, 7, 7, 0, 0, 918, 919, 7, 11, 0, 0, 919, 920, 1, 0, 0, 0, 920, 921, 6, 33, 14, 0, 921, 85, 1, 0, 0, 0, 922, 923, 7, 17, 0, 0, 923, 924, 7, 3, 0, 0, 924, 925, 7, 9, 0, 0, 925, 926, 7, 20, 0, 0, 926, 927, 1, 0, 0, 0, 927, 928, 6, 34, 15, 0, 928, 87, 1, 0, 0, 0, 929, 931, 8, 23, 0, 0, 930, 929, 1, 0, 0, 0, 931, 932, 1, 0, 0, 0, 932, 930, 1, 0, 0, 0, 932, 933, 1, 0, 0, 0, 933, 934, 1, 0, 0, 0, 934, 935, 6, 35, 4, 0, 935, 89, 1, 0, 0, 0, 936, 937, 3, 182, 82, 0, 937, 938, 1, 0, 0, 0, 938, 939, 6, 36, 16, 0, 939, 940, 6, 36, 17, 0, 940, 91, 1, 0, 0, 0, 941, 942, 3, 302, 142, 0, 942, 943, 1, 0, 0, 0, 943, 944, 6, 37, 18, 0, 944, 945, 6, 37, 17, 0, 945, 946, 6, 37, 17, 0, 946, 93, 1, 0, 0, 0, 947, 948, 3, 248, 115, 0, 948, 949, 1, 0, 0, 0, 949, 950, 6, 38, 19, 0, 950, 95, 1, 0, 0, 0, 951, 952, 3, 544, 263, 0, 952, 953, 1, 0, 0, 0, 953, 954, 6, 39, 20, 0, 954, 97, 1, 0, 0, 0, 955, 956, 3, 228, 105, 0, 956, 957, 1, 0, 0, 0, 957, 958, 6, 40, 21, 0, 958, 99, 1, 0, 0, 0, 959, 960, 3, 224, 103, 0, 960, 961, 1, 0, 0, 0, 961, 962, 6, 41, 22, 0, 962, 101, 1, 0, 0, 0, 963, 964, 3, 296, 139, 0, 964, 965, 1, 0, 0, 0, 965, 966, 6, 42, 23, 0, 966, 103, 1, 0, 0, 0, 967, 968, 3, 298, 140, 0, 968, 969, 1, 0, 0, 0, 969, 970, 6, 43, 24, 0, 970, 105, 1, 0, 0, 0, 971, 972, 3, 308, 145, 0, 972, 973, 1, 0, 0, 0, 973, 974, 6, 44, 25, 0, 974, 107, 1, 0, 0, 0, 975, 976, 3, 304, 143, 0, 976, 977, 1, 0, 0, 0, 977, 978, 6, 45, 26, 0, 978, 109, 1, 0, 0, 0, 979, 980, 3, 18, 0, 0, 980, 981, 1, 0, 0, 0, 981, 982, 6, 46, 0, 0, 982, 111, 1, 0, 0, 0, 983, 984, 3, 20, 1, 0, 984, 985, 1, 0, 0, 0, 985, 986, 6, 47, 0, 0, 986, 113, 1, 0, 0, 0, 987, 988, 3, 22, 2, 0, 988, 989, 1, 0, 0, 0, 989, 990, 6, 48, 0, 0, 990, 115, 1, 0, 0, 0, 991, 992, 3, 182, 82, 0, 992, 993, 1, 0, 0, 0, 993, 994, 6, 49, 16, 0, 994, 995, 6, 49, 17, 0, 995, 117, 1, 0, 0, 0, 996, 997, 3, 302, 142, 0, 997, 998, 1, 0, 0, 0, 998, 999, 6, 50, 18, 0, 999, 1000, 6, 50, 17, 0, 1000, 1001, 6, 50, 17, 0, 1001, 119, 1, 0, 0, 0, 1002, 1003, 3, 248, 115, 0, 1003, 1004, 1, 0, 0, 0, 1004, 1005, 6, 51, 19, 0, 1005, 1006, 6, 51, 27, 0, 1006, 121, 1, 0, 0, 0, 1007, 1008, 3, 258, 120, 0, 1008, 1009, 1, 0, 0, 0, 1009, 1010, 6, 52, 28, 0, 1010, 1011, 6, 52, 27, 0, 1011, 123, 1, 0, 0, 0, 1012, 1013, 8, 24, 0, 0, 1013, 125, 1, 0, 0, 0, 1014, 1016, 3, 124, 53, 0, 1015, 1014, 1, 0, 0, 0, 1016, 1017, 1, 0, 0, 0, 1017, 1015, 1, 0, 0, 0, 1017, 1018, 1, 0, 0, 0, 1018, 1019, 1, 0, 0, 0, 1019, 1020, 3, 220, 101, 0, 1020, 1022, 1, 0, 0, 0, 1021, 1015, 1, 0, 0, 0, 1021, 1022, 1, 0, 0, 0, 1022, 1024, 1, 0, 0, 0, 1023, 1025, 3, 124, 53, 0, 1024, 1023, 1, 0, 0, 0, 1025, 1026, 1, 0, 0, 0, 1026, 1024, 1, 0, 0, 0, 1026, 1027, 1, 0, 0, 0, 1027, 127, 1, 0, 0, 0, 1028, 1029, 3, 126, 54, 0, 1029, 1030, 1, 0, 0, 0, 1030, 1031, 6, 55, 29, 0, 1031, 129, 1, 0, 0, 0, 1032, 1033, 3, 204, 93, 0, 1033, 1034, 1, 0, 0, 0, 1034, 1035, 6, 56, 30, 0, 1035, 131, 1, 0, 0, 0, 1036, 1037, 3, 18, 0, 0, 1037, 1038, 1, 0, 0, 0, 1038, 1039, 6, 57, 0, 0, 1039, 133, 1, 0, 0, 0, 1040, 1041, 3, 20, 1, 0, 1041, 1042, 1, 0, 0, 0, 1042, 1043, 6, 58, 0, 0, 1043, 135, 1, 0, 0, 0, 1044, 1045, 3, 22, 2, 0, 1045, 1046, 1, 0, 0, 0, 1046, 1047, 6, 59, 0, 0, 1047, 137, 1, 0, 0, 0, 1048, 1049, 3, 182, 82, 0, 1049, 1050, 1, 0, 0, 0, 1050, 1051, 6, 60, 16, 0, 1051, 1052, 6, 60, 17, 0, 1052, 1053, 6, 60, 17, 0, 1053, 139, 1, 0, 0, 0, 1054, 1055, 3, 302, 142, 0, 1055, 1056, 1, 0, 0, 0, 1056, 1057, 6, 61, 18, 0, 1057, 1058, 6, 61, 17, 0, 1058, 1059, 6, 61, 17, 0, 1059, 1060, 6, 61, 17, 0, 1060, 141, 1, 0, 0, 0, 1061, 1062, 3, 296, 139, 0, 1062, 1063, 1, 0, 0, 0, 1063, 1064, 6, 62, 23, 0, 1064, 143, 1, 0, 0, 0, 1065, 1066, 3, 298, 140, 0, 1066, 1067, 1, 0, 0, 0, 1067, 1068, 6, 63, 24, 0, 1068, 145, 1, 0, 0, 0, 1069, 1070, 3, 214, 98, 0, 1070, 1071, 1, 0, 0, 0, 1071, 1072, 6, 64, 31, 0, 1072, 147, 1, 0, 0, 0, 1073, 1074, 3, 224, 103, 0, 1074, 1075, 1, 0, 0, 0, 1075, 1076, 6, 65, 22, 0, 1076, 149, 1, 0, 0, 0, 1077, 1078, 3, 228, 105, 0, 1078, 1079, 1, 0, 0, 0, 1079, 1080, 6, 66, 21, 0, 1080, 151, 1, 0, 0, 0, 1081, 1082, 3, 258, 120, 0, 1082, 1083, 1, 0, 0, 0, 1083, 1084, 6, 67, 28, 0, 1084, 153, 1, 0, 0, 0, 1085, 1086, 3, 514, 248, 0, 1086, 1087, 1, 0, 0, 0, 1087, 1088, 6, 68, 32, 0, 1088, 155, 1, 0, 0, 0, 1089, 1090, 3, 308, 145, 0, 1090, 1091, 1, 0, 0, 0, 1091, 1092, 6, 69, 25, 0, 1092, 157, 1, 0, 0, 0, 1093, 1094, 3, 252, 117, 0, 1094, 1095, 1, 0, 0, 0, 1095, 1096, 6, 70, 33, 0, 1096, 159, 1, 0, 0, 0, 1097, 1098, 3, 292, 137, 0, 1098, 1099, 1, 0, 0, 0, 1099, 1100, 6, 71, 34, 0, 1100, 161, 1, 0, 0, 0, 1101, 1102, 3, 288, 135, 0, 1102, 1103, 1, 0, 0, 0, 1103, 1104, 6, 72, 35, 0, 1104, 163, 1, 0, 0, 0, 1105, 1106, 3, 294, 138, 0, 1106, 1107, 1, 0, 0, 0, 1107, 1108, 6, 73, 36, 0, 1108, 165, 1, 0, 0, 0, 1109, 1110, 3, 18, 0, 0, 1110, 1111, 1, 0, 0, 0, 1111, 1112, 6, 74, 0, 0, 1112, 167, 1, 0, 0, 0, 1113, 1114, 3, 20, 1, 0, 1114, 1115, 1, 0, 0, 0, 1115, 1116, 6, 75, 0, 0, 1116, 169, 1, 0, 0, 0, 1117, 1118, 3, 22, 2, 0, 1118, 1119, 1, 0, 0, 0, 1119, 1120, 6, 76, 0, 0, 1120, 171, 1, 0, 0, 0, 1121, 1122, 3, 300, 141, 0, 1122, 1123, 1, 0, 0, 0, 1123, 1124, 6, 77, 37, 0, 1124, 1125, 6, 77, 38, 0, 1125, 173, 1, 0, 0, 0, 1126, 1127, 3, 182, 82, 0, 1127, 1128, 1, 0, 0, 0, 1128, 1129, 6, 78, 16, 0, 1129, 1130, 6, 78, 17, 0, 1130, 175, 1, 0, 0, 0, 1131, 1132, 3, 22, 2, 0, 1132, 1133, 1, 0, 0, 0, 1133, 1134, 6, 79, 0, 0, 1134, 177, 1, 0, 0, 0, 1135, 1136, 3, 18, 0, 0, 1136, 1137, 1, 0, 0, 0, 1137, 1138, 6, 80, 0, 0, 1138, 179, 1, 0, 0, 0, 1139, 1140, 3, 20, 1, 0, 1140, 1141, 1, 0, 0, 0, 1141, 1142, 6, 81, 0, 0, 1142, 181, 1, 0, 0, 0, 1143, 1144, 5, 124, 0, 0, 1144, 1145, 1, 0, 0, 0, 1145, 1146, 6, 82, 17, 0, 1146, 183, 1, 0, 0, 0, 1147, 1148, 7, 25, 0, 0, 1148, 185, 1, 0, 0, 0, 1149, 1150, 7, 26, 0, 0, 1150, 187, 1, 0, 0, 0, 1151, 1152, 5, 92, 0, 0, 1152, 1153, 7, 27, 0, 0, 1153, 189, 1, 0, 0, 0, 1154, 1155, 8, 28, 0, 0, 1155, 191, 1, 0, 0, 0, 1156, 1158, 7, 7, 0, 0, 1157, 1159, 7, 29, 0, 0, 1158, 1157, 1, 0, 0, 0, 1158, 1159, 1, 0, 0, 0, 1159, 1161, 1, 0, 0, 0, 1160, 1162, 3, 184, 83, 0, 1161, 1160, 1, 0, 0, 0, 1162, 1163, 1, 0, 0, 0, 1163, 1161, 1, 0, 0, 0, 1163, 1164, 1, 0, 0, 0, 1164, 193, 1, 0, 0, 0, 1165, 1166, 5, 64, 0, 0, 1166, 195, 1, 0, 0, 0, 1167, 1168, 5, 96, 0, 0, 1168, 197, 1, 0, 0, 0, 1169, 1173, 8, 30, 0, 0, 1170, 1171, 5, 96, 0, 0, 1171, 1173, 5, 96, 0, 0, 1172, 1169, 1, 0, 0, 0, 1172, 1170, 1, 0, 0, 0, 1173, 199, 1, 0, 0, 0, 1174, 1175, 5, 95, 0, 0, 1175, 201, 1, 0, 0, 0, 1176, 1180, 3, 186, 84, 0, 1177, 1180, 3, 184, 83, 0, 1178, 1180, 3, 200, 91, 0, 1179, 1176, 1, 0, 0, 0, 1179, 1177, 1, 0, 0, 0, 1179, 1178, 1, 0, 0, 0, 1180, 203, 1, 0, 0, 0, 1181, 1186, 5, 34, 0, 0, 1182, 1185, 3, 188, 85, 0, 1183, 1185, 3, 190, 86, 0, 1184, 1182, 1, 0, 0, 0, 1184, 1183, 1, 0, 0, 0, 1185, 1188, 1, 0, 0, 0, 1186, 1184, 1, 0, 0, 0, 1186, 1187, 1, 0, 0, 0, 1187, 1189, 1, 0, 0, 0, 1188, 1186, 1, 0, 0, 0, 1189, 1211, 5, 34, 0, 0, 1190, 1191, 5, 34, 0, 0, 1191, 1192, 5, 34, 0, 0, 1192, 1193, 5, 34, 0, 0, 1193, 1197, 1, 0, 0, 0, 1194, 1196, 8, 0, 0, 0, 1195, 1194, 1, 0, 0, 0, 1196, 1199, 1, 0, 0, 0, 1197, 1198, 1, 0, 0, 0, 1197, 1195, 1, 0, 0, 0, 1198, 1200, 1, 0, 0, 0, 1199, 1197, 1, 0, 0, 0, 1200, 1201, 5, 34, 0, 0, 1201, 1202, 5, 34, 0, 0, 1202, 1203, 5, 34, 0, 0, 1203, 1205, 1, 0, 0, 0, 1204, 1206, 5, 34, 0, 0, 1205, 1204, 1, 0, 0, 0, 1205, 1206, 1, 0, 0, 0, 1206, 1208, 1, 0, 0, 0, 1207, 1209, 5, 34, 0, 0, 1208, 1207, 1, 0, 0, 0, 1208, 1209, 1, 0, 0, 0, 1209, 1211, 1, 0, 0, 0, 1210, 1181, 1, 0, 0, 0, 1210, 1190, 1, 0, 0, 0, 1211, 205, 1, 0, 0, 0, 1212, 1214, 3, 184, 83, 0, 1213, 1212, 1, 0, 0, 0, 1214, 1215, 1, 0, 0, 0, 1215, 1213, 1, 0, 0, 0, 1215, 1216, 1, 0, 0, 0, 1216, 207, 1, 0, 0, 0, 1217, 1219, 3, 184, 83, 0, 1218, 1217, 1, 0, 0, 0, 1219, 1220, 1, 0, 0, 0, 1220, 1218, 1, 0, 0, 0, 1220, 1221, 1, 0, 0, 0, 1221, 1222, 1, 0, 0, 0, 1222, 1226, 3, 228, 105, 0, 1223, 1225, 3, 184, 83, 0, 1224, 1223, 1, 0, 0, 0, 1225, 1228, 1, 0, 0, 0, 1226, 1224, 1, 0, 0, 0, 1226, 1227, 1, 0, 0, 0, 1227, 1260, 1, 0, 0, 0, 1228, 1226, 1, 0, 0, 0, 1229, 1231, 3, 228, 105, 0, 1230, 1232, 3, 184, 83, 0, 1231, 1230, 1, 0, 0, 0, 1232, 1233, 1, 0, 0, 0, 1233, 1231, 1, 0, 0, 0, 1233, 1234, 1, 0, 0, 0, 1234, 1260, 1, 0, 0, 0, 1235, 1237, 3, 184, 83, 0, 1236, 1235, 1, 0, 0, 0, 1237, 1238, 1, 0, 0, 0, 1238, 1236, 1, 0, 0, 0, 1238, 1239, 1, 0, 0, 0, 1239, 1247, 1, 0, 0, 0, 1240, 1244, 3, 228, 105, 0, 1241, 1243, 3, 184, 83, 0, 1242, 1241, 1, 0, 0, 0, 1243, 1246, 1, 0, 0, 0, 1244, 1242, 1, 0, 0, 0, 1244, 1245, 1, 0, 0, 0, 1245, 1248, 1, 0, 0, 0, 1246, 1244, 1, 0, 0, 0, 1247, 1240, 1, 0, 0, 0, 1247, 1248, 1, 0, 0, 0, 1248, 1249, 1, 0, 0, 0, 1249, 1250, 3, 192, 87, 0, 1250, 1260, 1, 0, 0, 0, 1251, 1253, 3, 228, 105, 0, 1252, 1254, 3, 184, 83, 0, 1253, 1252, 1, 0, 0, 0, 1254, 1255, 1, 0, 0, 0, 1255, 1253, 1, 0, 0, 0, 1255, 1256, 1, 0, 0, 0, 1256, 1257, 1, 0, 0, 0, 1257, 1258, 3, 192, 87, 0, 1258, 1260, 1, 0, 0, 0, 1259, 1218, 1, 0, 0, 0, 1259, 1229, 1, 0, 0, 0, 1259, 1236, 1, 0, 0, 0, 1259, 1251, 1, 0, 0, 0, 1260, 209, 1, 0, 0, 0, 1261, 1262, 7, 4, 0, 0, 1262, 1263, 7, 5, 0, 0, 1263, 1264, 7, 16, 0, 0, 1264, 211, 1, 0, 0, 0, 1265, 1266, 7, 4, 0, 0, 1266, 1267, 7, 17, 0, 0, 1267, 1268, 7, 2, 0, 0, 1268, 213, 1, 0, 0, 0, 1269, 1270, 5, 61, 0, 0, 1270, 215, 1, 0, 0, 0, 1271, 1272, 7, 31, 0, 0, 1272, 1273, 7, 32, 0, 0, 1273, 217, 1, 0, 0, 0, 1274, 1275, 5, 58, 0, 0, 1275, 1276, 5, 58, 0, 0, 1276, 219, 1, 0, 0, 0, 1277, 1278, 5, 58, 0, 0, 1278, 221, 1, 0, 0, 0, 1279, 1280, 5, 59, 0, 0, 1280, 223, 1, 0, 0, 0, 1281, 1282, 5, 44, 0, 0, 1282, 225, 1, 0, 0, 0, 1283, 1284, 7, 16, 0, 0, 1284, 1285, 7, 7, 0, 0, 1285, 1286, 7, 17, 0, 0, 1286, 1287, 7, 2, 0, 0, 1287, 227, 1, 0, 0, 0, 1288, 1289, 5, 46, 0, 0, 1289, 229, 1, 0, 0, 0, 1290, 1291, 7, 21, 0, 0, 1291, 1292, 7, 4, 0, 0, 1292, 1293, 7, 14, 0, 0, 1293, 1294, 7, 17, 0, 0, 1294, 1295, 7, 7, 0, 0, 1295, 231, 1, 0, 0, 0, 1296, 1297, 7, 21, 0, 0, 1297, 1298, 7, 10, 0, 0, 1298, 1299, 7, 12, 0, 0, 1299, 1300, 7, 17, 0, 0, 1300, 1301, 7, 11, 0, 0, 1301, 233, 1, 0, 0, 0, 1302, 1303, 7, 10, 0, 0, 1303, 1304, 7, 5, 0, 0, 1304, 235, 1, 0, 0, 0, 1305, 1306, 7, 10, 0, 0, 1306, 1307, 7, 17, 0, 0, 1307, 237, 1, 0, 0, 0, 1308, 1309, 7, 14, 0, 0, 1309, 1310, 7, 4, 0, 0, 1310, 1311, 7, 17, 0, 0, 1311, 1312, 7, 11, 0, 0, 1312, 239, 1, 0, 0, 0, 1313, 1314, 7, 14, 0, 0, 1314, 1315, 7, 10, 0, 0, 1315, 1316, 7, 19, 0, 0, 1316, 1317, 7, 7, 0, 0, 1317, 241, 1, 0, 0, 0, 1318, 1319, 7, 5, 0, 0, 1319, 1320, 7, 9, 0, 0, 1320, 1321, 7, 11, 0, 0, 1321, 243, 1, 0, 0, 0, 1322, 1323, 7, 5, 0, 0, 1323, 1324, 7, 22, 0, 0, 1324, 1325, 7, 14, 0, 0, 1325, 1326, 7, 14, 0, 0, 1326, 245, 1, 0, 0, 0, 1327, 1328, 7, 5, 0, 0, 1328, 1329, 7, 22, 0, 0, 1329, 1330, 7, 14, 0, 0, 1330, 1331, 7, 14, 0, 0, 1331, 1332, 7, 17, 0, 0, 1332, 247, 1, 0, 0, 0, 1333, 1334, 7, 9, 0, 0, 1334, 1335, 7, 5, 0, 0, 1335, 249, 1, 0, 0, 0, 1336, 1337, 7, 9, 0, 0, 1337, 1338, 7, 12, 0, 0, 1338, 251, 1, 0, 0, 0, 1339, 1340, 5, 63, 0, 0, 1340, 253, 1, 0, 0, 0, 1341, 1342, 7, 12, 0, 0, 1342, 1343, 7, 14, 0, 0, 1343, 1344, 7, 10, 0, 0, 1344, 1345, 7, 19, 0, 0, 1345, 1346, 7, 7, 0, 0, 1346, 255, 1, 0, 0, 0, 1347, 1348, 7, 11, 0, 0, 1348, 1349, 7, 12, 0, 0, 1349, 1350, 7, 22, 0, 0, 1350, 1351, 7, 7, 0, 0, 1351, 257, 1, 0, 0, 0, 1352, 1353, 7, 20, 0, 0, 1353, 1354, 7, 10, 0, 0, 1354, 1355, 7, 11, 0, 0, 1355, 1356, 7, 3, 0, 0, 1356, 259, 1, 0, 0, 0, 1357, 1358, 5, 61, 0, 0, 1358, 1359, 5, 61, 0, 0, 1359, 261, 1, 0, 0, 0, 1360, 1361, 5, 61, 0, 0, 1361, 1362, 5, 126, 0, 0, 1362, 263, 1, 0, 0, 0, 1363, 1364, 5, 33, 0, 0, 1364, 1365, 5, 61, 0, 0, 1365, 265, 1, 0, 0, 0, 1366, 1367, 5, 60, 0, 0, 1367, 267, 1, 0, 0, 0, 1368, 1369, 5, 60, 0, 0, 1369, 1370, 5, 61, 0, 0, 1370, 269, 1, 0, 0, 0, 1371, 1372, 5, 62, 0, 0, 1372, 271, 1, 0, 0, 0, 1373, 1374, 5, 62, 0, 0, 1374, 1375, 5, 61, 0, 0, 1375, 273, 1, 0, 0, 0, 1376, 1377, 5, 43, 0, 0, 1377, 275, 1, 0, 0, 0, 1378, 1379, 5, 45, 0, 0, 1379, 277, 1, 0, 0, 0, 1380, 1381, 5, 42, 0, 0, 1381, 279, 1, 0, 0, 0, 1382, 1383, 5, 47, 0, 0, 1383, 281, 1, 0, 0, 0, 1384, 1385, 5, 37, 0, 0, 1385, 283, 1, 0, 0, 0, 1386, 1387, 5, 123, 0, 0, 1387, 285, 1, 0, 0, 0, 1388, 1389, 5, 125, 0, 0, 1389, 287, 1, 0, 0, 0, 1390, 1391, 5, 63, 0, 0, 1391, 1392, 5, 63, 0, 0, 1392, 289, 1, 0, 0, 0, 1393, 1394, 3, 50, 16, 0, 1394, 1395, 1, 0, 0, 0, 1395, 1396, 6, 136, 39, 0, 1396, 291, 1, 0, 0, 0, 1397, 1400, 3, 252, 117, 0, 1398, 1401, 3, 186, 84, 0, 1399, 1401, 3, 200, 91, 0, 1400, 1398, 1, 0, 0, 0, 1400, 1399, 1, 0, 0, 0, 1401, 1405, 1, 0, 0, 0, 1402, 1404, 3, 202, 92, 0, 1403, 1402, 1, 0, 0, 0, 1404, 1407, 1, 0, 0, 0, 1405, 1403, 1, 0, 0, 0, 1405, 1406, 1, 0, 0, 0, 1406, 1415, 1, 0, 0, 0, 1407, 1405, 1, 0, 0, 0, 1408, 1410, 3, 252, 117, 0, 1409, 1411, 3, 184, 83, 0, 1410, 1409, 1, 0, 0, 0, 1411, 1412, 1, 0, 0, 0, 1412, 1410, 1, 0, 0, 0, 1412, 1413, 1, 0, 0, 0, 1413, 1415, 1, 0, 0, 0, 1414, 1397, 1, 0, 0, 0, 1414, 1408, 1, 0, 0, 0, 1415, 293, 1, 0, 0, 0, 1416, 1419, 3, 288, 135, 0, 1417, 1420, 3, 186, 84, 0, 1418, 1420, 3, 200, 91, 0, 1419, 1417, 1, 0, 0, 0, 1419, 1418, 1, 0, 0, 0, 1420, 1424, 1, 0, 0, 0, 1421, 1423, 3, 202, 92, 0, 1422, 1421, 1, 0, 0, 0, 1423, 1426, 1, 0, 0, 0, 1424, 1422, 1, 0, 0, 0, 1424, 1425, 1, 0, 0, 0, 1425, 1434, 1, 0, 0, 0, 1426, 1424, 1, 0, 0, 0, 1427, 1429, 3, 288, 135, 0, 1428, 1430, 3, 184, 83, 0, 1429, 1428, 1, 0, 0, 0, 1430, 1431, 1, 0, 0, 0, 1431, 1429, 1, 0, 0, 0, 1431, 1432, 1, 0, 0, 0, 1432, 1434, 1, 0, 0, 0, 1433, 1416, 1, 0, 0, 0, 1433, 1427, 1, 0, 0, 0, 1434, 295, 1, 0, 0, 0, 1435, 1436, 5, 91, 0, 0, 1436, 1437, 1, 0, 0, 0, 1437, 1438, 6, 139, 4, 0, 1438, 1439, 6, 139, 4, 0, 1439, 297, 1, 0, 0, 0, 1440, 1441, 5, 93, 0, 0, 1441, 1442, 1, 0, 0, 0, 1442, 1443, 6, 140, 17, 0, 1443, 1444, 6, 140, 17, 0, 1444, 299, 1, 0, 0, 0, 1445, 1446, 5, 40, 0, 0, 1446, 1447, 1, 0, 0, 0, 1447, 1448, 6, 141, 4, 0, 1448, 1449, 6, 141, 4, 0, 1449, 301, 1, 0, 0, 0, 1450, 1451, 5, 41, 0, 0, 1451, 1452, 1, 0, 0, 0, 1452, 1453, 6, 142, 17, 0, 1453, 1454, 6, 142, 17, 0, 1454, 303, 1, 0, 0, 0, 1455, 1459, 3, 186, 84, 0, 1456, 1458, 3, 202, 92, 0, 1457, 1456, 1, 0, 0, 0, 1458, 1461, 1, 0, 0, 0, 1459, 1457, 1, 0, 0, 0, 1459, 1460, 1, 0, 0, 0, 1460, 1472, 1, 0, 0, 0, 1461, 1459, 1, 0, 0, 0, 1462, 1465, 3, 200, 91, 0, 1463, 1465, 3, 194, 88, 0, 1464, 1462, 1, 0, 0, 0, 1464, 1463, 1, 0, 0, 0, 1465, 1467, 1, 0, 0, 0, 1466, 1468, 3, 202, 92, 0, 1467, 1466, 1, 0, 0, 0, 1468, 1469, 1, 0, 0, 0, 1469, 1467, 1, 0, 0, 0, 1469, 1470, 1, 0, 0, 0, 1470, 1472, 1, 0, 0, 0, 1471, 1455, 1, 0, 0, 0, 1471, 1464, 1, 0, 0, 0, 1472, 305, 1, 0, 0, 0, 1473, 1475, 3, 196, 89, 0, 1474, 1476, 3, 198, 90, 0, 1475, 1474, 1, 0, 0, 0, 1476, 1477, 1, 0, 0, 0, 1477, 1475, 1, 0, 0, 0, 1477, 1478, 1, 0, 0, 0, 1478, 1479, 1, 0, 0, 0, 1479, 1480, 3, 196, 89, 0, 1480, 307, 1, 0, 0, 0, 1481, 1482, 3, 306, 144, 0, 1482, 309, 1, 0, 0, 0, 1483, 1484, 3, 18, 0, 0, 1484, 1485, 1, 0, 0, 0, 1485, 1486, 6, 146, 0, 0, 1486, 311, 1, 0, 0, 0, 1487, 1488, 3, 20, 1, 0, 1488, 1489, 1, 0, 0, 0, 1489, 1490, 6, 147, 0, 0, 1490, 313, 1, 0, 0, 0, 1491, 1492, 3, 22, 2, 0, 1492, 1493, 1, 0, 0, 0, 1493, 1494, 6, 148, 0, 0, 1494, 315, 1, 0, 0, 0, 1495, 1496, 3, 182, 82, 0, 1496, 1497, 1, 0, 0, 0, 1497, 1498, 6, 149, 16, 0, 1498, 1499, 6, 149, 17, 0, 1499, 317, 1, 0, 0, 0, 1500, 1501, 3, 220, 101, 0, 1501, 1502, 1, 0, 0, 0, 1502, 1503, 6, 150, 40, 0, 1503, 319, 1, 0, 0, 0, 1504, 1505, 3, 218, 100, 0, 1505, 1506, 1, 0, 0, 0, 1506, 1507, 6, 151, 41, 0, 1507, 321, 1, 0, 0, 0, 1508, 1509, 3, 224, 103, 0, 1509, 1510, 1, 0, 0, 0, 1510, 1511, 6, 152, 22, 0, 1511, 323, 1, 0, 0, 0, 1512, 1513, 3, 214, 98, 0, 1513, 1514, 1, 0, 0, 0, 1514, 1515, 6, 153, 31, 0, 1515, 325, 1, 0, 0, 0, 1516, 1517, 7, 15, 0, 0, 1517, 1518, 7, 7, 0, 0, 1518, 1519, 7, 11, 0, 0, 1519, 1520, 7, 4, 0, 0, 1520, 1521, 7, 16, 0, 0, 1521, 1522, 7, 4, 0, 0, 1522, 1523, 7, 11, 0, 0, 1523, 1524, 7, 4, 0, 0, 1524, 327, 1, 0, 0, 0, 1525, 1526, 3, 302, 142, 0, 1526, 1527, 1, 0, 0, 0, 1527, 1528, 6, 155, 18, 0, 1528, 1529, 6, 155, 17, 0, 1529, 1530, 6, 155, 17, 0, 1530, 329, 1, 0, 0, 0, 1531, 1532, 3, 300, 141, 0, 1532, 1533, 1, 0, 0, 0, 1533, 1534, 6, 156, 37, 0, 1534, 1535, 6, 156, 38, 0, 1535, 331, 1, 0, 0, 0, 1536, 1540, 8, 33, 0, 0, 1537, 1538, 5, 47, 0, 0, 1538, 1540, 8, 34, 0, 0, 1539, 1536, 1, 0, 0, 0, 1539, 1537, 1, 0, 0, 0, 1540, 333, 1, 0, 0, 0, 1541, 1543, 3, 332, 157, 0, 1542, 1541, 1, 0, 0, 0, 1543, 1544, 1, 0, 0, 0, 1544, 1542, 1, 0, 0, 0, 1544, 1545, 1, 0, 0, 0, 1545, 335, 1, 0, 0, 0, 1546, 1547, 3, 334, 158, 0, 1547, 1548, 1, 0, 0, 0, 1548, 1549, 6, 159, 42, 0, 1549, 337, 1, 0, 0, 0, 1550, 1551, 3, 204, 93, 0, 1551, 1552, 1, 0, 0, 0, 1552, 1553, 6, 160, 30, 0, 1553, 339, 1, 0, 0, 0, 1554, 1555, 3, 18, 0, 0, 1555, 1556, 1, 0, 0, 0, 1556, 1557, 6, 161, 0, 0, 1557, 341, 1, 0, 0, 0, 1558, 1559, 3, 20, 1, 0, 1559, 1560, 1, 0, 0, 0, 1560, 1561, 6, 162, 0, 0, 1561, 343, 1, 0, 0, 0, 1562, 1563, 3, 22, 2, 0, 1563, 1564, 1, 0, 0, 0, 1564, 1565, 6, 163, 0, 0, 1565, 345, 1, 0, 0, 0, 1566, 1567, 3, 300, 141, 0, 1567, 1568, 1, 0, 0, 0, 1568, 1569, 6, 164, 37, 0, 1569, 1570, 6, 164, 38, 0, 1570, 347, 1, 0, 0, 0, 1571, 1572, 3, 302, 142, 0, 1572, 1573, 1, 0, 0, 0, 1573, 1574, 6, 165, 18, 0, 1574, 1575, 6, 165, 17, 0, 1575, 1576, 6, 165, 17, 0, 1576, 349, 1, 0, 0, 0, 1577, 1578, 3, 182, 82, 0, 1578, 1579, 1, 0, 0, 0, 1579, 1580, 6, 166, 16, 0, 1580, 1581, 6, 166, 17, 0, 1581, 351, 1, 0, 0, 0, 1582, 1583, 3, 22, 2, 0, 1583, 1584, 1, 0, 0, 0, 1584, 1585, 6, 167, 0, 0, 1585, 353, 1, 0, 0, 0, 1586, 1587, 3, 18, 0, 0, 1587, 1588, 1, 0, 0, 0, 1588, 1589, 6, 168, 0, 0, 1589, 355, 1, 0, 0, 0, 1590, 1591, 3, 20, 1, 0, 1591, 1592, 1, 0, 0, 0, 1592, 1593, 6, 169, 0, 0, 1593, 357, 1, 0, 0, 0, 1594, 1595, 3, 182, 82, 0, 1595, 1596, 1, 0, 0, 0, 1596, 1597, 6, 170, 16, 0, 1597, 1598, 6, 170, 17, 0, 1598, 359, 1, 0, 0, 0, 1599, 1600, 3, 302, 142, 0, 1600, 1601, 1, 0, 0, 0, 1601, 1602, 6, 171, 18, 0, 1602, 1603, 6, 171, 17, 0, 1603, 1604, 6, 171, 17, 0, 1604, 361, 1, 0, 0, 0, 1605, 1606, 7, 6, 0, 0, 1606, 1607, 7, 12, 0, 0, 1607, 1608, 7, 9, 0, 0, 1608, 1609, 7, 22, 0, 0, 1609, 1610, 7, 8, 0, 0, 1610, 363, 1, 0, 0, 0, 1611, 1612, 7, 17, 0, 0, 1612, 1613, 7, 2, 0, 0, 1613, 1614, 7, 9, 0, 0, 1614, 1615, 7, 12, 0, 0, 1615, 1616, 7, 7, 0, 0, 1616, 365, 1, 0, 0, 0, 1617, 1618, 7, 19, 0, 0, 1618, 1619, 7, 7, 0, 0, 1619, 1620, 7, 32, 0, 0, 1620, 367, 1, 0, 0, 0, 1621, 1622, 3, 258, 120, 0, 1622, 1623, 1, 0, 0, 0, 1623, 1624, 6, 175, 28, 0, 1624, 1625, 6, 175, 17, 0, 1625, 1626, 6, 175, 4, 0, 1626, 369, 1, 0, 0, 0, 1627, 1628, 3, 224, 103, 0, 1628, 1629, 1, 0, 0, 0, 1629, 1630, 6, 176, 22, 0, 1630, 371, 1, 0, 0, 0, 1631, 1632, 3, 228, 105, 0, 1632, 1633, 1, 0, 0, 0, 1633, 1634, 6, 177, 21, 0, 1634, 373, 1, 0, 0, 0, 1635, 1636, 3, 252, 117, 0, 1636, 1637, 1, 0, 0, 0, 1637, 1638, 6, 178, 33, 0, 1638, 375, 1, 0, 0, 0, 1639, 1640, 3, 292, 137, 0, 1640, 1641, 1, 0, 0, 0, 1641, 1642, 6, 179, 34, 0, 1642, 377, 1, 0, 0, 0, 1643, 1644, 3, 288, 135, 0, 1644, 1645, 1, 0, 0, 0, 1645, 1646, 6, 180, 35, 0, 1646, 379, 1, 0, 0, 0, 1647, 1648, 3, 294, 138, 0, 1648, 1649, 1, 0, 0, 0, 1649, 1650, 6, 181, 36, 0, 1650, 381, 1, 0, 0, 0, 1651, 1652, 3, 216, 99, 0, 1652, 1653, 1, 0, 0, 0, 1653, 1654, 6, 182, 43, 0, 1654, 383, 1, 0, 0, 0, 1655, 1656, 3, 308, 145, 0, 1656, 1657, 1, 0, 0, 0, 1657, 1658, 6, 183, 25, 0, 1658, 385, 1, 0, 0, 0, 1659, 1660, 3, 304, 143, 0, 1660, 1661, 1, 0, 0, 0, 1661, 1662, 6, 184, 26, 0, 1662, 387, 1, 0, 0, 0, 1663, 1664, 3, 18, 0, 0, 1664, 1665, 1, 0, 0, 0, 1665, 1666, 6, 185, 0, 0, 1666, 389, 1, 0, 0, 0, 1667, 1668, 3, 20, 1, 0, 1668, 1669, 1, 0, 0, 0, 1669, 1670, 6, 186, 0, 0, 1670, 391, 1, 0, 0, 0, 1671, 1672, 3, 22, 2, 0, 1672, 1673, 1, 0, 0, 0, 1673, 1674, 6, 187, 0, 0, 1674, 393, 1, 0, 0, 0, 1675, 1676, 7, 17, 0, 0, 1676, 1677, 7, 11, 0, 0, 1677, 1678, 7, 4, 0, 0, 1678, 1679, 7, 11, 0, 0, 1679, 1680, 7, 17, 0, 0, 1680, 1681, 1, 0, 0, 0, 1681, 1682, 6, 188, 17, 0, 1682, 1683, 6, 188, 4, 0, 1683, 395, 1, 0, 0, 0, 1684, 1685, 3, 18, 0, 0, 1685, 1686, 1, 0, 0, 0, 1686, 1687, 6, 189, 0, 0, 1687, 397, 1, 0, 0, 0, 1688, 1689, 3, 20, 1, 0, 1689, 1690, 1, 0, 0, 0, 1690, 1691, 6, 190, 0, 0, 1691, 399, 1, 0, 0, 0, 1692, 1693, 3, 22, 2, 0, 1693, 1694, 1, 0, 0, 0, 1694, 1695, 6, 191, 0, 0, 1695, 401, 1, 0, 0, 0, 1696, 1697, 3, 182, 82, 0, 1697, 1698, 1, 0, 0, 0, 1698, 1699, 6, 192, 16, 0, 1699, 1700, 6, 192, 17, 0, 1700, 403, 1, 0, 0, 0, 1701, 1702, 7, 35, 0, 0, 1702, 1703, 7, 9, 0, 0, 1703, 1704, 7, 10, 0, 0, 1704, 1705, 7, 5, 0, 0, 1705, 405, 1, 0, 0, 0, 1706, 1707, 3, 544, 263, 0, 1707, 1708, 1, 0, 0, 0, 1708, 1709, 6, 194, 20, 0, 1709, 407, 1, 0, 0, 0, 1710, 1711, 3, 248, 115, 0, 1711, 1712, 1, 0, 0, 0, 1712, 1713, 6, 195, 19, 0, 1713, 1714, 6, 195, 17, 0, 1714, 1715, 6, 195, 4, 0, 1715, 409, 1, 0, 0, 0, 1716, 1717, 7, 22, 0, 0, 1717, 1718, 7, 17, 0, 0, 1718, 1719, 7, 10, 0, 0, 1719, 1720, 7, 5, 0, 0, 1720, 1721, 7, 6, 0, 0, 1721, 1722, 1, 0, 0, 0, 1722, 1723, 6, 196, 17, 0, 1723, 1724, 6, 196, 4, 0, 1724, 411, 1, 0, 0, 0, 1725, 1726, 3, 334, 158, 0, 1726, 1727, 1, 0, 0, 0, 1727, 1728, 6, 197, 42, 0, 1728, 413, 1, 0, 0, 0, 1729, 1730, 3, 204, 93, 0, 1730, 1731, 1, 0, 0, 0, 1731, 1732, 6, 198, 30, 0, 1732, 415, 1, 0, 0, 0, 1733, 1734, 3, 220, 101, 0, 1734, 1735, 1, 0, 0, 0, 1735, 1736, 6, 199, 40, 0, 1736, 417, 1, 0, 0, 0, 1737, 1738, 3, 18, 0, 0, 1738, 1739, 1, 0, 0, 0, 1739, 1740, 6, 200, 0, 0, 1740, 419, 1, 0, 0, 0, 1741, 1742, 3, 20, 1, 0, 1742, 1743, 1, 0, 0, 0, 1743, 1744, 6, 201, 0, 0, 1744, 421, 1, 0, 0, 0, 1745, 1746, 3, 22, 2, 0, 1746, 1747, 1, 0, 0, 0, 1747, 1748, 6, 202, 0, 0, 1748, 423, 1, 0, 0, 0, 1749, 1750, 3, 182, 82, 0, 1750, 1751, 1, 0, 0, 0, 1751, 1752, 6, 203, 16, 0, 1752, 1753, 6, 203, 17, 0, 1753, 425, 1, 0, 0, 0, 1754, 1755, 3, 302, 142, 0, 1755, 1756, 1, 0, 0, 0, 1756, 1757, 6, 204, 18, 0, 1757, 1758, 6, 204, 17, 0, 1758, 1759, 6, 204, 17, 0, 1759, 427, 1, 0, 0, 0, 1760, 1761, 3, 220, 101, 0, 1761, 1762, 1, 0, 0, 0, 1762, 1763, 6, 205, 40, 0, 1763, 429, 1, 0, 0, 0, 1764, 1765, 3, 224, 103, 0, 1765, 1766, 1, 0, 0, 0, 1766, 1767, 6, 206, 22, 0, 1767, 431, 1, 0, 0, 0, 1768, 1769, 3, 228, 105, 0, 1769, 1770, 1, 0, 0, 0, 1770, 1771, 6, 207, 21, 0, 1771, 433, 1, 0, 0, 0, 1772, 1773, 3, 248, 115, 0, 1773, 1774, 1, 0, 0, 0, 1774, 1775, 6, 208, 19, 0, 1775, 1776, 6, 208, 44, 0, 1776, 435, 1, 0, 0, 0, 1777, 1778, 3, 334, 158, 0, 1778, 1779, 1, 0, 0, 0, 1779, 1780, 6, 209, 42, 0, 1780, 437, 1, 0, 0, 0, 1781, 1782, 3, 204, 93, 0, 1782, 1783, 1, 0, 0, 0, 1783, 1784, 6, 210, 30, 0, 1784, 439, 1, 0, 0, 0, 1785, 1786, 3, 18, 0, 0, 1786, 1787, 1, 0, 0, 0, 1787, 1788, 6, 211, 0, 0, 1788, 441, 1, 0, 0, 0, 1789, 1790, 3, 20, 1, 0, 1790, 1791, 1, 0, 0, 0, 1791, 1792, 6, 212, 0, 0, 1792, 443, 1, 0, 0, 0, 1793, 1794, 3, 22, 2, 0, 1794, 1795, 1, 0, 0, 0, 1795, 1796, 6, 213, 0, 0, 1796, 445, 1, 0, 0, 0, 1797, 1798, 3, 182, 82, 0, 1798, 1799, 1, 0, 0, 0, 1799, 1800, 6, 214, 16, 0, 1800, 1801, 6, 214, 17, 0, 1801, 1802, 6, 214, 17, 0, 1802, 447, 1, 0, 0, 0, 1803, 1804, 3, 302, 142, 0, 1804, 1805, 1, 0, 0, 0, 1805, 1806, 6, 215, 18, 0, 1806, 1807, 6, 215, 17, 0, 1807, 1808, 6, 215, 17, 0, 1808, 1809, 6, 215, 17, 0, 1809, 449, 1, 0, 0, 0, 1810, 1811, 3, 224, 103, 0, 1811, 1812, 1, 0, 0, 0, 1812, 1813, 6, 216, 22, 0, 1813, 451, 1, 0, 0, 0, 1814, 1815, 3, 228, 105, 0, 1815, 1816, 1, 0, 0, 0, 1816, 1817, 6, 217, 21, 0, 1817, 453, 1, 0, 0, 0, 1818, 1819, 3, 514, 248, 0, 1819, 1820, 1, 0, 0, 0, 1820, 1821, 6, 218, 32, 0, 1821, 455, 1, 0, 0, 0, 1822, 1823, 3, 18, 0, 0, 1823, 1824, 1, 0, 0, 0, 1824, 1825, 6, 219, 0, 0, 1825, 457, 1, 0, 0, 0, 1826, 1827, 3, 20, 1, 0, 1827, 1828, 1, 0, 0, 0, 1828, 1829, 6, 220, 0, 0, 1829, 459, 1, 0, 0, 0, 1830, 1831, 3, 22, 2, 0, 1831, 1832, 1, 0, 0, 0, 1832, 1833, 6, 221, 0, 0, 1833, 461, 1, 0, 0, 0, 1834, 1835, 3, 182, 82, 0, 1835, 1836, 1, 0, 0, 0, 1836, 1837, 6, 222, 16, 0, 1837, 1838, 6, 222, 17, 0, 1838, 463, 1, 0, 0, 0, 1839, 1840, 3, 302, 142, 0, 1840, 1841, 1, 0, 0, 0, 1841, 1842, 6, 223, 18, 0, 1842, 1843, 6, 223, 17, 0, 1843, 1844, 6, 223, 17, 0, 1844, 465, 1, 0, 0, 0, 1845, 1846, 3, 296, 139, 0, 1846, 1847, 1, 0, 0, 0, 1847, 1848, 6, 224, 23, 0, 1848, 467, 1, 0, 0, 0, 1849, 1850, 3, 298, 140, 0, 1850, 1851, 1, 0, 0, 0, 1851, 1852, 6, 225, 24, 0, 1852, 469, 1, 0, 0, 0, 1853, 1854, 3, 228, 105, 0, 1854, 1855, 1, 0, 0, 0, 1855, 1856, 6, 226, 21, 0, 1856, 471, 1, 0, 0, 0, 1857, 1858, 3, 252, 117, 0, 1858, 1859, 1, 0, 0, 0, 1859, 1860, 6, 227, 33, 0, 1860, 473, 1, 0, 0, 0, 1861, 1862, 3, 292, 137, 0, 1862, 1863, 1, 0, 0, 0, 1863, 1864, 6, 228, 34, 0, 1864, 475, 1, 0, 0, 0, 1865, 1866, 3, 288, 135, 0, 1866, 1867, 1, 0, 0, 0, 1867, 1868, 6, 229, 35, 0, 1868, 477, 1, 0, 0, 0, 1869, 1870, 3, 294, 138, 0, 1870, 1871, 1, 0, 0, 0, 1871, 1872, 6, 230, 36, 0, 1872, 479, 1, 0, 0, 0, 1873, 1874, 3, 308, 145, 0, 1874, 1875, 1, 0, 0, 0, 1875, 1876, 6, 231, 25, 0, 1876, 481, 1, 0, 0, 0, 1877, 1878, 3, 304, 143, 0, 1878, 1879, 1, 0, 0, 0, 1879, 1880, 6, 232, 26, 0, 1880, 483, 1, 0, 0, 0, 1881, 1882, 3, 18, 0, 0, 1882, 1883, 1, 0, 0, 0, 1883, 1884, 6, 233, 0, 0, 1884, 485, 1, 0, 0, 0, 1885, 1886, 3, 20, 1, 0, 1886, 1887, 1, 0, 0, 0, 1887, 1888, 6, 234, 0, 0, 1888, 487, 1, 0, 0, 0, 1889, 1890, 3, 22, 2, 0, 1890, 1891, 1, 0, 0, 0, 1891, 1892, 6, 235, 0, 0, 1892, 489, 1, 0, 0, 0, 1893, 1894, 3, 182, 82, 0, 1894, 1895, 1, 0, 0, 0, 1895, 1896, 6, 236, 16, 0, 1896, 1897, 6, 236, 17, 0, 1897, 491, 1, 0, 0, 0, 1898, 1899, 3, 302, 142, 0, 1899, 1900, 1, 0, 0, 0, 1900, 1901, 6, 237, 18, 0, 1901, 1902, 6, 237, 17, 0, 1902, 1903, 6, 237, 17, 0, 1903, 493, 1, 0, 0, 0, 1904, 1905, 3, 228, 105, 0, 1905, 1906, 1, 0, 0, 0, 1906, 1907, 6, 238, 21, 0, 1907, 495, 1, 0, 0, 0, 1908, 1909, 3, 296, 139, 0, 1909, 1910, 1, 0, 0, 0, 1910, 1911, 6, 239, 23, 0, 1911, 497, 1, 0, 0, 0, 1912, 1913, 3, 298, 140, 0, 1913, 1914, 1, 0, 0, 0, 1914, 1915, 6, 240, 24, 0, 1915, 499, 1, 0, 0, 0, 1916, 1917, 3, 224, 103, 0, 1917, 1918, 1, 0, 0, 0, 1918, 1919, 6, 241, 22, 0, 1919, 501, 1, 0, 0, 0, 1920, 1921, 3, 252, 117, 0, 1921, 1922, 1, 0, 0, 0, 1922, 1923, 6, 242, 33, 0, 1923, 503, 1, 0, 0, 0, 1924, 1925, 3, 292, 137, 0, 1925, 1926, 1, 0, 0, 0, 1926, 1927, 6, 243, 34, 0, 1927, 505, 1, 0, 0, 0, 1928, 1929, 3, 288, 135, 0, 1929, 1930, 1, 0, 0, 0, 1930, 1931, 6, 244, 35, 0, 1931, 507, 1, 0, 0, 0, 1932, 1933, 3, 294, 138, 0, 1933, 1934, 1, 0, 0, 0, 1934, 1935, 6, 245, 36, 0, 1935, 509, 1, 0, 0, 0, 1936, 1941, 3, 186, 84, 0, 1937, 1941, 3, 184, 83, 0, 1938, 1941, 3, 200, 91, 0, 1939, 1941, 3, 278, 130, 0, 1940, 1936, 1, 0, 0, 0, 1940, 1937, 1, 0, 0, 0, 1940, 1938, 1, 0, 0, 0, 1940, 1939, 1, 0, 0, 0, 1941, 511, 1, 0, 0, 0, 1942, 1945, 3, 186, 84, 0, 1943, 1945, 3, 278, 130, 0, 1944, 1942, 1, 0, 0, 0, 1944, 1943, 1, 0, 0, 0, 1945, 1949, 1, 0, 0, 0, 1946, 1948, 3, 510, 246, 0, 1947, 1946, 1, 0, 0, 0, 1948, 1951, 1, 0, 0, 0, 1949, 1947, 1, 0, 0, 0, 1949, 1950, 1, 0, 0, 0, 1950, 1962, 1, 0, 0, 0, 1951, 1949, 1, 0, 0, 0, 1952, 1955, 3, 200, 91, 0, 1953, 1955, 3, 194, 88, 0, 1954, 1952, 1, 0, 0, 0, 1954, 1953, 1, 0, 0, 0, 1955, 1957, 1, 0, 0, 0, 1956, 1958, 3, 510, 246, 0, 1957, 1956, 1, 0, 0, 0, 1958, 1959, 1, 0, 0, 0, 1959, 1957, 1, 0, 0, 0, 1959, 1960, 1, 0, 0, 0, 1960, 1962, 1, 0, 0, 0, 1961, 1944, 1, 0, 0, 0, 1961, 1954, 1, 0, 0, 0, 1962, 513, 1, 0, 0, 0, 1963, 1966, 3, 512, 247, 0, 1964, 1966, 3, 306, 144, 0, 1965, 1963, 1, 0, 0, 0, 1965, 1964, 1, 0, 0, 0, 1966, 1967, 1, 0, 0, 0, 1967, 1965, 1, 0, 0, 0, 1967, 1968, 1, 0, 0, 0, 1968, 515, 1, 0, 0, 0, 1969, 1970, 3, 18, 0, 0, 1970, 1971, 1, 0, 0, 0, 1971, 1972, 6, 249, 0, 0, 1972, 517, 1, 0, 0, 0, 1973, 1974, 3, 20, 1, 0, 1974, 1975, 1, 0, 0, 0, 1975, 1976, 6, 250, 0, 0, 1976, 519, 1, 0, 0, 0, 1977, 1978, 3, 22, 2, 0, 1978, 1979, 1, 0, 0, 0, 1979, 1980, 6, 251, 0, 0, 1980, 521, 1, 0, 0, 0, 1981, 1982, 3, 182, 82, 0, 1982, 1983, 1, 0, 0, 0, 1983, 1984, 6, 252, 16, 0, 1984, 1985, 6, 252, 17, 0, 1985, 523, 1, 0, 0, 0, 1986, 1987, 3, 302, 142, 0, 1987, 1988, 1, 0, 0, 0, 1988, 1989, 6, 253, 18, 0, 1989, 1990, 6, 253, 17, 0, 1990, 1991, 6, 253, 17, 0, 1991, 525, 1, 0, 0, 0, 1992, 1993, 3, 296, 139, 0, 1993, 1994, 1, 0, 0, 0, 1994, 1995, 6, 254, 23, 0, 1995, 527, 1, 0, 0, 0, 1996, 1997, 3, 298, 140, 0, 1997, 1998, 1, 0, 0, 0, 1998, 1999, 6, 255, 24, 0, 1999, 529, 1, 0, 0, 0, 2000, 2001, 3, 214, 98, 0, 2001, 2002, 1, 0, 0, 0, 2002, 2003, 6, 256, 31, 0, 2003, 531, 1, 0, 0, 0, 2004, 2005, 3, 224, 103, 0, 2005, 2006, 1, 0, 0, 0, 2006, 2007, 6, 257, 22, 0, 2007, 533, 1, 0, 0, 0, 2008, 2009, 3, 228, 105, 0, 2009, 2010, 1, 0, 0, 0, 2010, 2011, 6, 258, 21, 0, 2011, 535, 1, 0, 0, 0, 2012, 2013, 3, 252, 117, 0, 2013, 2014, 1, 0, 0, 0, 2014, 2015, 6, 259, 33, 0, 2015, 537, 1, 0, 0, 0, 2016, 2017, 3, 292, 137, 0, 2017, 2018, 1, 0, 0, 0, 2018, 2019, 6, 260, 34, 0, 2019, 539, 1, 0, 0, 0, 2020, 2021, 3, 288, 135, 0, 2021, 2022, 1, 0, 0, 0, 2022, 2023, 6, 261, 35, 0, 2023, 541, 1, 0, 0, 0, 2024, 2025, 3, 294, 138, 0, 2025, 2026, 1, 0, 0, 0, 2026, 2027, 6, 262, 36, 0, 2027, 543, 1, 0, 0, 0, 2028, 2029, 7, 4, 0, 0, 2029, 2030, 7, 17, 0, 0, 2030, 545, 1, 0, 0, 0, 2031, 2032, 3, 514, 248, 0, 2032, 2033, 1, 0, 0, 0, 2033, 2034, 6, 264, 32, 0, 2034, 547, 1, 0, 0, 0, 2035, 2036, 3, 18, 0, 0, 2036, 2037, 1, 0, 0, 0, 2037, 2038, 6, 265, 0, 0, 2038, 549, 1, 0, 0, 0, 2039, 2040, 3, 20, 1, 0, 2040, 2041, 1, 0, 0, 0, 2041, 2042, 6, 266, 0, 0, 2042, 551, 1, 0, 0, 0, 2043, 2044, 3, 22, 2, 0, 2044, 2045, 1, 0, 0, 0, 2045, 2046, 6, 267, 0, 0, 2046, 553, 1, 0, 0, 0, 2047, 2048, 3, 256, 119, 0, 2048, 2049, 1, 0, 0, 0, 2049, 2050, 6, 268, 45, 0, 2050, 555, 1, 0, 0, 0, 2051, 2052, 3, 230, 106, 0, 2052, 2053, 1, 0, 0, 0, 2053, 2054, 6, 269, 46, 0, 2054, 557, 1, 0, 0, 0, 2055, 2056, 3, 244, 113, 0, 2056, 2057, 1, 0, 0, 0, 2057, 2058, 6, 270, 47, 0, 2058, 559, 1, 0, 0, 0, 2059, 2060, 3, 222, 102, 0, 2060, 2061, 1, 0, 0, 0, 2061, 2062, 6, 271, 48, 0, 2062, 2063, 6, 271, 17, 0, 2063, 561, 1, 0, 0, 0, 2064, 2065, 3, 214, 98, 0, 2065, 2066, 1, 0, 0, 0, 2066, 2067, 6, 272, 31, 0, 2067, 563, 1, 0, 0, 0, 2068, 2069, 3, 204, 93, 0, 2069, 2070, 1, 0, 0, 0, 2070, 2071, 6, 273, 30, 0, 2071, 565, 1, 0, 0, 0, 2072, 2073, 3, 304, 143, 0, 2073, 2074, 1, 0, 0, 0, 2074, 2075, 6, 274, 26, 0, 2075, 567, 1, 0, 0, 0, 2076, 2077, 3, 308, 145, 0, 2077, 2078, 1, 0, 0, 0, 2078, 2079, 6, 275, 25, 0, 2079, 569, 1, 0, 0, 0, 2080, 2081, 3, 208, 95, 0, 2081, 2082, 1, 0, 0, 0, 2082, 2083, 6, 276, 49, 0, 2083, 571, 1, 0, 0, 0, 2084, 2085, 3, 206, 94, 0, 2085, 2086, 1, 0, 0, 0, 2086, 2087, 6, 277, 50, 0, 2087, 573, 1, 0, 0, 0, 2088, 2089, 3, 224, 103, 0, 2089, 2090, 1, 0, 0, 0, 2090, 2091, 6, 278, 22, 0, 2091, 575, 1, 0, 0, 0, 2092, 2093, 3, 228, 105, 0, 2093, 2094, 1, 0, 0, 0, 2094, 2095, 6, 279, 21, 0, 2095, 577, 1, 0, 0, 0, 2096, 2097, 3, 252, 117, 0, 2097, 2098, 1, 0, 0, 0, 2098, 2099, 6, 280, 33, 0, 2099, 579, 1, 0, 0, 0, 2100, 2101, 3, 292, 137, 0, 2101, 2102, 1, 0, 0, 0, 2102, 2103, 6, 281, 34, 0, 2103, 581, 1, 0, 0, 0, 2104, 2105, 3, 288, 135, 0, 2105, 2106, 1, 0, 0, 0, 2106, 2107, 6, 282, 35, 0, 2107, 583, 1, 0, 0, 0, 2108, 2109, 3, 294, 138, 0, 2109, 2110, 1, 0, 0, 0, 2110, 2111, 6, 283, 36, 0, 2111, 585, 1, 0, 0, 0, 2112, 2113, 3, 296, 139, 0, 2113, 2114, 1, 0, 0, 0, 2114, 2115, 6, 284, 23, 0, 2115, 587, 1, 0, 0, 0, 2116, 2117, 3, 298, 140, 0, 2117, 2118, 1, 0, 0, 0, 2118, 2119, 6, 285, 24, 0, 2119, 589, 1, 0, 0, 0, 2120, 2121, 3, 514, 248, 0, 2121, 2122, 1, 0, 0, 0, 2122, 2123, 6, 286, 32, 0, 2123, 591, 1, 0, 0, 0, 2124, 2125, 3, 18, 0, 0, 2125, 2126, 1, 0, 0, 0, 2126, 2127, 6, 287, 0, 0, 2127, 593, 1, 0, 0, 0, 2128, 2129, 3, 20, 1, 0, 2129, 2130, 1, 0, 0, 0, 2130, 2131, 6, 288, 0, 0, 2131, 595, 1, 0, 0, 0, 2132, 2133, 3, 22, 2, 0, 2133, 2134, 1, 0, 0, 0, 2134, 2135, 6, 289, 0, 0, 2135, 597, 1, 0, 0, 0, 2136, 2137, 3, 182, 82, 0, 2137, 2138, 1, 0, 0, 0, 2138, 2139, 6, 290, 16, 0, 2139, 2140, 6, 290, 17, 0, 2140, 599, 1, 0, 0, 0, 2141, 2142, 7, 10, 0, 0, 2142, 2143, 7, 5, 0, 0, 2143, 2144, 7, 21, 0, 0, 2144, 2145, 7, 9, 0, 0, 2145, 601, 1, 0, 0, 0, 2146, 2147, 3, 18, 0, 0, 2147, 2148, 1, 0, 0, 0, 2148, 2149, 6, 292, 0, 0, 2149, 603, 1, 0, 0, 0, 2150, 2151, 3, 20, 1, 0, 2151, 2152, 1, 0, 0, 0, 2152, 2153, 6, 293, 0, 0, 2153, 605, 1, 0, 0, 0, 2154, 2155, 3, 22, 2, 0, 2155, 2156, 1, 0, 0, 0, 2156, 2157, 6, 294, 0, 0, 2157, 607, 1, 0, 0, 0, 70, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 614, 618, 621, 630, 632, 643, 932, 1017, 1021, 1026, 1158, 1163, 1172, 1179, 1184, 1186, 1197, 1205, 1208, 1210, 1215, 1220, 1226, 1233, 1238, 1244, 1247, 1255, 1259, 1400, 1405, 1412, 1414, 1419, 1424, 1431, 1433, 1459, 1464, 1469, 1471, 1477, 1539, 1544, 1940, 1944, 1949, 1954, 1959, 1961, 1965, 1967, 51, 0, 1, 0, 5, 1, 0, 5, 2, 0, 5, 4, 0, 5, 5, 0, 5, 6, 0, 5, 7, 0, 5, 8, 0, 5, 9, 0, 5, 10, 0, 5, 11, 0, 5, 13, 0, 5, 14, 0, 5, 15, 0, 5, 16, 0, 5, 17, 0, 7, 50, 0, 4, 0, 0, 7, 99, 0, 7, 73, 0, 7, 141, 0, 7, 63, 0, 7, 61, 0, 7, 96, 0, 7, 97, 0, 7, 101, 0, 7, 100, 0, 5, 3, 0, 7, 78, 0, 7, 40, 0, 7, 51, 0, 7, 56, 0, 7, 137, 0, 7, 75, 0, 7, 94, 0, 7, 93, 0, 7, 95, 0, 7, 98, 0, 5, 0, 0, 7, 17, 0, 7, 59, 0, 7, 58, 0, 7, 106, 0, 7, 57, 0, 5, 12, 0, 7, 77, 0, 7, 64, 0, 7, 71, 0, 7, 60, 0, 7, 53, 0, 7, 52, 0] \ No newline at end of file +[4, 0, 160, 2347, 6, -1, 6, -1, 6, -1, 6, -1, 6, -1, 6, -1, 6, -1, 6, -1, 6, -1, 6, -1, 6, -1, 6, -1, 6, -1, 6, -1, 6, -1, 6, -1, 6, -1, 6, -1, 6, -1, 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, 2, 26, 7, 26, 2, 27, 7, 27, 2, 28, 7, 28, 2, 29, 7, 29, 2, 30, 7, 30, 2, 31, 7, 31, 2, 32, 7, 32, 2, 33, 7, 33, 2, 34, 7, 34, 2, 35, 7, 35, 2, 36, 7, 36, 2, 37, 7, 37, 2, 38, 7, 38, 2, 39, 7, 39, 2, 40, 7, 40, 2, 41, 7, 41, 2, 42, 7, 42, 2, 43, 7, 43, 2, 44, 7, 44, 2, 45, 7, 45, 2, 46, 7, 46, 2, 47, 7, 47, 2, 48, 7, 48, 2, 49, 7, 49, 2, 50, 7, 50, 2, 51, 7, 51, 2, 52, 7, 52, 2, 53, 7, 53, 2, 54, 7, 54, 2, 55, 7, 55, 2, 56, 7, 56, 2, 57, 7, 57, 2, 58, 7, 58, 2, 59, 7, 59, 2, 60, 7, 60, 2, 61, 7, 61, 2, 62, 7, 62, 2, 63, 7, 63, 2, 64, 7, 64, 2, 65, 7, 65, 2, 66, 7, 66, 2, 67, 7, 67, 2, 68, 7, 68, 2, 69, 7, 69, 2, 70, 7, 70, 2, 71, 7, 71, 2, 72, 7, 72, 2, 73, 7, 73, 2, 74, 7, 74, 2, 75, 7, 75, 2, 76, 7, 76, 2, 77, 7, 77, 2, 78, 7, 78, 2, 79, 7, 79, 2, 80, 7, 80, 2, 81, 7, 81, 2, 82, 7, 82, 2, 83, 7, 83, 2, 84, 7, 84, 2, 85, 7, 85, 2, 86, 7, 86, 2, 87, 7, 87, 2, 88, 7, 88, 2, 89, 7, 89, 2, 90, 7, 90, 2, 91, 7, 91, 2, 92, 7, 92, 2, 93, 7, 93, 2, 94, 7, 94, 2, 95, 7, 95, 2, 96, 7, 96, 2, 97, 7, 97, 2, 98, 7, 98, 2, 99, 7, 99, 2, 100, 7, 100, 2, 101, 7, 101, 2, 102, 7, 102, 2, 103, 7, 103, 2, 104, 7, 104, 2, 105, 7, 105, 2, 106, 7, 106, 2, 107, 7, 107, 2, 108, 7, 108, 2, 109, 7, 109, 2, 110, 7, 110, 2, 111, 7, 111, 2, 112, 7, 112, 2, 113, 7, 113, 2, 114, 7, 114, 2, 115, 7, 115, 2, 116, 7, 116, 2, 117, 7, 117, 2, 118, 7, 118, 2, 119, 7, 119, 2, 120, 7, 120, 2, 121, 7, 121, 2, 122, 7, 122, 2, 123, 7, 123, 2, 124, 7, 124, 2, 125, 7, 125, 2, 126, 7, 126, 2, 127, 7, 127, 2, 128, 7, 128, 2, 129, 7, 129, 2, 130, 7, 130, 2, 131, 7, 131, 2, 132, 7, 132, 2, 133, 7, 133, 2, 134, 7, 134, 2, 135, 7, 135, 2, 136, 7, 136, 2, 137, 7, 137, 2, 138, 7, 138, 2, 139, 7, 139, 2, 140, 7, 140, 2, 141, 7, 141, 2, 142, 7, 142, 2, 143, 7, 143, 2, 144, 7, 144, 2, 145, 7, 145, 2, 146, 7, 146, 2, 147, 7, 147, 2, 148, 7, 148, 2, 149, 7, 149, 2, 150, 7, 150, 2, 151, 7, 151, 2, 152, 7, 152, 2, 153, 7, 153, 2, 154, 7, 154, 2, 155, 7, 155, 2, 156, 7, 156, 2, 157, 7, 157, 2, 158, 7, 158, 2, 159, 7, 159, 2, 160, 7, 160, 2, 161, 7, 161, 2, 162, 7, 162, 2, 163, 7, 163, 2, 164, 7, 164, 2, 165, 7, 165, 2, 166, 7, 166, 2, 167, 7, 167, 2, 168, 7, 168, 2, 169, 7, 169, 2, 170, 7, 170, 2, 171, 7, 171, 2, 172, 7, 172, 2, 173, 7, 173, 2, 174, 7, 174, 2, 175, 7, 175, 2, 176, 7, 176, 2, 177, 7, 177, 2, 178, 7, 178, 2, 179, 7, 179, 2, 180, 7, 180, 2, 181, 7, 181, 2, 182, 7, 182, 2, 183, 7, 183, 2, 184, 7, 184, 2, 185, 7, 185, 2, 186, 7, 186, 2, 187, 7, 187, 2, 188, 7, 188, 2, 189, 7, 189, 2, 190, 7, 190, 2, 191, 7, 191, 2, 192, 7, 192, 2, 193, 7, 193, 2, 194, 7, 194, 2, 195, 7, 195, 2, 196, 7, 196, 2, 197, 7, 197, 2, 198, 7, 198, 2, 199, 7, 199, 2, 200, 7, 200, 2, 201, 7, 201, 2, 202, 7, 202, 2, 203, 7, 203, 2, 204, 7, 204, 2, 205, 7, 205, 2, 206, 7, 206, 2, 207, 7, 207, 2, 208, 7, 208, 2, 209, 7, 209, 2, 210, 7, 210, 2, 211, 7, 211, 2, 212, 7, 212, 2, 213, 7, 213, 2, 214, 7, 214, 2, 215, 7, 215, 2, 216, 7, 216, 2, 217, 7, 217, 2, 218, 7, 218, 2, 219, 7, 219, 2, 220, 7, 220, 2, 221, 7, 221, 2, 222, 7, 222, 2, 223, 7, 223, 2, 224, 7, 224, 2, 225, 7, 225, 2, 226, 7, 226, 2, 227, 7, 227, 2, 228, 7, 228, 2, 229, 7, 229, 2, 230, 7, 230, 2, 231, 7, 231, 2, 232, 7, 232, 2, 233, 7, 233, 2, 234, 7, 234, 2, 235, 7, 235, 2, 236, 7, 236, 2, 237, 7, 237, 2, 238, 7, 238, 2, 239, 7, 239, 2, 240, 7, 240, 2, 241, 7, 241, 2, 242, 7, 242, 2, 243, 7, 243, 2, 244, 7, 244, 2, 245, 7, 245, 2, 246, 7, 246, 2, 247, 7, 247, 2, 248, 7, 248, 2, 249, 7, 249, 2, 250, 7, 250, 2, 251, 7, 251, 2, 252, 7, 252, 2, 253, 7, 253, 2, 254, 7, 254, 2, 255, 7, 255, 2, 256, 7, 256, 2, 257, 7, 257, 2, 258, 7, 258, 2, 259, 7, 259, 2, 260, 7, 260, 2, 261, 7, 261, 2, 262, 7, 262, 2, 263, 7, 263, 2, 264, 7, 264, 2, 265, 7, 265, 2, 266, 7, 266, 2, 267, 7, 267, 2, 268, 7, 268, 2, 269, 7, 269, 2, 270, 7, 270, 2, 271, 7, 271, 2, 272, 7, 272, 2, 273, 7, 273, 2, 274, 7, 274, 2, 275, 7, 275, 2, 276, 7, 276, 2, 277, 7, 277, 2, 278, 7, 278, 2, 279, 7, 279, 2, 280, 7, 280, 2, 281, 7, 281, 2, 282, 7, 282, 2, 283, 7, 283, 2, 284, 7, 284, 2, 285, 7, 285, 2, 286, 7, 286, 2, 287, 7, 287, 2, 288, 7, 288, 2, 289, 7, 289, 2, 290, 7, 290, 2, 291, 7, 291, 2, 292, 7, 292, 2, 293, 7, 293, 2, 294, 7, 294, 2, 295, 7, 295, 2, 296, 7, 296, 2, 297, 7, 297, 2, 298, 7, 298, 2, 299, 7, 299, 2, 300, 7, 300, 2, 301, 7, 301, 2, 302, 7, 302, 2, 303, 7, 303, 2, 304, 7, 304, 2, 305, 7, 305, 2, 306, 7, 306, 2, 307, 7, 307, 2, 308, 7, 308, 2, 309, 7, 309, 2, 310, 7, 310, 2, 311, 7, 311, 2, 312, 7, 312, 2, 313, 7, 313, 2, 314, 7, 314, 1, 0, 1, 0, 1, 0, 1, 0, 5, 0, 655, 8, 0, 10, 0, 12, 0, 658, 9, 0, 1, 0, 3, 0, 661, 8, 0, 1, 0, 3, 0, 664, 8, 0, 1, 0, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 5, 1, 673, 8, 1, 10, 1, 12, 1, 676, 9, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 4, 2, 684, 8, 2, 11, 2, 12, 2, 685, 1, 2, 1, 2, 1, 3, 1, 3, 1, 3, 1, 3, 1, 3, 1, 3, 1, 3, 1, 3, 1, 3, 1, 3, 1, 3, 1, 3, 1, 3, 1, 3, 1, 3, 1, 4, 1, 4, 1, 4, 1, 4, 1, 4, 1, 4, 1, 4, 1, 4, 1, 4, 1, 5, 1, 5, 1, 5, 1, 5, 1, 5, 1, 5, 1, 5, 1, 5, 1, 5, 1, 5, 1, 5, 1, 6, 1, 6, 1, 6, 1, 6, 1, 6, 1, 6, 1, 6, 1, 6, 1, 6, 1, 6, 1, 6, 1, 6, 1, 6, 1, 7, 1, 7, 1, 7, 1, 7, 1, 7, 1, 7, 1, 7, 1, 7, 1, 7, 1, 7, 1, 8, 1, 8, 1, 8, 1, 8, 1, 8, 1, 8, 1, 8, 1, 9, 1, 9, 1, 9, 1, 9, 1, 9, 1, 9, 1, 9, 1, 10, 1, 10, 1, 10, 1, 10, 1, 10, 1, 10, 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, 12, 1, 12, 1, 13, 1, 13, 1, 13, 1, 13, 1, 13, 1, 13, 1, 13, 1, 13, 1, 13, 1, 14, 1, 14, 1, 14, 1, 14, 1, 14, 1, 14, 1, 14, 1, 15, 1, 15, 1, 15, 1, 15, 1, 15, 1, 15, 1, 15, 1, 15, 1, 16, 1, 16, 1, 16, 1, 16, 1, 16, 1, 16, 1, 16, 1, 16, 1, 17, 1, 17, 1, 17, 1, 17, 1, 17, 1, 17, 1, 17, 1, 18, 1, 18, 1, 18, 1, 18, 1, 18, 1, 19, 1, 19, 1, 19, 1, 19, 1, 19, 1, 19, 1, 19, 1, 20, 1, 20, 1, 20, 1, 20, 1, 20, 1, 20, 1, 20, 1, 21, 1, 21, 1, 21, 1, 21, 1, 21, 1, 21, 1, 21, 1, 21, 1, 21, 1, 22, 1, 22, 1, 22, 1, 22, 1, 22, 1, 22, 1, 22, 1, 22, 1, 22, 1, 22, 1, 22, 1, 22, 1, 22, 1, 22, 1, 23, 1, 23, 1, 23, 1, 23, 1, 23, 1, 23, 1, 23, 1, 23, 1, 23, 1, 24, 1, 24, 1, 24, 1, 24, 1, 24, 1, 24, 1, 24, 1, 24, 1, 25, 1, 25, 1, 25, 1, 25, 1, 25, 1, 25, 1, 25, 1, 25, 1, 26, 1, 26, 1, 26, 1, 26, 1, 26, 1, 26, 1, 26, 1, 26, 1, 26, 1, 27, 1, 27, 1, 27, 1, 27, 1, 27, 1, 27, 1, 27, 1, 27, 1, 27, 1, 27, 1, 27, 1, 27, 1, 28, 1, 28, 1, 28, 1, 28, 1, 28, 1, 28, 1, 28, 1, 28, 1, 28, 1, 28, 1, 28, 1, 28, 1, 29, 1, 29, 1, 29, 1, 29, 1, 29, 1, 29, 1, 29, 1, 30, 1, 30, 1, 30, 1, 30, 1, 30, 1, 30, 1, 30, 1, 31, 1, 31, 1, 31, 1, 31, 1, 31, 1, 31, 1, 31, 1, 31, 1, 31, 1, 31, 1, 31, 1, 31, 1, 32, 1, 32, 1, 32, 1, 32, 1, 32, 1, 32, 1, 32, 1, 32, 1, 32, 1, 32, 1, 33, 1, 33, 1, 33, 1, 33, 1, 33, 1, 33, 1, 33, 1, 33, 1, 33, 1, 34, 1, 34, 1, 34, 1, 34, 1, 34, 1, 34, 1, 35, 1, 35, 1, 35, 1, 35, 1, 35, 1, 35, 1, 35, 1, 36, 4, 36, 983, 8, 36, 11, 36, 12, 36, 984, 1, 36, 1, 36, 1, 37, 1, 37, 1, 37, 1, 37, 1, 37, 1, 38, 1, 38, 1, 38, 1, 38, 1, 38, 1, 38, 1, 39, 1, 39, 1, 39, 1, 39, 1, 40, 1, 40, 1, 40, 1, 40, 1, 41, 1, 41, 1, 41, 1, 41, 1, 42, 1, 42, 1, 42, 1, 42, 1, 43, 1, 43, 1, 43, 1, 43, 1, 44, 1, 44, 1, 44, 1, 44, 1, 45, 1, 45, 1, 45, 1, 45, 1, 46, 1, 46, 1, 46, 1, 46, 1, 47, 1, 47, 1, 47, 1, 47, 1, 48, 1, 48, 1, 48, 1, 48, 1, 49, 1, 49, 1, 49, 1, 49, 1, 50, 1, 50, 1, 50, 1, 50, 1, 50, 1, 51, 1, 51, 1, 51, 1, 51, 1, 51, 1, 51, 1, 52, 1, 52, 1, 52, 1, 52, 1, 52, 1, 53, 1, 53, 1, 53, 1, 53, 1, 53, 1, 54, 1, 54, 1, 55, 4, 55, 1068, 8, 55, 11, 55, 12, 55, 1069, 1, 55, 1, 55, 3, 55, 1074, 8, 55, 1, 55, 4, 55, 1077, 8, 55, 11, 55, 12, 55, 1078, 1, 56, 1, 56, 1, 56, 1, 56, 1, 57, 1, 57, 1, 57, 1, 57, 1, 58, 1, 58, 1, 58, 1, 58, 1, 59, 1, 59, 1, 59, 1, 59, 1, 60, 1, 60, 1, 60, 1, 60, 1, 61, 1, 61, 1, 61, 1, 61, 1, 61, 1, 61, 1, 62, 1, 62, 1, 62, 1, 62, 1, 62, 1, 62, 1, 62, 1, 63, 1, 63, 1, 63, 1, 63, 1, 64, 1, 64, 1, 64, 1, 64, 1, 65, 1, 65, 1, 65, 1, 65, 1, 66, 1, 66, 1, 66, 1, 66, 1, 67, 1, 67, 1, 67, 1, 67, 1, 68, 1, 68, 1, 68, 1, 68, 1, 69, 1, 69, 1, 69, 1, 69, 1, 70, 1, 70, 1, 70, 1, 70, 1, 71, 1, 71, 1, 71, 1, 71, 1, 72, 1, 72, 1, 72, 1, 72, 1, 73, 1, 73, 1, 73, 1, 73, 1, 74, 1, 74, 1, 74, 1, 74, 1, 75, 1, 75, 1, 75, 1, 75, 1, 76, 1, 76, 1, 76, 1, 76, 1, 77, 1, 77, 1, 77, 1, 77, 1, 78, 1, 78, 1, 78, 1, 78, 1, 78, 1, 79, 1, 79, 1, 79, 1, 79, 1, 79, 1, 80, 1, 80, 1, 80, 1, 80, 1, 81, 1, 81, 1, 81, 1, 81, 1, 82, 1, 82, 1, 82, 1, 82, 1, 83, 1, 83, 1, 83, 1, 83, 1, 84, 1, 84, 1, 85, 1, 85, 1, 86, 1, 86, 1, 86, 1, 87, 1, 87, 1, 88, 1, 88, 3, 88, 1211, 8, 88, 1, 88, 4, 88, 1214, 8, 88, 11, 88, 12, 88, 1215, 1, 89, 1, 89, 1, 90, 1, 90, 1, 91, 1, 91, 1, 91, 3, 91, 1225, 8, 91, 1, 92, 1, 92, 1, 93, 1, 93, 1, 93, 3, 93, 1232, 8, 93, 1, 94, 1, 94, 1, 94, 5, 94, 1237, 8, 94, 10, 94, 12, 94, 1240, 9, 94, 1, 94, 1, 94, 1, 94, 1, 94, 1, 94, 1, 94, 5, 94, 1248, 8, 94, 10, 94, 12, 94, 1251, 9, 94, 1, 94, 1, 94, 1, 94, 1, 94, 1, 94, 3, 94, 1258, 8, 94, 1, 94, 3, 94, 1261, 8, 94, 3, 94, 1263, 8, 94, 1, 95, 4, 95, 1266, 8, 95, 11, 95, 12, 95, 1267, 1, 96, 4, 96, 1271, 8, 96, 11, 96, 12, 96, 1272, 1, 96, 1, 96, 5, 96, 1277, 8, 96, 10, 96, 12, 96, 1280, 9, 96, 1, 96, 1, 96, 4, 96, 1284, 8, 96, 11, 96, 12, 96, 1285, 1, 96, 4, 96, 1289, 8, 96, 11, 96, 12, 96, 1290, 1, 96, 1, 96, 5, 96, 1295, 8, 96, 10, 96, 12, 96, 1298, 9, 96, 3, 96, 1300, 8, 96, 1, 96, 1, 96, 1, 96, 1, 96, 4, 96, 1306, 8, 96, 11, 96, 12, 96, 1307, 1, 96, 1, 96, 3, 96, 1312, 8, 96, 1, 97, 1, 97, 1, 97, 1, 97, 1, 98, 1, 98, 1, 98, 1, 98, 1, 99, 1, 99, 1, 100, 1, 100, 1, 100, 1, 101, 1, 101, 1, 101, 1, 102, 1, 102, 1, 103, 1, 103, 1, 104, 1, 104, 1, 105, 1, 105, 1, 105, 1, 105, 1, 105, 1, 106, 1, 106, 1, 107, 1, 107, 1, 107, 1, 107, 1, 107, 1, 107, 1, 108, 1, 108, 1, 108, 1, 108, 1, 108, 1, 108, 1, 109, 1, 109, 1, 109, 1, 110, 1, 110, 1, 110, 1, 111, 1, 111, 1, 111, 1, 111, 1, 111, 1, 112, 1, 112, 1, 112, 1, 112, 1, 112, 1, 113, 1, 113, 1, 113, 1, 113, 1, 114, 1, 114, 1, 114, 1, 114, 1, 114, 1, 115, 1, 115, 1, 115, 1, 115, 1, 115, 1, 115, 1, 116, 1, 116, 1, 116, 1, 117, 1, 117, 1, 117, 1, 118, 1, 118, 1, 119, 1, 119, 1, 119, 1, 119, 1, 119, 1, 119, 1, 120, 1, 120, 1, 120, 1, 120, 1, 120, 1, 121, 1, 121, 1, 121, 1, 121, 1, 121, 1, 122, 1, 122, 1, 122, 1, 123, 1, 123, 1, 123, 1, 124, 1, 124, 1, 124, 1, 125, 1, 125, 1, 126, 1, 126, 1, 126, 1, 127, 1, 127, 1, 128, 1, 128, 1, 128, 1, 129, 1, 129, 1, 130, 1, 130, 1, 131, 1, 131, 1, 132, 1, 132, 1, 133, 1, 133, 1, 134, 1, 134, 1, 135, 1, 135, 1, 136, 1, 136, 1, 136, 1, 137, 1, 137, 1, 137, 1, 137, 1, 138, 1, 138, 1, 138, 3, 138, 1453, 8, 138, 1, 138, 5, 138, 1456, 8, 138, 10, 138, 12, 138, 1459, 9, 138, 1, 138, 1, 138, 4, 138, 1463, 8, 138, 11, 138, 12, 138, 1464, 3, 138, 1467, 8, 138, 1, 139, 1, 139, 1, 139, 3, 139, 1472, 8, 139, 1, 139, 5, 139, 1475, 8, 139, 10, 139, 12, 139, 1478, 9, 139, 1, 139, 1, 139, 4, 139, 1482, 8, 139, 11, 139, 12, 139, 1483, 3, 139, 1486, 8, 139, 1, 140, 1, 140, 1, 140, 1, 140, 1, 140, 1, 141, 1, 141, 1, 141, 1, 141, 1, 141, 1, 142, 1, 142, 1, 142, 1, 142, 1, 142, 1, 143, 1, 143, 1, 143, 1, 143, 1, 143, 1, 144, 1, 144, 5, 144, 1510, 8, 144, 10, 144, 12, 144, 1513, 9, 144, 1, 144, 1, 144, 3, 144, 1517, 8, 144, 1, 144, 4, 144, 1520, 8, 144, 11, 144, 12, 144, 1521, 3, 144, 1524, 8, 144, 1, 145, 1, 145, 4, 145, 1528, 8, 145, 11, 145, 12, 145, 1529, 1, 145, 1, 145, 1, 146, 1, 146, 1, 147, 1, 147, 1, 147, 1, 147, 1, 148, 1, 148, 1, 148, 1, 148, 1, 149, 1, 149, 1, 149, 1, 149, 1, 150, 1, 150, 1, 150, 1, 150, 1, 150, 1, 151, 1, 151, 1, 151, 1, 151, 1, 152, 1, 152, 1, 152, 1, 152, 1, 153, 1, 153, 1, 153, 1, 153, 1, 154, 1, 154, 1, 154, 1, 154, 1, 155, 1, 155, 1, 155, 1, 155, 1, 155, 1, 155, 1, 155, 1, 155, 1, 155, 1, 156, 1, 156, 1, 156, 1, 156, 1, 156, 1, 156, 1, 157, 1, 157, 1, 157, 1, 157, 1, 157, 1, 158, 1, 158, 1, 158, 3, 158, 1592, 8, 158, 1, 159, 4, 159, 1595, 8, 159, 11, 159, 12, 159, 1596, 1, 160, 1, 160, 1, 160, 1, 160, 1, 161, 1, 161, 1, 161, 1, 161, 1, 162, 1, 162, 1, 162, 1, 162, 1, 163, 1, 163, 1, 163, 1, 163, 1, 164, 1, 164, 1, 164, 1, 164, 1, 165, 1, 165, 1, 165, 1, 165, 1, 165, 1, 166, 1, 166, 1, 166, 1, 166, 1, 166, 1, 166, 1, 167, 1, 167, 1, 167, 1, 167, 1, 167, 1, 168, 1, 168, 1, 168, 1, 168, 1, 169, 1, 169, 1, 169, 1, 169, 1, 170, 1, 170, 1, 170, 1, 170, 1, 171, 1, 171, 1, 171, 1, 171, 1, 171, 1, 172, 1, 172, 1, 172, 1, 172, 1, 172, 1, 172, 1, 173, 1, 173, 1, 173, 1, 173, 1, 173, 1, 173, 1, 174, 1, 174, 1, 174, 1, 174, 1, 174, 1, 174, 1, 175, 1, 175, 1, 175, 1, 175, 1, 176, 1, 176, 1, 176, 1, 176, 1, 176, 1, 176, 1, 177, 1, 177, 1, 177, 1, 177, 1, 178, 1, 178, 1, 178, 1, 178, 1, 179, 1, 179, 1, 179, 1, 179, 1, 180, 1, 180, 1, 180, 1, 180, 1, 181, 1, 181, 1, 181, 1, 181, 1, 182, 1, 182, 1, 182, 1, 182, 1, 183, 1, 183, 1, 183, 1, 183, 1, 184, 1, 184, 1, 184, 1, 184, 1, 185, 1, 185, 1, 185, 1, 185, 1, 186, 1, 186, 1, 186, 1, 186, 1, 187, 1, 187, 1, 187, 1, 187, 1, 188, 1, 188, 1, 188, 1, 188, 1, 189, 1, 189, 1, 189, 1, 189, 1, 189, 1, 189, 1, 189, 1, 189, 1, 189, 1, 190, 1, 190, 1, 190, 1, 190, 1, 191, 1, 191, 1, 191, 1, 191, 1, 192, 1, 192, 1, 192, 1, 192, 1, 193, 1, 193, 1, 193, 1, 193, 1, 193, 1, 194, 1, 194, 1, 194, 1, 194, 1, 194, 1, 195, 1, 195, 1, 195, 1, 195, 1, 196, 1, 196, 1, 196, 1, 196, 1, 196, 1, 196, 1, 197, 1, 197, 1, 197, 1, 197, 1, 197, 1, 197, 1, 197, 1, 197, 1, 197, 1, 198, 1, 198, 1, 198, 1, 198, 1, 199, 1, 199, 1, 199, 1, 199, 1, 200, 1, 200, 1, 200, 1, 200, 1, 201, 1, 201, 1, 201, 1, 201, 1, 202, 1, 202, 1, 202, 1, 202, 1, 203, 1, 203, 1, 203, 1, 203, 1, 204, 1, 204, 1, 204, 1, 204, 1, 204, 1, 205, 1, 205, 1, 205, 1, 205, 1, 205, 1, 205, 1, 206, 1, 206, 1, 206, 1, 206, 1, 207, 1, 207, 1, 207, 1, 207, 1, 208, 1, 208, 1, 208, 1, 208, 1, 209, 1, 209, 1, 209, 1, 209, 1, 209, 1, 210, 1, 210, 1, 210, 1, 210, 1, 211, 1, 211, 1, 211, 1, 211, 1, 212, 1, 212, 1, 212, 1, 212, 1, 213, 1, 213, 1, 213, 1, 213, 1, 214, 1, 214, 1, 214, 1, 214, 1, 215, 1, 215, 1, 215, 1, 215, 1, 215, 1, 215, 1, 216, 1, 216, 1, 216, 1, 216, 1, 216, 1, 216, 1, 216, 1, 217, 1, 217, 1, 217, 1, 217, 1, 218, 1, 218, 1, 218, 1, 218, 1, 219, 1, 219, 1, 219, 1, 219, 1, 220, 1, 220, 1, 220, 1, 220, 1, 221, 1, 221, 1, 221, 1, 221, 1, 222, 1, 222, 1, 222, 1, 222, 1, 223, 1, 223, 1, 223, 1, 223, 1, 223, 1, 224, 1, 224, 1, 224, 1, 224, 1, 224, 1, 224, 1, 225, 1, 225, 1, 225, 1, 225, 1, 226, 1, 226, 1, 226, 1, 226, 1, 227, 1, 227, 1, 227, 1, 227, 1, 228, 1, 228, 1, 228, 1, 228, 1, 229, 1, 229, 1, 229, 1, 229, 1, 230, 1, 230, 1, 230, 1, 230, 1, 231, 1, 231, 1, 231, 1, 231, 1, 232, 1, 232, 1, 232, 1, 232, 1, 233, 1, 233, 1, 233, 1, 233, 1, 234, 1, 234, 1, 234, 1, 234, 1, 235, 1, 235, 1, 235, 1, 235, 1, 236, 1, 236, 1, 236, 1, 236, 1, 237, 1, 237, 1, 237, 1, 237, 1, 237, 1, 238, 1, 238, 1, 238, 1, 238, 1, 238, 1, 238, 1, 239, 1, 239, 1, 239, 1, 239, 1, 240, 1, 240, 1, 240, 1, 240, 1, 241, 1, 241, 1, 241, 1, 241, 1, 242, 1, 242, 1, 242, 1, 242, 1, 243, 1, 243, 1, 243, 1, 243, 1, 244, 1, 244, 1, 244, 1, 244, 1, 245, 1, 245, 1, 245, 1, 245, 1, 246, 1, 246, 1, 246, 1, 246, 1, 247, 1, 247, 1, 247, 1, 247, 3, 247, 1993, 8, 247, 1, 248, 1, 248, 3, 248, 1997, 8, 248, 1, 248, 5, 248, 2000, 8, 248, 10, 248, 12, 248, 2003, 9, 248, 1, 248, 1, 248, 3, 248, 2007, 8, 248, 1, 248, 4, 248, 2010, 8, 248, 11, 248, 12, 248, 2011, 3, 248, 2014, 8, 248, 1, 249, 1, 249, 4, 249, 2018, 8, 249, 11, 249, 12, 249, 2019, 1, 250, 1, 250, 1, 250, 1, 250, 1, 251, 1, 251, 1, 251, 1, 251, 1, 252, 1, 252, 1, 252, 1, 252, 1, 253, 1, 253, 5, 253, 2036, 8, 253, 10, 253, 12, 253, 2039, 9, 253, 1, 253, 1, 253, 4, 253, 2043, 8, 253, 11, 253, 12, 253, 2044, 3, 253, 2047, 8, 253, 1, 254, 1, 254, 1, 254, 1, 254, 1, 255, 1, 255, 1, 255, 1, 255, 1, 256, 1, 256, 1, 256, 1, 256, 1, 257, 1, 257, 1, 257, 1, 257, 1, 257, 1, 258, 1, 258, 1, 258, 1, 258, 1, 258, 1, 258, 1, 259, 1, 259, 1, 259, 1, 259, 1, 260, 1, 260, 1, 260, 1, 260, 1, 261, 1, 261, 1, 261, 1, 261, 1, 262, 1, 262, 1, 262, 1, 262, 1, 262, 1, 263, 1, 263, 1, 263, 4, 263, 2092, 8, 263, 11, 263, 12, 263, 2093, 1, 264, 1, 264, 1, 264, 1, 264, 5, 264, 2100, 8, 264, 10, 264, 12, 264, 2103, 9, 264, 1, 264, 1, 264, 1, 264, 1, 264, 1, 264, 5, 264, 2110, 8, 264, 10, 264, 12, 264, 2113, 9, 264, 1, 264, 1, 264, 1, 264, 5, 264, 2118, 8, 264, 10, 264, 12, 264, 2121, 9, 264, 1, 264, 3, 264, 2124, 8, 264, 1, 265, 1, 265, 5, 265, 2128, 8, 265, 10, 265, 12, 265, 2131, 9, 265, 1, 265, 3, 265, 2134, 8, 265, 1, 265, 3, 265, 2137, 8, 265, 1, 266, 1, 266, 1, 266, 1, 266, 1, 266, 1, 266, 1, 267, 1, 267, 1, 267, 1, 267, 1, 267, 1, 267, 1, 267, 1, 267, 1, 268, 1, 268, 1, 268, 1, 268, 1, 268, 1, 268, 1, 269, 1, 269, 1, 269, 1, 269, 1, 270, 1, 270, 1, 270, 1, 270, 1, 271, 1, 271, 1, 271, 1, 271, 1, 272, 1, 272, 1, 272, 1, 272, 1, 272, 1, 273, 1, 273, 1, 273, 1, 273, 1, 273, 1, 273, 1, 274, 1, 274, 1, 274, 1, 274, 1, 275, 1, 275, 1, 275, 1, 275, 1, 276, 1, 276, 1, 276, 1, 276, 1, 277, 1, 277, 1, 277, 1, 277, 1, 278, 1, 278, 1, 278, 1, 278, 1, 279, 1, 279, 1, 279, 1, 279, 1, 280, 1, 280, 1, 280, 1, 280, 1, 281, 1, 281, 1, 281, 1, 281, 1, 282, 1, 282, 1, 282, 1, 282, 1, 283, 1, 283, 1, 283, 1, 284, 1, 284, 1, 284, 1, 284, 1, 285, 1, 285, 1, 285, 1, 285, 1, 286, 1, 286, 1, 286, 1, 286, 1, 287, 1, 287, 1, 287, 1, 287, 1, 288, 1, 288, 1, 288, 1, 288, 1, 289, 1, 289, 1, 289, 1, 289, 1, 290, 1, 290, 1, 290, 1, 290, 1, 291, 1, 291, 1, 291, 1, 291, 1, 291, 1, 292, 1, 292, 1, 292, 1, 292, 1, 293, 1, 293, 1, 293, 1, 293, 1, 294, 1, 294, 1, 294, 1, 294, 1, 295, 1, 295, 1, 295, 1, 295, 1, 296, 1, 296, 1, 296, 1, 296, 1, 297, 1, 297, 1, 297, 1, 297, 1, 298, 1, 298, 1, 298, 1, 298, 1, 299, 1, 299, 1, 299, 1, 299, 1, 300, 1, 300, 1, 300, 1, 300, 1, 301, 1, 301, 1, 301, 1, 301, 1, 302, 1, 302, 1, 302, 1, 302, 1, 303, 1, 303, 1, 303, 1, 303, 1, 304, 1, 304, 1, 304, 1, 304, 1, 305, 1, 305, 1, 305, 1, 305, 1, 306, 1, 306, 1, 306, 1, 306, 1, 307, 1, 307, 1, 307, 1, 307, 1, 308, 1, 308, 1, 308, 1, 308, 1, 309, 1, 309, 1, 309, 1, 309, 1, 310, 1, 310, 1, 310, 1, 310, 1, 310, 1, 311, 1, 311, 1, 311, 1, 311, 1, 311, 1, 312, 1, 312, 1, 312, 1, 312, 1, 313, 1, 313, 1, 313, 1, 313, 1, 314, 1, 314, 1, 314, 1, 314, 2, 674, 1249, 0, 315, 20, 1, 22, 2, 24, 3, 26, 4, 28, 5, 30, 6, 32, 7, 34, 8, 36, 9, 38, 10, 40, 11, 42, 12, 44, 13, 46, 14, 48, 15, 50, 16, 52, 17, 54, 18, 56, 19, 58, 20, 60, 21, 62, 22, 64, 23, 66, 24, 68, 25, 70, 26, 72, 27, 74, 28, 76, 29, 78, 30, 80, 31, 82, 32, 84, 33, 86, 34, 88, 35, 90, 36, 92, 37, 94, 0, 96, 0, 98, 0, 100, 0, 102, 0, 104, 0, 106, 0, 108, 0, 110, 0, 112, 0, 114, 38, 116, 39, 118, 40, 120, 0, 122, 0, 124, 0, 126, 0, 128, 0, 130, 41, 132, 0, 134, 0, 136, 42, 138, 43, 140, 44, 142, 0, 144, 0, 146, 0, 148, 0, 150, 0, 152, 0, 154, 0, 156, 0, 158, 0, 160, 0, 162, 0, 164, 0, 166, 0, 168, 0, 170, 45, 172, 46, 174, 47, 176, 0, 178, 0, 180, 48, 182, 49, 184, 50, 186, 51, 188, 0, 190, 0, 192, 0, 194, 0, 196, 0, 198, 0, 200, 0, 202, 0, 204, 0, 206, 0, 208, 52, 210, 53, 212, 54, 214, 55, 216, 56, 218, 57, 220, 58, 222, 59, 224, 60, 226, 61, 228, 62, 230, 63, 232, 64, 234, 65, 236, 66, 238, 67, 240, 68, 242, 69, 244, 70, 246, 71, 248, 72, 250, 73, 252, 74, 254, 75, 256, 76, 258, 77, 260, 78, 262, 79, 264, 80, 266, 81, 268, 82, 270, 83, 272, 84, 274, 85, 276, 86, 278, 87, 280, 88, 282, 89, 284, 90, 286, 91, 288, 92, 290, 93, 292, 94, 294, 0, 296, 95, 298, 96, 300, 97, 302, 98, 304, 99, 306, 100, 308, 101, 310, 0, 312, 102, 314, 103, 316, 104, 318, 105, 320, 0, 322, 0, 324, 0, 326, 0, 328, 0, 330, 106, 332, 0, 334, 0, 336, 0, 338, 107, 340, 0, 342, 0, 344, 108, 346, 109, 348, 110, 350, 0, 352, 0, 354, 0, 356, 111, 358, 112, 360, 113, 362, 0, 364, 0, 366, 114, 368, 115, 370, 116, 372, 0, 374, 0, 376, 0, 378, 0, 380, 0, 382, 0, 384, 0, 386, 0, 388, 0, 390, 0, 392, 117, 394, 118, 396, 119, 398, 120, 400, 121, 402, 122, 404, 123, 406, 0, 408, 124, 410, 0, 412, 0, 414, 125, 416, 0, 418, 0, 420, 0, 422, 126, 424, 127, 426, 128, 428, 0, 430, 0, 432, 0, 434, 0, 436, 0, 438, 0, 440, 0, 442, 0, 444, 129, 446, 130, 448, 131, 450, 0, 452, 0, 454, 0, 456, 0, 458, 0, 460, 132, 462, 133, 464, 134, 466, 0, 468, 0, 470, 0, 472, 0, 474, 0, 476, 0, 478, 0, 480, 0, 482, 0, 484, 0, 486, 0, 488, 135, 490, 136, 492, 137, 494, 0, 496, 0, 498, 0, 500, 0, 502, 0, 504, 0, 506, 0, 508, 0, 510, 0, 512, 0, 514, 0, 516, 0, 518, 138, 520, 139, 522, 140, 524, 141, 526, 142, 528, 0, 530, 0, 532, 0, 534, 0, 536, 0, 538, 143, 540, 144, 542, 145, 544, 0, 546, 146, 548, 0, 550, 0, 552, 0, 554, 0, 556, 0, 558, 147, 560, 148, 562, 149, 564, 0, 566, 0, 568, 0, 570, 0, 572, 0, 574, 0, 576, 0, 578, 0, 580, 0, 582, 0, 584, 0, 586, 150, 588, 0, 590, 151, 592, 152, 594, 153, 596, 0, 598, 0, 600, 0, 602, 0, 604, 0, 606, 0, 608, 0, 610, 0, 612, 0, 614, 0, 616, 0, 618, 0, 620, 0, 622, 0, 624, 0, 626, 0, 628, 0, 630, 0, 632, 0, 634, 154, 636, 155, 638, 156, 640, 0, 642, 157, 644, 158, 646, 159, 648, 160, 20, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 43, 2, 0, 10, 10, 13, 13, 3, 0, 9, 10, 13, 13, 32, 32, 2, 0, 67, 67, 99, 99, 2, 0, 72, 72, 104, 104, 2, 0, 65, 65, 97, 97, 2, 0, 78, 78, 110, 110, 2, 0, 71, 71, 103, 103, 2, 0, 69, 69, 101, 101, 2, 0, 80, 80, 112, 112, 2, 0, 79, 79, 111, 111, 2, 0, 73, 73, 105, 105, 2, 0, 84, 84, 116, 116, 2, 0, 82, 82, 114, 114, 2, 0, 88, 88, 120, 120, 2, 0, 76, 76, 108, 108, 2, 0, 77, 77, 109, 109, 2, 0, 68, 68, 100, 100, 2, 0, 83, 83, 115, 115, 2, 0, 86, 86, 118, 118, 2, 0, 75, 75, 107, 107, 2, 0, 87, 87, 119, 119, 2, 0, 70, 70, 102, 102, 2, 0, 85, 85, 117, 117, 2, 0, 81, 81, 113, 113, 6, 0, 9, 10, 13, 13, 32, 32, 47, 47, 91, 91, 93, 93, 12, 0, 9, 10, 13, 13, 32, 32, 34, 35, 40, 41, 44, 44, 47, 47, 58, 58, 60, 60, 62, 63, 92, 92, 124, 124, 1, 0, 48, 57, 2, 0, 65, 90, 97, 122, 8, 0, 34, 34, 78, 78, 82, 82, 84, 84, 92, 92, 110, 110, 114, 114, 116, 116, 4, 0, 10, 10, 13, 13, 34, 34, 92, 92, 2, 0, 43, 43, 45, 45, 1, 0, 96, 96, 2, 0, 66, 66, 98, 98, 2, 0, 89, 89, 121, 121, 12, 0, 9, 10, 13, 13, 32, 32, 34, 34, 40, 41, 44, 44, 47, 47, 58, 58, 61, 61, 91, 91, 93, 93, 124, 124, 2, 0, 42, 42, 47, 47, 2, 0, 74, 74, 106, 106, 3, 0, 48, 57, 65, 90, 97, 122, 4, 0, 48, 57, 65, 90, 95, 95, 97, 122, 2, 0, 64, 64, 95, 95, 6, 0, 10, 10, 13, 13, 34, 35, 39, 41, 96, 96, 124, 124, 2, 0, 34, 34, 92, 92, 2, 0, 39, 39, 92, 92, 2383, 0, 20, 1, 0, 0, 0, 0, 22, 1, 0, 0, 0, 0, 24, 1, 0, 0, 0, 0, 26, 1, 0, 0, 0, 0, 28, 1, 0, 0, 0, 0, 30, 1, 0, 0, 0, 0, 32, 1, 0, 0, 0, 0, 34, 1, 0, 0, 0, 0, 36, 1, 0, 0, 0, 0, 38, 1, 0, 0, 0, 0, 40, 1, 0, 0, 0, 0, 42, 1, 0, 0, 0, 0, 44, 1, 0, 0, 0, 0, 46, 1, 0, 0, 0, 0, 48, 1, 0, 0, 0, 0, 50, 1, 0, 0, 0, 0, 52, 1, 0, 0, 0, 0, 54, 1, 0, 0, 0, 0, 56, 1, 0, 0, 0, 0, 58, 1, 0, 0, 0, 0, 60, 1, 0, 0, 0, 0, 62, 1, 0, 0, 0, 0, 64, 1, 0, 0, 0, 0, 66, 1, 0, 0, 0, 0, 68, 1, 0, 0, 0, 0, 70, 1, 0, 0, 0, 0, 72, 1, 0, 0, 0, 0, 74, 1, 0, 0, 0, 0, 76, 1, 0, 0, 0, 0, 78, 1, 0, 0, 0, 0, 80, 1, 0, 0, 0, 0, 82, 1, 0, 0, 0, 0, 84, 1, 0, 0, 0, 0, 86, 1, 0, 0, 0, 0, 88, 1, 0, 0, 0, 0, 90, 1, 0, 0, 0, 0, 92, 1, 0, 0, 0, 1, 94, 1, 0, 0, 0, 1, 96, 1, 0, 0, 0, 1, 98, 1, 0, 0, 0, 1, 100, 1, 0, 0, 0, 1, 102, 1, 0, 0, 0, 1, 104, 1, 0, 0, 0, 1, 106, 1, 0, 0, 0, 1, 108, 1, 0, 0, 0, 1, 110, 1, 0, 0, 0, 1, 112, 1, 0, 0, 0, 1, 114, 1, 0, 0, 0, 1, 116, 1, 0, 0, 0, 1, 118, 1, 0, 0, 0, 2, 120, 1, 0, 0, 0, 2, 122, 1, 0, 0, 0, 2, 124, 1, 0, 0, 0, 2, 126, 1, 0, 0, 0, 2, 130, 1, 0, 0, 0, 2, 132, 1, 0, 0, 0, 2, 134, 1, 0, 0, 0, 2, 136, 1, 0, 0, 0, 2, 138, 1, 0, 0, 0, 2, 140, 1, 0, 0, 0, 3, 142, 1, 0, 0, 0, 3, 144, 1, 0, 0, 0, 3, 146, 1, 0, 0, 0, 3, 148, 1, 0, 0, 0, 3, 150, 1, 0, 0, 0, 3, 152, 1, 0, 0, 0, 3, 154, 1, 0, 0, 0, 3, 156, 1, 0, 0, 0, 3, 158, 1, 0, 0, 0, 3, 160, 1, 0, 0, 0, 3, 162, 1, 0, 0, 0, 3, 164, 1, 0, 0, 0, 3, 166, 1, 0, 0, 0, 3, 168, 1, 0, 0, 0, 3, 170, 1, 0, 0, 0, 3, 172, 1, 0, 0, 0, 3, 174, 1, 0, 0, 0, 4, 176, 1, 0, 0, 0, 4, 178, 1, 0, 0, 0, 4, 180, 1, 0, 0, 0, 4, 182, 1, 0, 0, 0, 4, 184, 1, 0, 0, 0, 5, 186, 1, 0, 0, 0, 5, 208, 1, 0, 0, 0, 5, 210, 1, 0, 0, 0, 5, 212, 1, 0, 0, 0, 5, 214, 1, 0, 0, 0, 5, 216, 1, 0, 0, 0, 5, 218, 1, 0, 0, 0, 5, 220, 1, 0, 0, 0, 5, 222, 1, 0, 0, 0, 5, 224, 1, 0, 0, 0, 5, 226, 1, 0, 0, 0, 5, 228, 1, 0, 0, 0, 5, 230, 1, 0, 0, 0, 5, 232, 1, 0, 0, 0, 5, 234, 1, 0, 0, 0, 5, 236, 1, 0, 0, 0, 5, 238, 1, 0, 0, 0, 5, 240, 1, 0, 0, 0, 5, 242, 1, 0, 0, 0, 5, 244, 1, 0, 0, 0, 5, 246, 1, 0, 0, 0, 5, 248, 1, 0, 0, 0, 5, 250, 1, 0, 0, 0, 5, 252, 1, 0, 0, 0, 5, 254, 1, 0, 0, 0, 5, 256, 1, 0, 0, 0, 5, 258, 1, 0, 0, 0, 5, 260, 1, 0, 0, 0, 5, 262, 1, 0, 0, 0, 5, 264, 1, 0, 0, 0, 5, 266, 1, 0, 0, 0, 5, 268, 1, 0, 0, 0, 5, 270, 1, 0, 0, 0, 5, 272, 1, 0, 0, 0, 5, 274, 1, 0, 0, 0, 5, 276, 1, 0, 0, 0, 5, 278, 1, 0, 0, 0, 5, 280, 1, 0, 0, 0, 5, 282, 1, 0, 0, 0, 5, 284, 1, 0, 0, 0, 5, 286, 1, 0, 0, 0, 5, 288, 1, 0, 0, 0, 5, 290, 1, 0, 0, 0, 5, 292, 1, 0, 0, 0, 5, 294, 1, 0, 0, 0, 5, 296, 1, 0, 0, 0, 5, 298, 1, 0, 0, 0, 5, 300, 1, 0, 0, 0, 5, 302, 1, 0, 0, 0, 5, 304, 1, 0, 0, 0, 5, 306, 1, 0, 0, 0, 5, 308, 1, 0, 0, 0, 5, 312, 1, 0, 0, 0, 5, 314, 1, 0, 0, 0, 5, 316, 1, 0, 0, 0, 5, 318, 1, 0, 0, 0, 6, 320, 1, 0, 0, 0, 6, 322, 1, 0, 0, 0, 6, 324, 1, 0, 0, 0, 6, 326, 1, 0, 0, 0, 6, 328, 1, 0, 0, 0, 6, 330, 1, 0, 0, 0, 6, 332, 1, 0, 0, 0, 6, 334, 1, 0, 0, 0, 6, 338, 1, 0, 0, 0, 6, 340, 1, 0, 0, 0, 6, 342, 1, 0, 0, 0, 6, 344, 1, 0, 0, 0, 6, 346, 1, 0, 0, 0, 6, 348, 1, 0, 0, 0, 7, 350, 1, 0, 0, 0, 7, 352, 1, 0, 0, 0, 7, 354, 1, 0, 0, 0, 7, 356, 1, 0, 0, 0, 7, 358, 1, 0, 0, 0, 7, 360, 1, 0, 0, 0, 8, 362, 1, 0, 0, 0, 8, 364, 1, 0, 0, 0, 8, 366, 1, 0, 0, 0, 8, 368, 1, 0, 0, 0, 8, 370, 1, 0, 0, 0, 8, 372, 1, 0, 0, 0, 8, 374, 1, 0, 0, 0, 8, 376, 1, 0, 0, 0, 8, 378, 1, 0, 0, 0, 8, 380, 1, 0, 0, 0, 8, 382, 1, 0, 0, 0, 8, 384, 1, 0, 0, 0, 8, 386, 1, 0, 0, 0, 8, 388, 1, 0, 0, 0, 8, 390, 1, 0, 0, 0, 8, 392, 1, 0, 0, 0, 8, 394, 1, 0, 0, 0, 8, 396, 1, 0, 0, 0, 9, 398, 1, 0, 0, 0, 9, 400, 1, 0, 0, 0, 9, 402, 1, 0, 0, 0, 9, 404, 1, 0, 0, 0, 10, 406, 1, 0, 0, 0, 10, 408, 1, 0, 0, 0, 10, 410, 1, 0, 0, 0, 10, 412, 1, 0, 0, 0, 10, 414, 1, 0, 0, 0, 10, 416, 1, 0, 0, 0, 10, 418, 1, 0, 0, 0, 10, 420, 1, 0, 0, 0, 10, 422, 1, 0, 0, 0, 10, 424, 1, 0, 0, 0, 10, 426, 1, 0, 0, 0, 11, 428, 1, 0, 0, 0, 11, 430, 1, 0, 0, 0, 11, 432, 1, 0, 0, 0, 11, 434, 1, 0, 0, 0, 11, 436, 1, 0, 0, 0, 11, 438, 1, 0, 0, 0, 11, 440, 1, 0, 0, 0, 11, 442, 1, 0, 0, 0, 11, 444, 1, 0, 0, 0, 11, 446, 1, 0, 0, 0, 11, 448, 1, 0, 0, 0, 12, 450, 1, 0, 0, 0, 12, 452, 1, 0, 0, 0, 12, 454, 1, 0, 0, 0, 12, 456, 1, 0, 0, 0, 12, 458, 1, 0, 0, 0, 12, 460, 1, 0, 0, 0, 12, 462, 1, 0, 0, 0, 12, 464, 1, 0, 0, 0, 13, 466, 1, 0, 0, 0, 13, 468, 1, 0, 0, 0, 13, 470, 1, 0, 0, 0, 13, 472, 1, 0, 0, 0, 13, 474, 1, 0, 0, 0, 13, 476, 1, 0, 0, 0, 13, 478, 1, 0, 0, 0, 13, 480, 1, 0, 0, 0, 13, 482, 1, 0, 0, 0, 13, 484, 1, 0, 0, 0, 13, 486, 1, 0, 0, 0, 13, 488, 1, 0, 0, 0, 13, 490, 1, 0, 0, 0, 13, 492, 1, 0, 0, 0, 14, 494, 1, 0, 0, 0, 14, 496, 1, 0, 0, 0, 14, 498, 1, 0, 0, 0, 14, 500, 1, 0, 0, 0, 14, 502, 1, 0, 0, 0, 14, 504, 1, 0, 0, 0, 14, 506, 1, 0, 0, 0, 14, 508, 1, 0, 0, 0, 14, 510, 1, 0, 0, 0, 14, 512, 1, 0, 0, 0, 14, 518, 1, 0, 0, 0, 14, 520, 1, 0, 0, 0, 14, 522, 1, 0, 0, 0, 14, 524, 1, 0, 0, 0, 15, 526, 1, 0, 0, 0, 15, 528, 1, 0, 0, 0, 15, 530, 1, 0, 0, 0, 15, 532, 1, 0, 0, 0, 15, 534, 1, 0, 0, 0, 15, 536, 1, 0, 0, 0, 15, 538, 1, 0, 0, 0, 15, 540, 1, 0, 0, 0, 15, 542, 1, 0, 0, 0, 16, 544, 1, 0, 0, 0, 16, 546, 1, 0, 0, 0, 16, 552, 1, 0, 0, 0, 16, 554, 1, 0, 0, 0, 16, 556, 1, 0, 0, 0, 16, 558, 1, 0, 0, 0, 16, 560, 1, 0, 0, 0, 16, 562, 1, 0, 0, 0, 17, 564, 1, 0, 0, 0, 17, 566, 1, 0, 0, 0, 17, 568, 1, 0, 0, 0, 17, 570, 1, 0, 0, 0, 17, 572, 1, 0, 0, 0, 17, 574, 1, 0, 0, 0, 17, 576, 1, 0, 0, 0, 17, 578, 1, 0, 0, 0, 17, 580, 1, 0, 0, 0, 17, 582, 1, 0, 0, 0, 17, 584, 1, 0, 0, 0, 17, 586, 1, 0, 0, 0, 17, 588, 1, 0, 0, 0, 17, 590, 1, 0, 0, 0, 17, 592, 1, 0, 0, 0, 17, 594, 1, 0, 0, 0, 18, 596, 1, 0, 0, 0, 18, 598, 1, 0, 0, 0, 18, 600, 1, 0, 0, 0, 18, 602, 1, 0, 0, 0, 18, 604, 1, 0, 0, 0, 18, 606, 1, 0, 0, 0, 18, 608, 1, 0, 0, 0, 18, 610, 1, 0, 0, 0, 18, 612, 1, 0, 0, 0, 18, 614, 1, 0, 0, 0, 18, 616, 1, 0, 0, 0, 18, 618, 1, 0, 0, 0, 18, 620, 1, 0, 0, 0, 18, 622, 1, 0, 0, 0, 18, 624, 1, 0, 0, 0, 18, 626, 1, 0, 0, 0, 18, 628, 1, 0, 0, 0, 18, 630, 1, 0, 0, 0, 18, 632, 1, 0, 0, 0, 18, 634, 1, 0, 0, 0, 18, 636, 1, 0, 0, 0, 18, 638, 1, 0, 0, 0, 19, 640, 1, 0, 0, 0, 19, 642, 1, 0, 0, 0, 19, 644, 1, 0, 0, 0, 19, 646, 1, 0, 0, 0, 19, 648, 1, 0, 0, 0, 20, 650, 1, 0, 0, 0, 22, 667, 1, 0, 0, 0, 24, 683, 1, 0, 0, 0, 26, 689, 1, 0, 0, 0, 28, 704, 1, 0, 0, 0, 30, 713, 1, 0, 0, 0, 32, 724, 1, 0, 0, 0, 34, 737, 1, 0, 0, 0, 36, 747, 1, 0, 0, 0, 38, 754, 1, 0, 0, 0, 40, 761, 1, 0, 0, 0, 42, 769, 1, 0, 0, 0, 44, 778, 1, 0, 0, 0, 46, 784, 1, 0, 0, 0, 48, 793, 1, 0, 0, 0, 50, 800, 1, 0, 0, 0, 52, 808, 1, 0, 0, 0, 54, 816, 1, 0, 0, 0, 56, 823, 1, 0, 0, 0, 58, 828, 1, 0, 0, 0, 60, 835, 1, 0, 0, 0, 62, 842, 1, 0, 0, 0, 64, 851, 1, 0, 0, 0, 66, 865, 1, 0, 0, 0, 68, 874, 1, 0, 0, 0, 70, 882, 1, 0, 0, 0, 72, 890, 1, 0, 0, 0, 74, 899, 1, 0, 0, 0, 76, 911, 1, 0, 0, 0, 78, 923, 1, 0, 0, 0, 80, 930, 1, 0, 0, 0, 82, 937, 1, 0, 0, 0, 84, 949, 1, 0, 0, 0, 86, 959, 1, 0, 0, 0, 88, 968, 1, 0, 0, 0, 90, 974, 1, 0, 0, 0, 92, 982, 1, 0, 0, 0, 94, 988, 1, 0, 0, 0, 96, 993, 1, 0, 0, 0, 98, 999, 1, 0, 0, 0, 100, 1003, 1, 0, 0, 0, 102, 1007, 1, 0, 0, 0, 104, 1011, 1, 0, 0, 0, 106, 1015, 1, 0, 0, 0, 108, 1019, 1, 0, 0, 0, 110, 1023, 1, 0, 0, 0, 112, 1027, 1, 0, 0, 0, 114, 1031, 1, 0, 0, 0, 116, 1035, 1, 0, 0, 0, 118, 1039, 1, 0, 0, 0, 120, 1043, 1, 0, 0, 0, 122, 1048, 1, 0, 0, 0, 124, 1054, 1, 0, 0, 0, 126, 1059, 1, 0, 0, 0, 128, 1064, 1, 0, 0, 0, 130, 1073, 1, 0, 0, 0, 132, 1080, 1, 0, 0, 0, 134, 1084, 1, 0, 0, 0, 136, 1088, 1, 0, 0, 0, 138, 1092, 1, 0, 0, 0, 140, 1096, 1, 0, 0, 0, 142, 1100, 1, 0, 0, 0, 144, 1106, 1, 0, 0, 0, 146, 1113, 1, 0, 0, 0, 148, 1117, 1, 0, 0, 0, 150, 1121, 1, 0, 0, 0, 152, 1125, 1, 0, 0, 0, 154, 1129, 1, 0, 0, 0, 156, 1133, 1, 0, 0, 0, 158, 1137, 1, 0, 0, 0, 160, 1141, 1, 0, 0, 0, 162, 1145, 1, 0, 0, 0, 164, 1149, 1, 0, 0, 0, 166, 1153, 1, 0, 0, 0, 168, 1157, 1, 0, 0, 0, 170, 1161, 1, 0, 0, 0, 172, 1165, 1, 0, 0, 0, 174, 1169, 1, 0, 0, 0, 176, 1173, 1, 0, 0, 0, 178, 1178, 1, 0, 0, 0, 180, 1183, 1, 0, 0, 0, 182, 1187, 1, 0, 0, 0, 184, 1191, 1, 0, 0, 0, 186, 1195, 1, 0, 0, 0, 188, 1199, 1, 0, 0, 0, 190, 1201, 1, 0, 0, 0, 192, 1203, 1, 0, 0, 0, 194, 1206, 1, 0, 0, 0, 196, 1208, 1, 0, 0, 0, 198, 1217, 1, 0, 0, 0, 200, 1219, 1, 0, 0, 0, 202, 1224, 1, 0, 0, 0, 204, 1226, 1, 0, 0, 0, 206, 1231, 1, 0, 0, 0, 208, 1262, 1, 0, 0, 0, 210, 1265, 1, 0, 0, 0, 212, 1311, 1, 0, 0, 0, 214, 1313, 1, 0, 0, 0, 216, 1317, 1, 0, 0, 0, 218, 1321, 1, 0, 0, 0, 220, 1323, 1, 0, 0, 0, 222, 1326, 1, 0, 0, 0, 224, 1329, 1, 0, 0, 0, 226, 1331, 1, 0, 0, 0, 228, 1333, 1, 0, 0, 0, 230, 1335, 1, 0, 0, 0, 232, 1340, 1, 0, 0, 0, 234, 1342, 1, 0, 0, 0, 236, 1348, 1, 0, 0, 0, 238, 1354, 1, 0, 0, 0, 240, 1357, 1, 0, 0, 0, 242, 1360, 1, 0, 0, 0, 244, 1365, 1, 0, 0, 0, 246, 1370, 1, 0, 0, 0, 248, 1374, 1, 0, 0, 0, 250, 1379, 1, 0, 0, 0, 252, 1385, 1, 0, 0, 0, 254, 1388, 1, 0, 0, 0, 256, 1391, 1, 0, 0, 0, 258, 1393, 1, 0, 0, 0, 260, 1399, 1, 0, 0, 0, 262, 1404, 1, 0, 0, 0, 264, 1409, 1, 0, 0, 0, 266, 1412, 1, 0, 0, 0, 268, 1415, 1, 0, 0, 0, 270, 1418, 1, 0, 0, 0, 272, 1420, 1, 0, 0, 0, 274, 1423, 1, 0, 0, 0, 276, 1425, 1, 0, 0, 0, 278, 1428, 1, 0, 0, 0, 280, 1430, 1, 0, 0, 0, 282, 1432, 1, 0, 0, 0, 284, 1434, 1, 0, 0, 0, 286, 1436, 1, 0, 0, 0, 288, 1438, 1, 0, 0, 0, 290, 1440, 1, 0, 0, 0, 292, 1442, 1, 0, 0, 0, 294, 1445, 1, 0, 0, 0, 296, 1466, 1, 0, 0, 0, 298, 1485, 1, 0, 0, 0, 300, 1487, 1, 0, 0, 0, 302, 1492, 1, 0, 0, 0, 304, 1497, 1, 0, 0, 0, 306, 1502, 1, 0, 0, 0, 308, 1523, 1, 0, 0, 0, 310, 1525, 1, 0, 0, 0, 312, 1533, 1, 0, 0, 0, 314, 1535, 1, 0, 0, 0, 316, 1539, 1, 0, 0, 0, 318, 1543, 1, 0, 0, 0, 320, 1547, 1, 0, 0, 0, 322, 1552, 1, 0, 0, 0, 324, 1556, 1, 0, 0, 0, 326, 1560, 1, 0, 0, 0, 328, 1564, 1, 0, 0, 0, 330, 1568, 1, 0, 0, 0, 332, 1577, 1, 0, 0, 0, 334, 1583, 1, 0, 0, 0, 336, 1591, 1, 0, 0, 0, 338, 1594, 1, 0, 0, 0, 340, 1598, 1, 0, 0, 0, 342, 1602, 1, 0, 0, 0, 344, 1606, 1, 0, 0, 0, 346, 1610, 1, 0, 0, 0, 348, 1614, 1, 0, 0, 0, 350, 1618, 1, 0, 0, 0, 352, 1623, 1, 0, 0, 0, 354, 1629, 1, 0, 0, 0, 356, 1634, 1, 0, 0, 0, 358, 1638, 1, 0, 0, 0, 360, 1642, 1, 0, 0, 0, 362, 1646, 1, 0, 0, 0, 364, 1651, 1, 0, 0, 0, 366, 1657, 1, 0, 0, 0, 368, 1663, 1, 0, 0, 0, 370, 1669, 1, 0, 0, 0, 372, 1673, 1, 0, 0, 0, 374, 1679, 1, 0, 0, 0, 376, 1683, 1, 0, 0, 0, 378, 1687, 1, 0, 0, 0, 380, 1691, 1, 0, 0, 0, 382, 1695, 1, 0, 0, 0, 384, 1699, 1, 0, 0, 0, 386, 1703, 1, 0, 0, 0, 388, 1707, 1, 0, 0, 0, 390, 1711, 1, 0, 0, 0, 392, 1715, 1, 0, 0, 0, 394, 1719, 1, 0, 0, 0, 396, 1723, 1, 0, 0, 0, 398, 1727, 1, 0, 0, 0, 400, 1736, 1, 0, 0, 0, 402, 1740, 1, 0, 0, 0, 404, 1744, 1, 0, 0, 0, 406, 1748, 1, 0, 0, 0, 408, 1753, 1, 0, 0, 0, 410, 1758, 1, 0, 0, 0, 412, 1762, 1, 0, 0, 0, 414, 1768, 1, 0, 0, 0, 416, 1777, 1, 0, 0, 0, 418, 1781, 1, 0, 0, 0, 420, 1785, 1, 0, 0, 0, 422, 1789, 1, 0, 0, 0, 424, 1793, 1, 0, 0, 0, 426, 1797, 1, 0, 0, 0, 428, 1801, 1, 0, 0, 0, 430, 1806, 1, 0, 0, 0, 432, 1812, 1, 0, 0, 0, 434, 1816, 1, 0, 0, 0, 436, 1820, 1, 0, 0, 0, 438, 1824, 1, 0, 0, 0, 440, 1829, 1, 0, 0, 0, 442, 1833, 1, 0, 0, 0, 444, 1837, 1, 0, 0, 0, 446, 1841, 1, 0, 0, 0, 448, 1845, 1, 0, 0, 0, 450, 1849, 1, 0, 0, 0, 452, 1855, 1, 0, 0, 0, 454, 1862, 1, 0, 0, 0, 456, 1866, 1, 0, 0, 0, 458, 1870, 1, 0, 0, 0, 460, 1874, 1, 0, 0, 0, 462, 1878, 1, 0, 0, 0, 464, 1882, 1, 0, 0, 0, 466, 1886, 1, 0, 0, 0, 468, 1891, 1, 0, 0, 0, 470, 1897, 1, 0, 0, 0, 472, 1901, 1, 0, 0, 0, 474, 1905, 1, 0, 0, 0, 476, 1909, 1, 0, 0, 0, 478, 1913, 1, 0, 0, 0, 480, 1917, 1, 0, 0, 0, 482, 1921, 1, 0, 0, 0, 484, 1925, 1, 0, 0, 0, 486, 1929, 1, 0, 0, 0, 488, 1933, 1, 0, 0, 0, 490, 1937, 1, 0, 0, 0, 492, 1941, 1, 0, 0, 0, 494, 1945, 1, 0, 0, 0, 496, 1950, 1, 0, 0, 0, 498, 1956, 1, 0, 0, 0, 500, 1960, 1, 0, 0, 0, 502, 1964, 1, 0, 0, 0, 504, 1968, 1, 0, 0, 0, 506, 1972, 1, 0, 0, 0, 508, 1976, 1, 0, 0, 0, 510, 1980, 1, 0, 0, 0, 512, 1984, 1, 0, 0, 0, 514, 1992, 1, 0, 0, 0, 516, 2013, 1, 0, 0, 0, 518, 2017, 1, 0, 0, 0, 520, 2021, 1, 0, 0, 0, 522, 2025, 1, 0, 0, 0, 524, 2029, 1, 0, 0, 0, 526, 2046, 1, 0, 0, 0, 528, 2048, 1, 0, 0, 0, 530, 2052, 1, 0, 0, 0, 532, 2056, 1, 0, 0, 0, 534, 2060, 1, 0, 0, 0, 536, 2065, 1, 0, 0, 0, 538, 2071, 1, 0, 0, 0, 540, 2075, 1, 0, 0, 0, 542, 2079, 1, 0, 0, 0, 544, 2083, 1, 0, 0, 0, 546, 2091, 1, 0, 0, 0, 548, 2123, 1, 0, 0, 0, 550, 2125, 1, 0, 0, 0, 552, 2138, 1, 0, 0, 0, 554, 2144, 1, 0, 0, 0, 556, 2152, 1, 0, 0, 0, 558, 2158, 1, 0, 0, 0, 560, 2162, 1, 0, 0, 0, 562, 2166, 1, 0, 0, 0, 564, 2170, 1, 0, 0, 0, 566, 2175, 1, 0, 0, 0, 568, 2181, 1, 0, 0, 0, 570, 2185, 1, 0, 0, 0, 572, 2189, 1, 0, 0, 0, 574, 2193, 1, 0, 0, 0, 576, 2197, 1, 0, 0, 0, 578, 2201, 1, 0, 0, 0, 580, 2205, 1, 0, 0, 0, 582, 2209, 1, 0, 0, 0, 584, 2213, 1, 0, 0, 0, 586, 2217, 1, 0, 0, 0, 588, 2220, 1, 0, 0, 0, 590, 2224, 1, 0, 0, 0, 592, 2228, 1, 0, 0, 0, 594, 2232, 1, 0, 0, 0, 596, 2236, 1, 0, 0, 0, 598, 2240, 1, 0, 0, 0, 600, 2244, 1, 0, 0, 0, 602, 2248, 1, 0, 0, 0, 604, 2253, 1, 0, 0, 0, 606, 2257, 1, 0, 0, 0, 608, 2261, 1, 0, 0, 0, 610, 2265, 1, 0, 0, 0, 612, 2269, 1, 0, 0, 0, 614, 2273, 1, 0, 0, 0, 616, 2277, 1, 0, 0, 0, 618, 2281, 1, 0, 0, 0, 620, 2285, 1, 0, 0, 0, 622, 2289, 1, 0, 0, 0, 624, 2293, 1, 0, 0, 0, 626, 2297, 1, 0, 0, 0, 628, 2301, 1, 0, 0, 0, 630, 2305, 1, 0, 0, 0, 632, 2309, 1, 0, 0, 0, 634, 2313, 1, 0, 0, 0, 636, 2317, 1, 0, 0, 0, 638, 2321, 1, 0, 0, 0, 640, 2325, 1, 0, 0, 0, 642, 2330, 1, 0, 0, 0, 644, 2335, 1, 0, 0, 0, 646, 2339, 1, 0, 0, 0, 648, 2343, 1, 0, 0, 0, 650, 651, 5, 47, 0, 0, 651, 652, 5, 47, 0, 0, 652, 656, 1, 0, 0, 0, 653, 655, 8, 0, 0, 0, 654, 653, 1, 0, 0, 0, 655, 658, 1, 0, 0, 0, 656, 654, 1, 0, 0, 0, 656, 657, 1, 0, 0, 0, 657, 660, 1, 0, 0, 0, 658, 656, 1, 0, 0, 0, 659, 661, 5, 13, 0, 0, 660, 659, 1, 0, 0, 0, 660, 661, 1, 0, 0, 0, 661, 663, 1, 0, 0, 0, 662, 664, 5, 10, 0, 0, 663, 662, 1, 0, 0, 0, 663, 664, 1, 0, 0, 0, 664, 665, 1, 0, 0, 0, 665, 666, 6, 0, 0, 0, 666, 21, 1, 0, 0, 0, 667, 668, 5, 47, 0, 0, 668, 669, 5, 42, 0, 0, 669, 674, 1, 0, 0, 0, 670, 673, 3, 22, 1, 0, 671, 673, 9, 0, 0, 0, 672, 670, 1, 0, 0, 0, 672, 671, 1, 0, 0, 0, 673, 676, 1, 0, 0, 0, 674, 675, 1, 0, 0, 0, 674, 672, 1, 0, 0, 0, 675, 677, 1, 0, 0, 0, 676, 674, 1, 0, 0, 0, 677, 678, 5, 42, 0, 0, 678, 679, 5, 47, 0, 0, 679, 680, 1, 0, 0, 0, 680, 681, 6, 1, 0, 0, 681, 23, 1, 0, 0, 0, 682, 684, 7, 1, 0, 0, 683, 682, 1, 0, 0, 0, 684, 685, 1, 0, 0, 0, 685, 683, 1, 0, 0, 0, 685, 686, 1, 0, 0, 0, 686, 687, 1, 0, 0, 0, 687, 688, 6, 2, 0, 0, 688, 25, 1, 0, 0, 0, 689, 690, 7, 2, 0, 0, 690, 691, 7, 3, 0, 0, 691, 692, 7, 4, 0, 0, 692, 693, 7, 5, 0, 0, 693, 694, 7, 6, 0, 0, 694, 695, 7, 7, 0, 0, 695, 696, 5, 95, 0, 0, 696, 697, 7, 8, 0, 0, 697, 698, 7, 9, 0, 0, 698, 699, 7, 10, 0, 0, 699, 700, 7, 5, 0, 0, 700, 701, 7, 11, 0, 0, 701, 702, 1, 0, 0, 0, 702, 703, 6, 3, 1, 0, 703, 27, 1, 0, 0, 0, 704, 705, 7, 7, 0, 0, 705, 706, 7, 5, 0, 0, 706, 707, 7, 12, 0, 0, 707, 708, 7, 10, 0, 0, 708, 709, 7, 2, 0, 0, 709, 710, 7, 3, 0, 0, 710, 711, 1, 0, 0, 0, 711, 712, 6, 4, 2, 0, 712, 29, 1, 0, 0, 0, 713, 714, 4, 5, 0, 0, 714, 715, 7, 7, 0, 0, 715, 716, 7, 13, 0, 0, 716, 717, 7, 8, 0, 0, 717, 718, 7, 14, 0, 0, 718, 719, 7, 4, 0, 0, 719, 720, 7, 10, 0, 0, 720, 721, 7, 5, 0, 0, 721, 722, 1, 0, 0, 0, 722, 723, 6, 5, 3, 0, 723, 31, 1, 0, 0, 0, 724, 725, 7, 2, 0, 0, 725, 726, 7, 9, 0, 0, 726, 727, 7, 15, 0, 0, 727, 728, 7, 8, 0, 0, 728, 729, 7, 14, 0, 0, 729, 730, 7, 7, 0, 0, 730, 731, 7, 11, 0, 0, 731, 732, 7, 10, 0, 0, 732, 733, 7, 9, 0, 0, 733, 734, 7, 5, 0, 0, 734, 735, 1, 0, 0, 0, 735, 736, 6, 6, 4, 0, 736, 33, 1, 0, 0, 0, 737, 738, 7, 16, 0, 0, 738, 739, 7, 10, 0, 0, 739, 740, 7, 17, 0, 0, 740, 741, 7, 17, 0, 0, 741, 742, 7, 7, 0, 0, 742, 743, 7, 2, 0, 0, 743, 744, 7, 11, 0, 0, 744, 745, 1, 0, 0, 0, 745, 746, 6, 7, 4, 0, 746, 35, 1, 0, 0, 0, 747, 748, 7, 7, 0, 0, 748, 749, 7, 18, 0, 0, 749, 750, 7, 4, 0, 0, 750, 751, 7, 14, 0, 0, 751, 752, 1, 0, 0, 0, 752, 753, 6, 8, 4, 0, 753, 37, 1, 0, 0, 0, 754, 755, 7, 6, 0, 0, 755, 756, 7, 12, 0, 0, 756, 757, 7, 9, 0, 0, 757, 758, 7, 19, 0, 0, 758, 759, 1, 0, 0, 0, 759, 760, 6, 9, 4, 0, 760, 39, 1, 0, 0, 0, 761, 762, 7, 14, 0, 0, 762, 763, 7, 10, 0, 0, 763, 764, 7, 15, 0, 0, 764, 765, 7, 10, 0, 0, 765, 766, 7, 11, 0, 0, 766, 767, 1, 0, 0, 0, 767, 768, 6, 10, 4, 0, 768, 41, 1, 0, 0, 0, 769, 770, 7, 12, 0, 0, 770, 771, 7, 7, 0, 0, 771, 772, 7, 12, 0, 0, 772, 773, 7, 4, 0, 0, 773, 774, 7, 5, 0, 0, 774, 775, 7, 19, 0, 0, 775, 776, 1, 0, 0, 0, 776, 777, 6, 11, 4, 0, 777, 43, 1, 0, 0, 0, 778, 779, 7, 12, 0, 0, 779, 780, 7, 9, 0, 0, 780, 781, 7, 20, 0, 0, 781, 782, 1, 0, 0, 0, 782, 783, 6, 12, 4, 0, 783, 45, 1, 0, 0, 0, 784, 785, 7, 17, 0, 0, 785, 786, 7, 4, 0, 0, 786, 787, 7, 15, 0, 0, 787, 788, 7, 8, 0, 0, 788, 789, 7, 14, 0, 0, 789, 790, 7, 7, 0, 0, 790, 791, 1, 0, 0, 0, 791, 792, 6, 13, 4, 0, 792, 47, 1, 0, 0, 0, 793, 794, 7, 17, 0, 0, 794, 795, 7, 9, 0, 0, 795, 796, 7, 12, 0, 0, 796, 797, 7, 11, 0, 0, 797, 798, 1, 0, 0, 0, 798, 799, 6, 14, 4, 0, 799, 49, 1, 0, 0, 0, 800, 801, 7, 17, 0, 0, 801, 802, 7, 11, 0, 0, 802, 803, 7, 4, 0, 0, 803, 804, 7, 11, 0, 0, 804, 805, 7, 17, 0, 0, 805, 806, 1, 0, 0, 0, 806, 807, 6, 15, 4, 0, 807, 51, 1, 0, 0, 0, 808, 809, 7, 20, 0, 0, 809, 810, 7, 3, 0, 0, 810, 811, 7, 7, 0, 0, 811, 812, 7, 12, 0, 0, 812, 813, 7, 7, 0, 0, 813, 814, 1, 0, 0, 0, 814, 815, 6, 16, 4, 0, 815, 53, 1, 0, 0, 0, 816, 817, 7, 21, 0, 0, 817, 818, 7, 12, 0, 0, 818, 819, 7, 9, 0, 0, 819, 820, 7, 15, 0, 0, 820, 821, 1, 0, 0, 0, 821, 822, 6, 17, 5, 0, 822, 55, 1, 0, 0, 0, 823, 824, 7, 11, 0, 0, 824, 825, 7, 17, 0, 0, 825, 826, 1, 0, 0, 0, 826, 827, 6, 18, 5, 0, 827, 57, 1, 0, 0, 0, 828, 829, 7, 21, 0, 0, 829, 830, 7, 9, 0, 0, 830, 831, 7, 12, 0, 0, 831, 832, 7, 19, 0, 0, 832, 833, 1, 0, 0, 0, 833, 834, 6, 19, 6, 0, 834, 59, 1, 0, 0, 0, 835, 836, 7, 21, 0, 0, 836, 837, 7, 22, 0, 0, 837, 838, 7, 17, 0, 0, 838, 839, 7, 7, 0, 0, 839, 840, 1, 0, 0, 0, 840, 841, 6, 20, 7, 0, 841, 61, 1, 0, 0, 0, 842, 843, 7, 10, 0, 0, 843, 844, 7, 5, 0, 0, 844, 845, 7, 14, 0, 0, 845, 846, 7, 10, 0, 0, 846, 847, 7, 5, 0, 0, 847, 848, 7, 7, 0, 0, 848, 849, 1, 0, 0, 0, 849, 850, 6, 21, 8, 0, 850, 63, 1, 0, 0, 0, 851, 852, 7, 10, 0, 0, 852, 853, 7, 5, 0, 0, 853, 854, 7, 14, 0, 0, 854, 855, 7, 10, 0, 0, 855, 856, 7, 5, 0, 0, 856, 857, 7, 7, 0, 0, 857, 858, 7, 17, 0, 0, 858, 859, 7, 11, 0, 0, 859, 860, 7, 4, 0, 0, 860, 861, 7, 11, 0, 0, 861, 862, 7, 17, 0, 0, 862, 863, 1, 0, 0, 0, 863, 864, 6, 22, 4, 0, 864, 65, 1, 0, 0, 0, 865, 866, 7, 14, 0, 0, 866, 867, 7, 9, 0, 0, 867, 868, 7, 9, 0, 0, 868, 869, 7, 19, 0, 0, 869, 870, 7, 22, 0, 0, 870, 871, 7, 8, 0, 0, 871, 872, 1, 0, 0, 0, 872, 873, 6, 23, 9, 0, 873, 67, 1, 0, 0, 0, 874, 875, 4, 24, 1, 0, 875, 876, 7, 21, 0, 0, 876, 877, 7, 22, 0, 0, 877, 878, 7, 14, 0, 0, 878, 879, 7, 14, 0, 0, 879, 880, 1, 0, 0, 0, 880, 881, 6, 24, 9, 0, 881, 69, 1, 0, 0, 0, 882, 883, 4, 25, 2, 0, 883, 884, 7, 14, 0, 0, 884, 885, 7, 7, 0, 0, 885, 886, 7, 21, 0, 0, 886, 887, 7, 11, 0, 0, 887, 888, 1, 0, 0, 0, 888, 889, 6, 25, 9, 0, 889, 71, 1, 0, 0, 0, 890, 891, 4, 26, 3, 0, 891, 892, 7, 12, 0, 0, 892, 893, 7, 10, 0, 0, 893, 894, 7, 6, 0, 0, 894, 895, 7, 3, 0, 0, 895, 896, 7, 11, 0, 0, 896, 897, 1, 0, 0, 0, 897, 898, 6, 26, 9, 0, 898, 73, 1, 0, 0, 0, 899, 900, 4, 27, 4, 0, 900, 901, 7, 14, 0, 0, 901, 902, 7, 9, 0, 0, 902, 903, 7, 9, 0, 0, 903, 904, 7, 19, 0, 0, 904, 905, 7, 22, 0, 0, 905, 906, 7, 8, 0, 0, 906, 907, 5, 95, 0, 0, 907, 908, 5, 128020, 0, 0, 908, 909, 1, 0, 0, 0, 909, 910, 6, 27, 10, 0, 910, 75, 1, 0, 0, 0, 911, 912, 7, 15, 0, 0, 912, 913, 7, 18, 0, 0, 913, 914, 5, 95, 0, 0, 914, 915, 7, 7, 0, 0, 915, 916, 7, 13, 0, 0, 916, 917, 7, 8, 0, 0, 917, 918, 7, 4, 0, 0, 918, 919, 7, 5, 0, 0, 919, 920, 7, 16, 0, 0, 920, 921, 1, 0, 0, 0, 921, 922, 6, 28, 11, 0, 922, 77, 1, 0, 0, 0, 923, 924, 7, 16, 0, 0, 924, 925, 7, 12, 0, 0, 925, 926, 7, 9, 0, 0, 926, 927, 7, 8, 0, 0, 927, 928, 1, 0, 0, 0, 928, 929, 6, 29, 12, 0, 929, 79, 1, 0, 0, 0, 930, 931, 7, 19, 0, 0, 931, 932, 7, 7, 0, 0, 932, 933, 7, 7, 0, 0, 933, 934, 7, 8, 0, 0, 934, 935, 1, 0, 0, 0, 935, 936, 6, 30, 12, 0, 936, 81, 1, 0, 0, 0, 937, 938, 4, 31, 5, 0, 938, 939, 7, 10, 0, 0, 939, 940, 7, 5, 0, 0, 940, 941, 7, 17, 0, 0, 941, 942, 7, 10, 0, 0, 942, 943, 7, 17, 0, 0, 943, 944, 7, 11, 0, 0, 944, 945, 5, 95, 0, 0, 945, 946, 5, 128020, 0, 0, 946, 947, 1, 0, 0, 0, 947, 948, 6, 31, 12, 0, 948, 83, 1, 0, 0, 0, 949, 950, 4, 32, 6, 0, 950, 951, 7, 8, 0, 0, 951, 952, 7, 12, 0, 0, 952, 953, 7, 9, 0, 0, 953, 954, 7, 15, 0, 0, 954, 955, 7, 23, 0, 0, 955, 956, 7, 14, 0, 0, 956, 957, 1, 0, 0, 0, 957, 958, 6, 32, 13, 0, 958, 85, 1, 0, 0, 0, 959, 960, 7, 12, 0, 0, 960, 961, 7, 7, 0, 0, 961, 962, 7, 5, 0, 0, 962, 963, 7, 4, 0, 0, 963, 964, 7, 15, 0, 0, 964, 965, 7, 7, 0, 0, 965, 966, 1, 0, 0, 0, 966, 967, 6, 33, 14, 0, 967, 87, 1, 0, 0, 0, 968, 969, 7, 17, 0, 0, 969, 970, 7, 7, 0, 0, 970, 971, 7, 11, 0, 0, 971, 972, 1, 0, 0, 0, 972, 973, 6, 34, 15, 0, 973, 89, 1, 0, 0, 0, 974, 975, 7, 17, 0, 0, 975, 976, 7, 3, 0, 0, 976, 977, 7, 9, 0, 0, 977, 978, 7, 20, 0, 0, 978, 979, 1, 0, 0, 0, 979, 980, 6, 35, 16, 0, 980, 91, 1, 0, 0, 0, 981, 983, 8, 24, 0, 0, 982, 981, 1, 0, 0, 0, 983, 984, 1, 0, 0, 0, 984, 982, 1, 0, 0, 0, 984, 985, 1, 0, 0, 0, 985, 986, 1, 0, 0, 0, 986, 987, 6, 36, 4, 0, 987, 93, 1, 0, 0, 0, 988, 989, 3, 186, 83, 0, 989, 990, 1, 0, 0, 0, 990, 991, 6, 37, 17, 0, 991, 992, 6, 37, 18, 0, 992, 95, 1, 0, 0, 0, 993, 994, 3, 306, 143, 0, 994, 995, 1, 0, 0, 0, 995, 996, 6, 38, 19, 0, 996, 997, 6, 38, 18, 0, 997, 998, 6, 38, 18, 0, 998, 97, 1, 0, 0, 0, 999, 1000, 3, 252, 116, 0, 1000, 1001, 1, 0, 0, 0, 1001, 1002, 6, 39, 20, 0, 1002, 99, 1, 0, 0, 0, 1003, 1004, 3, 586, 283, 0, 1004, 1005, 1, 0, 0, 0, 1005, 1006, 6, 40, 21, 0, 1006, 101, 1, 0, 0, 0, 1007, 1008, 3, 232, 106, 0, 1008, 1009, 1, 0, 0, 0, 1009, 1010, 6, 41, 22, 0, 1010, 103, 1, 0, 0, 0, 1011, 1012, 3, 228, 104, 0, 1012, 1013, 1, 0, 0, 0, 1013, 1014, 6, 42, 23, 0, 1014, 105, 1, 0, 0, 0, 1015, 1016, 3, 300, 140, 0, 1016, 1017, 1, 0, 0, 0, 1017, 1018, 6, 43, 24, 0, 1018, 107, 1, 0, 0, 0, 1019, 1020, 3, 302, 141, 0, 1020, 1021, 1, 0, 0, 0, 1021, 1022, 6, 44, 25, 0, 1022, 109, 1, 0, 0, 0, 1023, 1024, 3, 312, 146, 0, 1024, 1025, 1, 0, 0, 0, 1025, 1026, 6, 45, 26, 0, 1026, 111, 1, 0, 0, 0, 1027, 1028, 3, 308, 144, 0, 1028, 1029, 1, 0, 0, 0, 1029, 1030, 6, 46, 27, 0, 1030, 113, 1, 0, 0, 0, 1031, 1032, 3, 20, 0, 0, 1032, 1033, 1, 0, 0, 0, 1033, 1034, 6, 47, 0, 0, 1034, 115, 1, 0, 0, 0, 1035, 1036, 3, 22, 1, 0, 1036, 1037, 1, 0, 0, 0, 1037, 1038, 6, 48, 0, 0, 1038, 117, 1, 0, 0, 0, 1039, 1040, 3, 24, 2, 0, 1040, 1041, 1, 0, 0, 0, 1041, 1042, 6, 49, 0, 0, 1042, 119, 1, 0, 0, 0, 1043, 1044, 3, 186, 83, 0, 1044, 1045, 1, 0, 0, 0, 1045, 1046, 6, 50, 17, 0, 1046, 1047, 6, 50, 18, 0, 1047, 121, 1, 0, 0, 0, 1048, 1049, 3, 306, 143, 0, 1049, 1050, 1, 0, 0, 0, 1050, 1051, 6, 51, 19, 0, 1051, 1052, 6, 51, 18, 0, 1052, 1053, 6, 51, 18, 0, 1053, 123, 1, 0, 0, 0, 1054, 1055, 3, 252, 116, 0, 1055, 1056, 1, 0, 0, 0, 1056, 1057, 6, 52, 20, 0, 1057, 1058, 6, 52, 28, 0, 1058, 125, 1, 0, 0, 0, 1059, 1060, 3, 262, 121, 0, 1060, 1061, 1, 0, 0, 0, 1061, 1062, 6, 53, 29, 0, 1062, 1063, 6, 53, 28, 0, 1063, 127, 1, 0, 0, 0, 1064, 1065, 8, 25, 0, 0, 1065, 129, 1, 0, 0, 0, 1066, 1068, 3, 128, 54, 0, 1067, 1066, 1, 0, 0, 0, 1068, 1069, 1, 0, 0, 0, 1069, 1067, 1, 0, 0, 0, 1069, 1070, 1, 0, 0, 0, 1070, 1071, 1, 0, 0, 0, 1071, 1072, 3, 224, 102, 0, 1072, 1074, 1, 0, 0, 0, 1073, 1067, 1, 0, 0, 0, 1073, 1074, 1, 0, 0, 0, 1074, 1076, 1, 0, 0, 0, 1075, 1077, 3, 128, 54, 0, 1076, 1075, 1, 0, 0, 0, 1077, 1078, 1, 0, 0, 0, 1078, 1076, 1, 0, 0, 0, 1078, 1079, 1, 0, 0, 0, 1079, 131, 1, 0, 0, 0, 1080, 1081, 3, 130, 55, 0, 1081, 1082, 1, 0, 0, 0, 1082, 1083, 6, 56, 30, 0, 1083, 133, 1, 0, 0, 0, 1084, 1085, 3, 208, 94, 0, 1085, 1086, 1, 0, 0, 0, 1086, 1087, 6, 57, 31, 0, 1087, 135, 1, 0, 0, 0, 1088, 1089, 3, 20, 0, 0, 1089, 1090, 1, 0, 0, 0, 1090, 1091, 6, 58, 0, 0, 1091, 137, 1, 0, 0, 0, 1092, 1093, 3, 22, 1, 0, 1093, 1094, 1, 0, 0, 0, 1094, 1095, 6, 59, 0, 0, 1095, 139, 1, 0, 0, 0, 1096, 1097, 3, 24, 2, 0, 1097, 1098, 1, 0, 0, 0, 1098, 1099, 6, 60, 0, 0, 1099, 141, 1, 0, 0, 0, 1100, 1101, 3, 186, 83, 0, 1101, 1102, 1, 0, 0, 0, 1102, 1103, 6, 61, 17, 0, 1103, 1104, 6, 61, 18, 0, 1104, 1105, 6, 61, 18, 0, 1105, 143, 1, 0, 0, 0, 1106, 1107, 3, 306, 143, 0, 1107, 1108, 1, 0, 0, 0, 1108, 1109, 6, 62, 19, 0, 1109, 1110, 6, 62, 18, 0, 1110, 1111, 6, 62, 18, 0, 1111, 1112, 6, 62, 18, 0, 1112, 145, 1, 0, 0, 0, 1113, 1114, 3, 300, 140, 0, 1114, 1115, 1, 0, 0, 0, 1115, 1116, 6, 63, 24, 0, 1116, 147, 1, 0, 0, 0, 1117, 1118, 3, 302, 141, 0, 1118, 1119, 1, 0, 0, 0, 1119, 1120, 6, 64, 25, 0, 1120, 149, 1, 0, 0, 0, 1121, 1122, 3, 218, 99, 0, 1122, 1123, 1, 0, 0, 0, 1123, 1124, 6, 65, 32, 0, 1124, 151, 1, 0, 0, 0, 1125, 1126, 3, 228, 104, 0, 1126, 1127, 1, 0, 0, 0, 1127, 1128, 6, 66, 23, 0, 1128, 153, 1, 0, 0, 0, 1129, 1130, 3, 232, 106, 0, 1130, 1131, 1, 0, 0, 0, 1131, 1132, 6, 67, 22, 0, 1132, 155, 1, 0, 0, 0, 1133, 1134, 3, 262, 121, 0, 1134, 1135, 1, 0, 0, 0, 1135, 1136, 6, 68, 29, 0, 1136, 157, 1, 0, 0, 0, 1137, 1138, 3, 518, 249, 0, 1138, 1139, 1, 0, 0, 0, 1139, 1140, 6, 69, 33, 0, 1140, 159, 1, 0, 0, 0, 1141, 1142, 3, 312, 146, 0, 1142, 1143, 1, 0, 0, 0, 1143, 1144, 6, 70, 26, 0, 1144, 161, 1, 0, 0, 0, 1145, 1146, 3, 256, 118, 0, 1146, 1147, 1, 0, 0, 0, 1147, 1148, 6, 71, 34, 0, 1148, 163, 1, 0, 0, 0, 1149, 1150, 3, 296, 138, 0, 1150, 1151, 1, 0, 0, 0, 1151, 1152, 6, 72, 35, 0, 1152, 165, 1, 0, 0, 0, 1153, 1154, 3, 292, 136, 0, 1154, 1155, 1, 0, 0, 0, 1155, 1156, 6, 73, 36, 0, 1156, 167, 1, 0, 0, 0, 1157, 1158, 3, 298, 139, 0, 1158, 1159, 1, 0, 0, 0, 1159, 1160, 6, 74, 37, 0, 1160, 169, 1, 0, 0, 0, 1161, 1162, 3, 20, 0, 0, 1162, 1163, 1, 0, 0, 0, 1163, 1164, 6, 75, 0, 0, 1164, 171, 1, 0, 0, 0, 1165, 1166, 3, 22, 1, 0, 1166, 1167, 1, 0, 0, 0, 1167, 1168, 6, 76, 0, 0, 1168, 173, 1, 0, 0, 0, 1169, 1170, 3, 24, 2, 0, 1170, 1171, 1, 0, 0, 0, 1171, 1172, 6, 77, 0, 0, 1172, 175, 1, 0, 0, 0, 1173, 1174, 3, 304, 142, 0, 1174, 1175, 1, 0, 0, 0, 1175, 1176, 6, 78, 38, 0, 1176, 1177, 6, 78, 39, 0, 1177, 177, 1, 0, 0, 0, 1178, 1179, 3, 186, 83, 0, 1179, 1180, 1, 0, 0, 0, 1180, 1181, 6, 79, 17, 0, 1181, 1182, 6, 79, 18, 0, 1182, 179, 1, 0, 0, 0, 1183, 1184, 3, 24, 2, 0, 1184, 1185, 1, 0, 0, 0, 1185, 1186, 6, 80, 0, 0, 1186, 181, 1, 0, 0, 0, 1187, 1188, 3, 20, 0, 0, 1188, 1189, 1, 0, 0, 0, 1189, 1190, 6, 81, 0, 0, 1190, 183, 1, 0, 0, 0, 1191, 1192, 3, 22, 1, 0, 1192, 1193, 1, 0, 0, 0, 1193, 1194, 6, 82, 0, 0, 1194, 185, 1, 0, 0, 0, 1195, 1196, 5, 124, 0, 0, 1196, 1197, 1, 0, 0, 0, 1197, 1198, 6, 83, 18, 0, 1198, 187, 1, 0, 0, 0, 1199, 1200, 7, 26, 0, 0, 1200, 189, 1, 0, 0, 0, 1201, 1202, 7, 27, 0, 0, 1202, 191, 1, 0, 0, 0, 1203, 1204, 5, 92, 0, 0, 1204, 1205, 7, 28, 0, 0, 1205, 193, 1, 0, 0, 0, 1206, 1207, 8, 29, 0, 0, 1207, 195, 1, 0, 0, 0, 1208, 1210, 7, 7, 0, 0, 1209, 1211, 7, 30, 0, 0, 1210, 1209, 1, 0, 0, 0, 1210, 1211, 1, 0, 0, 0, 1211, 1213, 1, 0, 0, 0, 1212, 1214, 3, 188, 84, 0, 1213, 1212, 1, 0, 0, 0, 1214, 1215, 1, 0, 0, 0, 1215, 1213, 1, 0, 0, 0, 1215, 1216, 1, 0, 0, 0, 1216, 197, 1, 0, 0, 0, 1217, 1218, 5, 64, 0, 0, 1218, 199, 1, 0, 0, 0, 1219, 1220, 5, 96, 0, 0, 1220, 201, 1, 0, 0, 0, 1221, 1225, 8, 31, 0, 0, 1222, 1223, 5, 96, 0, 0, 1223, 1225, 5, 96, 0, 0, 1224, 1221, 1, 0, 0, 0, 1224, 1222, 1, 0, 0, 0, 1225, 203, 1, 0, 0, 0, 1226, 1227, 5, 95, 0, 0, 1227, 205, 1, 0, 0, 0, 1228, 1232, 3, 190, 85, 0, 1229, 1232, 3, 188, 84, 0, 1230, 1232, 3, 204, 92, 0, 1231, 1228, 1, 0, 0, 0, 1231, 1229, 1, 0, 0, 0, 1231, 1230, 1, 0, 0, 0, 1232, 207, 1, 0, 0, 0, 1233, 1238, 5, 34, 0, 0, 1234, 1237, 3, 192, 86, 0, 1235, 1237, 3, 194, 87, 0, 1236, 1234, 1, 0, 0, 0, 1236, 1235, 1, 0, 0, 0, 1237, 1240, 1, 0, 0, 0, 1238, 1236, 1, 0, 0, 0, 1238, 1239, 1, 0, 0, 0, 1239, 1241, 1, 0, 0, 0, 1240, 1238, 1, 0, 0, 0, 1241, 1263, 5, 34, 0, 0, 1242, 1243, 5, 34, 0, 0, 1243, 1244, 5, 34, 0, 0, 1244, 1245, 5, 34, 0, 0, 1245, 1249, 1, 0, 0, 0, 1246, 1248, 8, 0, 0, 0, 1247, 1246, 1, 0, 0, 0, 1248, 1251, 1, 0, 0, 0, 1249, 1250, 1, 0, 0, 0, 1249, 1247, 1, 0, 0, 0, 1250, 1252, 1, 0, 0, 0, 1251, 1249, 1, 0, 0, 0, 1252, 1253, 5, 34, 0, 0, 1253, 1254, 5, 34, 0, 0, 1254, 1255, 5, 34, 0, 0, 1255, 1257, 1, 0, 0, 0, 1256, 1258, 5, 34, 0, 0, 1257, 1256, 1, 0, 0, 0, 1257, 1258, 1, 0, 0, 0, 1258, 1260, 1, 0, 0, 0, 1259, 1261, 5, 34, 0, 0, 1260, 1259, 1, 0, 0, 0, 1260, 1261, 1, 0, 0, 0, 1261, 1263, 1, 0, 0, 0, 1262, 1233, 1, 0, 0, 0, 1262, 1242, 1, 0, 0, 0, 1263, 209, 1, 0, 0, 0, 1264, 1266, 3, 188, 84, 0, 1265, 1264, 1, 0, 0, 0, 1266, 1267, 1, 0, 0, 0, 1267, 1265, 1, 0, 0, 0, 1267, 1268, 1, 0, 0, 0, 1268, 211, 1, 0, 0, 0, 1269, 1271, 3, 188, 84, 0, 1270, 1269, 1, 0, 0, 0, 1271, 1272, 1, 0, 0, 0, 1272, 1270, 1, 0, 0, 0, 1272, 1273, 1, 0, 0, 0, 1273, 1274, 1, 0, 0, 0, 1274, 1278, 3, 232, 106, 0, 1275, 1277, 3, 188, 84, 0, 1276, 1275, 1, 0, 0, 0, 1277, 1280, 1, 0, 0, 0, 1278, 1276, 1, 0, 0, 0, 1278, 1279, 1, 0, 0, 0, 1279, 1312, 1, 0, 0, 0, 1280, 1278, 1, 0, 0, 0, 1281, 1283, 3, 232, 106, 0, 1282, 1284, 3, 188, 84, 0, 1283, 1282, 1, 0, 0, 0, 1284, 1285, 1, 0, 0, 0, 1285, 1283, 1, 0, 0, 0, 1285, 1286, 1, 0, 0, 0, 1286, 1312, 1, 0, 0, 0, 1287, 1289, 3, 188, 84, 0, 1288, 1287, 1, 0, 0, 0, 1289, 1290, 1, 0, 0, 0, 1290, 1288, 1, 0, 0, 0, 1290, 1291, 1, 0, 0, 0, 1291, 1299, 1, 0, 0, 0, 1292, 1296, 3, 232, 106, 0, 1293, 1295, 3, 188, 84, 0, 1294, 1293, 1, 0, 0, 0, 1295, 1298, 1, 0, 0, 0, 1296, 1294, 1, 0, 0, 0, 1296, 1297, 1, 0, 0, 0, 1297, 1300, 1, 0, 0, 0, 1298, 1296, 1, 0, 0, 0, 1299, 1292, 1, 0, 0, 0, 1299, 1300, 1, 0, 0, 0, 1300, 1301, 1, 0, 0, 0, 1301, 1302, 3, 196, 88, 0, 1302, 1312, 1, 0, 0, 0, 1303, 1305, 3, 232, 106, 0, 1304, 1306, 3, 188, 84, 0, 1305, 1304, 1, 0, 0, 0, 1306, 1307, 1, 0, 0, 0, 1307, 1305, 1, 0, 0, 0, 1307, 1308, 1, 0, 0, 0, 1308, 1309, 1, 0, 0, 0, 1309, 1310, 3, 196, 88, 0, 1310, 1312, 1, 0, 0, 0, 1311, 1270, 1, 0, 0, 0, 1311, 1281, 1, 0, 0, 0, 1311, 1288, 1, 0, 0, 0, 1311, 1303, 1, 0, 0, 0, 1312, 213, 1, 0, 0, 0, 1313, 1314, 7, 4, 0, 0, 1314, 1315, 7, 5, 0, 0, 1315, 1316, 7, 16, 0, 0, 1316, 215, 1, 0, 0, 0, 1317, 1318, 7, 4, 0, 0, 1318, 1319, 7, 17, 0, 0, 1319, 1320, 7, 2, 0, 0, 1320, 217, 1, 0, 0, 0, 1321, 1322, 5, 61, 0, 0, 1322, 219, 1, 0, 0, 0, 1323, 1324, 7, 32, 0, 0, 1324, 1325, 7, 33, 0, 0, 1325, 221, 1, 0, 0, 0, 1326, 1327, 5, 58, 0, 0, 1327, 1328, 5, 58, 0, 0, 1328, 223, 1, 0, 0, 0, 1329, 1330, 5, 58, 0, 0, 1330, 225, 1, 0, 0, 0, 1331, 1332, 5, 59, 0, 0, 1332, 227, 1, 0, 0, 0, 1333, 1334, 5, 44, 0, 0, 1334, 229, 1, 0, 0, 0, 1335, 1336, 7, 16, 0, 0, 1336, 1337, 7, 7, 0, 0, 1337, 1338, 7, 17, 0, 0, 1338, 1339, 7, 2, 0, 0, 1339, 231, 1, 0, 0, 0, 1340, 1341, 5, 46, 0, 0, 1341, 233, 1, 0, 0, 0, 1342, 1343, 7, 21, 0, 0, 1343, 1344, 7, 4, 0, 0, 1344, 1345, 7, 14, 0, 0, 1345, 1346, 7, 17, 0, 0, 1346, 1347, 7, 7, 0, 0, 1347, 235, 1, 0, 0, 0, 1348, 1349, 7, 21, 0, 0, 1349, 1350, 7, 10, 0, 0, 1350, 1351, 7, 12, 0, 0, 1351, 1352, 7, 17, 0, 0, 1352, 1353, 7, 11, 0, 0, 1353, 237, 1, 0, 0, 0, 1354, 1355, 7, 10, 0, 0, 1355, 1356, 7, 5, 0, 0, 1356, 239, 1, 0, 0, 0, 1357, 1358, 7, 10, 0, 0, 1358, 1359, 7, 17, 0, 0, 1359, 241, 1, 0, 0, 0, 1360, 1361, 7, 14, 0, 0, 1361, 1362, 7, 4, 0, 0, 1362, 1363, 7, 17, 0, 0, 1363, 1364, 7, 11, 0, 0, 1364, 243, 1, 0, 0, 0, 1365, 1366, 7, 14, 0, 0, 1366, 1367, 7, 10, 0, 0, 1367, 1368, 7, 19, 0, 0, 1368, 1369, 7, 7, 0, 0, 1369, 245, 1, 0, 0, 0, 1370, 1371, 7, 5, 0, 0, 1371, 1372, 7, 9, 0, 0, 1372, 1373, 7, 11, 0, 0, 1373, 247, 1, 0, 0, 0, 1374, 1375, 7, 5, 0, 0, 1375, 1376, 7, 22, 0, 0, 1376, 1377, 7, 14, 0, 0, 1377, 1378, 7, 14, 0, 0, 1378, 249, 1, 0, 0, 0, 1379, 1380, 7, 5, 0, 0, 1380, 1381, 7, 22, 0, 0, 1381, 1382, 7, 14, 0, 0, 1382, 1383, 7, 14, 0, 0, 1383, 1384, 7, 17, 0, 0, 1384, 251, 1, 0, 0, 0, 1385, 1386, 7, 9, 0, 0, 1386, 1387, 7, 5, 0, 0, 1387, 253, 1, 0, 0, 0, 1388, 1389, 7, 9, 0, 0, 1389, 1390, 7, 12, 0, 0, 1390, 255, 1, 0, 0, 0, 1391, 1392, 5, 63, 0, 0, 1392, 257, 1, 0, 0, 0, 1393, 1394, 7, 12, 0, 0, 1394, 1395, 7, 14, 0, 0, 1395, 1396, 7, 10, 0, 0, 1396, 1397, 7, 19, 0, 0, 1397, 1398, 7, 7, 0, 0, 1398, 259, 1, 0, 0, 0, 1399, 1400, 7, 11, 0, 0, 1400, 1401, 7, 12, 0, 0, 1401, 1402, 7, 22, 0, 0, 1402, 1403, 7, 7, 0, 0, 1403, 261, 1, 0, 0, 0, 1404, 1405, 7, 20, 0, 0, 1405, 1406, 7, 10, 0, 0, 1406, 1407, 7, 11, 0, 0, 1407, 1408, 7, 3, 0, 0, 1408, 263, 1, 0, 0, 0, 1409, 1410, 5, 61, 0, 0, 1410, 1411, 5, 61, 0, 0, 1411, 265, 1, 0, 0, 0, 1412, 1413, 5, 61, 0, 0, 1413, 1414, 5, 126, 0, 0, 1414, 267, 1, 0, 0, 0, 1415, 1416, 5, 33, 0, 0, 1416, 1417, 5, 61, 0, 0, 1417, 269, 1, 0, 0, 0, 1418, 1419, 5, 60, 0, 0, 1419, 271, 1, 0, 0, 0, 1420, 1421, 5, 60, 0, 0, 1421, 1422, 5, 61, 0, 0, 1422, 273, 1, 0, 0, 0, 1423, 1424, 5, 62, 0, 0, 1424, 275, 1, 0, 0, 0, 1425, 1426, 5, 62, 0, 0, 1426, 1427, 5, 61, 0, 0, 1427, 277, 1, 0, 0, 0, 1428, 1429, 5, 43, 0, 0, 1429, 279, 1, 0, 0, 0, 1430, 1431, 5, 45, 0, 0, 1431, 281, 1, 0, 0, 0, 1432, 1433, 5, 42, 0, 0, 1433, 283, 1, 0, 0, 0, 1434, 1435, 5, 47, 0, 0, 1435, 285, 1, 0, 0, 0, 1436, 1437, 5, 37, 0, 0, 1437, 287, 1, 0, 0, 0, 1438, 1439, 5, 123, 0, 0, 1439, 289, 1, 0, 0, 0, 1440, 1441, 5, 125, 0, 0, 1441, 291, 1, 0, 0, 0, 1442, 1443, 5, 63, 0, 0, 1443, 1444, 5, 63, 0, 0, 1444, 293, 1, 0, 0, 0, 1445, 1446, 3, 52, 16, 0, 1446, 1447, 1, 0, 0, 0, 1447, 1448, 6, 137, 40, 0, 1448, 295, 1, 0, 0, 0, 1449, 1452, 3, 256, 118, 0, 1450, 1453, 3, 190, 85, 0, 1451, 1453, 3, 204, 92, 0, 1452, 1450, 1, 0, 0, 0, 1452, 1451, 1, 0, 0, 0, 1453, 1457, 1, 0, 0, 0, 1454, 1456, 3, 206, 93, 0, 1455, 1454, 1, 0, 0, 0, 1456, 1459, 1, 0, 0, 0, 1457, 1455, 1, 0, 0, 0, 1457, 1458, 1, 0, 0, 0, 1458, 1467, 1, 0, 0, 0, 1459, 1457, 1, 0, 0, 0, 1460, 1462, 3, 256, 118, 0, 1461, 1463, 3, 188, 84, 0, 1462, 1461, 1, 0, 0, 0, 1463, 1464, 1, 0, 0, 0, 1464, 1462, 1, 0, 0, 0, 1464, 1465, 1, 0, 0, 0, 1465, 1467, 1, 0, 0, 0, 1466, 1449, 1, 0, 0, 0, 1466, 1460, 1, 0, 0, 0, 1467, 297, 1, 0, 0, 0, 1468, 1471, 3, 292, 136, 0, 1469, 1472, 3, 190, 85, 0, 1470, 1472, 3, 204, 92, 0, 1471, 1469, 1, 0, 0, 0, 1471, 1470, 1, 0, 0, 0, 1472, 1476, 1, 0, 0, 0, 1473, 1475, 3, 206, 93, 0, 1474, 1473, 1, 0, 0, 0, 1475, 1478, 1, 0, 0, 0, 1476, 1474, 1, 0, 0, 0, 1476, 1477, 1, 0, 0, 0, 1477, 1486, 1, 0, 0, 0, 1478, 1476, 1, 0, 0, 0, 1479, 1481, 3, 292, 136, 0, 1480, 1482, 3, 188, 84, 0, 1481, 1480, 1, 0, 0, 0, 1482, 1483, 1, 0, 0, 0, 1483, 1481, 1, 0, 0, 0, 1483, 1484, 1, 0, 0, 0, 1484, 1486, 1, 0, 0, 0, 1485, 1468, 1, 0, 0, 0, 1485, 1479, 1, 0, 0, 0, 1486, 299, 1, 0, 0, 0, 1487, 1488, 5, 91, 0, 0, 1488, 1489, 1, 0, 0, 0, 1489, 1490, 6, 140, 4, 0, 1490, 1491, 6, 140, 4, 0, 1491, 301, 1, 0, 0, 0, 1492, 1493, 5, 93, 0, 0, 1493, 1494, 1, 0, 0, 0, 1494, 1495, 6, 141, 18, 0, 1495, 1496, 6, 141, 18, 0, 1496, 303, 1, 0, 0, 0, 1497, 1498, 5, 40, 0, 0, 1498, 1499, 1, 0, 0, 0, 1499, 1500, 6, 142, 4, 0, 1500, 1501, 6, 142, 4, 0, 1501, 305, 1, 0, 0, 0, 1502, 1503, 5, 41, 0, 0, 1503, 1504, 1, 0, 0, 0, 1504, 1505, 6, 143, 18, 0, 1505, 1506, 6, 143, 18, 0, 1506, 307, 1, 0, 0, 0, 1507, 1511, 3, 190, 85, 0, 1508, 1510, 3, 206, 93, 0, 1509, 1508, 1, 0, 0, 0, 1510, 1513, 1, 0, 0, 0, 1511, 1509, 1, 0, 0, 0, 1511, 1512, 1, 0, 0, 0, 1512, 1524, 1, 0, 0, 0, 1513, 1511, 1, 0, 0, 0, 1514, 1517, 3, 204, 92, 0, 1515, 1517, 3, 198, 89, 0, 1516, 1514, 1, 0, 0, 0, 1516, 1515, 1, 0, 0, 0, 1517, 1519, 1, 0, 0, 0, 1518, 1520, 3, 206, 93, 0, 1519, 1518, 1, 0, 0, 0, 1520, 1521, 1, 0, 0, 0, 1521, 1519, 1, 0, 0, 0, 1521, 1522, 1, 0, 0, 0, 1522, 1524, 1, 0, 0, 0, 1523, 1507, 1, 0, 0, 0, 1523, 1516, 1, 0, 0, 0, 1524, 309, 1, 0, 0, 0, 1525, 1527, 3, 200, 90, 0, 1526, 1528, 3, 202, 91, 0, 1527, 1526, 1, 0, 0, 0, 1528, 1529, 1, 0, 0, 0, 1529, 1527, 1, 0, 0, 0, 1529, 1530, 1, 0, 0, 0, 1530, 1531, 1, 0, 0, 0, 1531, 1532, 3, 200, 90, 0, 1532, 311, 1, 0, 0, 0, 1533, 1534, 3, 310, 145, 0, 1534, 313, 1, 0, 0, 0, 1535, 1536, 3, 20, 0, 0, 1536, 1537, 1, 0, 0, 0, 1537, 1538, 6, 147, 0, 0, 1538, 315, 1, 0, 0, 0, 1539, 1540, 3, 22, 1, 0, 1540, 1541, 1, 0, 0, 0, 1541, 1542, 6, 148, 0, 0, 1542, 317, 1, 0, 0, 0, 1543, 1544, 3, 24, 2, 0, 1544, 1545, 1, 0, 0, 0, 1545, 1546, 6, 149, 0, 0, 1546, 319, 1, 0, 0, 0, 1547, 1548, 3, 186, 83, 0, 1548, 1549, 1, 0, 0, 0, 1549, 1550, 6, 150, 17, 0, 1550, 1551, 6, 150, 18, 0, 1551, 321, 1, 0, 0, 0, 1552, 1553, 3, 224, 102, 0, 1553, 1554, 1, 0, 0, 0, 1554, 1555, 6, 151, 41, 0, 1555, 323, 1, 0, 0, 0, 1556, 1557, 3, 222, 101, 0, 1557, 1558, 1, 0, 0, 0, 1558, 1559, 6, 152, 42, 0, 1559, 325, 1, 0, 0, 0, 1560, 1561, 3, 228, 104, 0, 1561, 1562, 1, 0, 0, 0, 1562, 1563, 6, 153, 23, 0, 1563, 327, 1, 0, 0, 0, 1564, 1565, 3, 218, 99, 0, 1565, 1566, 1, 0, 0, 0, 1566, 1567, 6, 154, 32, 0, 1567, 329, 1, 0, 0, 0, 1568, 1569, 7, 15, 0, 0, 1569, 1570, 7, 7, 0, 0, 1570, 1571, 7, 11, 0, 0, 1571, 1572, 7, 4, 0, 0, 1572, 1573, 7, 16, 0, 0, 1573, 1574, 7, 4, 0, 0, 1574, 1575, 7, 11, 0, 0, 1575, 1576, 7, 4, 0, 0, 1576, 331, 1, 0, 0, 0, 1577, 1578, 3, 306, 143, 0, 1578, 1579, 1, 0, 0, 0, 1579, 1580, 6, 156, 19, 0, 1580, 1581, 6, 156, 18, 0, 1581, 1582, 6, 156, 18, 0, 1582, 333, 1, 0, 0, 0, 1583, 1584, 3, 304, 142, 0, 1584, 1585, 1, 0, 0, 0, 1585, 1586, 6, 157, 38, 0, 1586, 1587, 6, 157, 39, 0, 1587, 335, 1, 0, 0, 0, 1588, 1592, 8, 34, 0, 0, 1589, 1590, 5, 47, 0, 0, 1590, 1592, 8, 35, 0, 0, 1591, 1588, 1, 0, 0, 0, 1591, 1589, 1, 0, 0, 0, 1592, 337, 1, 0, 0, 0, 1593, 1595, 3, 336, 158, 0, 1594, 1593, 1, 0, 0, 0, 1595, 1596, 1, 0, 0, 0, 1596, 1594, 1, 0, 0, 0, 1596, 1597, 1, 0, 0, 0, 1597, 339, 1, 0, 0, 0, 1598, 1599, 3, 338, 159, 0, 1599, 1600, 1, 0, 0, 0, 1600, 1601, 6, 160, 43, 0, 1601, 341, 1, 0, 0, 0, 1602, 1603, 3, 208, 94, 0, 1603, 1604, 1, 0, 0, 0, 1604, 1605, 6, 161, 31, 0, 1605, 343, 1, 0, 0, 0, 1606, 1607, 3, 20, 0, 0, 1607, 1608, 1, 0, 0, 0, 1608, 1609, 6, 162, 0, 0, 1609, 345, 1, 0, 0, 0, 1610, 1611, 3, 22, 1, 0, 1611, 1612, 1, 0, 0, 0, 1612, 1613, 6, 163, 0, 0, 1613, 347, 1, 0, 0, 0, 1614, 1615, 3, 24, 2, 0, 1615, 1616, 1, 0, 0, 0, 1616, 1617, 6, 164, 0, 0, 1617, 349, 1, 0, 0, 0, 1618, 1619, 3, 304, 142, 0, 1619, 1620, 1, 0, 0, 0, 1620, 1621, 6, 165, 38, 0, 1621, 1622, 6, 165, 39, 0, 1622, 351, 1, 0, 0, 0, 1623, 1624, 3, 306, 143, 0, 1624, 1625, 1, 0, 0, 0, 1625, 1626, 6, 166, 19, 0, 1626, 1627, 6, 166, 18, 0, 1627, 1628, 6, 166, 18, 0, 1628, 353, 1, 0, 0, 0, 1629, 1630, 3, 186, 83, 0, 1630, 1631, 1, 0, 0, 0, 1631, 1632, 6, 167, 17, 0, 1632, 1633, 6, 167, 18, 0, 1633, 355, 1, 0, 0, 0, 1634, 1635, 3, 24, 2, 0, 1635, 1636, 1, 0, 0, 0, 1636, 1637, 6, 168, 0, 0, 1637, 357, 1, 0, 0, 0, 1638, 1639, 3, 20, 0, 0, 1639, 1640, 1, 0, 0, 0, 1640, 1641, 6, 169, 0, 0, 1641, 359, 1, 0, 0, 0, 1642, 1643, 3, 22, 1, 0, 1643, 1644, 1, 0, 0, 0, 1644, 1645, 6, 170, 0, 0, 1645, 361, 1, 0, 0, 0, 1646, 1647, 3, 186, 83, 0, 1647, 1648, 1, 0, 0, 0, 1648, 1649, 6, 171, 17, 0, 1649, 1650, 6, 171, 18, 0, 1650, 363, 1, 0, 0, 0, 1651, 1652, 3, 306, 143, 0, 1652, 1653, 1, 0, 0, 0, 1653, 1654, 6, 172, 19, 0, 1654, 1655, 6, 172, 18, 0, 1655, 1656, 6, 172, 18, 0, 1656, 365, 1, 0, 0, 0, 1657, 1658, 7, 6, 0, 0, 1658, 1659, 7, 12, 0, 0, 1659, 1660, 7, 9, 0, 0, 1660, 1661, 7, 22, 0, 0, 1661, 1662, 7, 8, 0, 0, 1662, 367, 1, 0, 0, 0, 1663, 1664, 7, 17, 0, 0, 1664, 1665, 7, 2, 0, 0, 1665, 1666, 7, 9, 0, 0, 1666, 1667, 7, 12, 0, 0, 1667, 1668, 7, 7, 0, 0, 1668, 369, 1, 0, 0, 0, 1669, 1670, 7, 19, 0, 0, 1670, 1671, 7, 7, 0, 0, 1671, 1672, 7, 33, 0, 0, 1672, 371, 1, 0, 0, 0, 1673, 1674, 3, 262, 121, 0, 1674, 1675, 1, 0, 0, 0, 1675, 1676, 6, 176, 29, 0, 1676, 1677, 6, 176, 18, 0, 1677, 1678, 6, 176, 4, 0, 1678, 373, 1, 0, 0, 0, 1679, 1680, 3, 228, 104, 0, 1680, 1681, 1, 0, 0, 0, 1681, 1682, 6, 177, 23, 0, 1682, 375, 1, 0, 0, 0, 1683, 1684, 3, 232, 106, 0, 1684, 1685, 1, 0, 0, 0, 1685, 1686, 6, 178, 22, 0, 1686, 377, 1, 0, 0, 0, 1687, 1688, 3, 256, 118, 0, 1688, 1689, 1, 0, 0, 0, 1689, 1690, 6, 179, 34, 0, 1690, 379, 1, 0, 0, 0, 1691, 1692, 3, 296, 138, 0, 1692, 1693, 1, 0, 0, 0, 1693, 1694, 6, 180, 35, 0, 1694, 381, 1, 0, 0, 0, 1695, 1696, 3, 292, 136, 0, 1696, 1697, 1, 0, 0, 0, 1697, 1698, 6, 181, 36, 0, 1698, 383, 1, 0, 0, 0, 1699, 1700, 3, 298, 139, 0, 1700, 1701, 1, 0, 0, 0, 1701, 1702, 6, 182, 37, 0, 1702, 385, 1, 0, 0, 0, 1703, 1704, 3, 220, 100, 0, 1704, 1705, 1, 0, 0, 0, 1705, 1706, 6, 183, 44, 0, 1706, 387, 1, 0, 0, 0, 1707, 1708, 3, 312, 146, 0, 1708, 1709, 1, 0, 0, 0, 1709, 1710, 6, 184, 26, 0, 1710, 389, 1, 0, 0, 0, 1711, 1712, 3, 308, 144, 0, 1712, 1713, 1, 0, 0, 0, 1713, 1714, 6, 185, 27, 0, 1714, 391, 1, 0, 0, 0, 1715, 1716, 3, 20, 0, 0, 1716, 1717, 1, 0, 0, 0, 1717, 1718, 6, 186, 0, 0, 1718, 393, 1, 0, 0, 0, 1719, 1720, 3, 22, 1, 0, 1720, 1721, 1, 0, 0, 0, 1721, 1722, 6, 187, 0, 0, 1722, 395, 1, 0, 0, 0, 1723, 1724, 3, 24, 2, 0, 1724, 1725, 1, 0, 0, 0, 1725, 1726, 6, 188, 0, 0, 1726, 397, 1, 0, 0, 0, 1727, 1728, 7, 17, 0, 0, 1728, 1729, 7, 11, 0, 0, 1729, 1730, 7, 4, 0, 0, 1730, 1731, 7, 11, 0, 0, 1731, 1732, 7, 17, 0, 0, 1732, 1733, 1, 0, 0, 0, 1733, 1734, 6, 189, 18, 0, 1734, 1735, 6, 189, 4, 0, 1735, 399, 1, 0, 0, 0, 1736, 1737, 3, 20, 0, 0, 1737, 1738, 1, 0, 0, 0, 1738, 1739, 6, 190, 0, 0, 1739, 401, 1, 0, 0, 0, 1740, 1741, 3, 22, 1, 0, 1741, 1742, 1, 0, 0, 0, 1742, 1743, 6, 191, 0, 0, 1743, 403, 1, 0, 0, 0, 1744, 1745, 3, 24, 2, 0, 1745, 1746, 1, 0, 0, 0, 1746, 1747, 6, 192, 0, 0, 1747, 405, 1, 0, 0, 0, 1748, 1749, 3, 186, 83, 0, 1749, 1750, 1, 0, 0, 0, 1750, 1751, 6, 193, 17, 0, 1751, 1752, 6, 193, 18, 0, 1752, 407, 1, 0, 0, 0, 1753, 1754, 7, 36, 0, 0, 1754, 1755, 7, 9, 0, 0, 1755, 1756, 7, 10, 0, 0, 1756, 1757, 7, 5, 0, 0, 1757, 409, 1, 0, 0, 0, 1758, 1759, 3, 586, 283, 0, 1759, 1760, 1, 0, 0, 0, 1760, 1761, 6, 195, 21, 0, 1761, 411, 1, 0, 0, 0, 1762, 1763, 3, 252, 116, 0, 1763, 1764, 1, 0, 0, 0, 1764, 1765, 6, 196, 20, 0, 1765, 1766, 6, 196, 18, 0, 1766, 1767, 6, 196, 4, 0, 1767, 413, 1, 0, 0, 0, 1768, 1769, 7, 22, 0, 0, 1769, 1770, 7, 17, 0, 0, 1770, 1771, 7, 10, 0, 0, 1771, 1772, 7, 5, 0, 0, 1772, 1773, 7, 6, 0, 0, 1773, 1774, 1, 0, 0, 0, 1774, 1775, 6, 197, 18, 0, 1775, 1776, 6, 197, 4, 0, 1776, 415, 1, 0, 0, 0, 1777, 1778, 3, 338, 159, 0, 1778, 1779, 1, 0, 0, 0, 1779, 1780, 6, 198, 43, 0, 1780, 417, 1, 0, 0, 0, 1781, 1782, 3, 208, 94, 0, 1782, 1783, 1, 0, 0, 0, 1783, 1784, 6, 199, 31, 0, 1784, 419, 1, 0, 0, 0, 1785, 1786, 3, 224, 102, 0, 1786, 1787, 1, 0, 0, 0, 1787, 1788, 6, 200, 41, 0, 1788, 421, 1, 0, 0, 0, 1789, 1790, 3, 20, 0, 0, 1790, 1791, 1, 0, 0, 0, 1791, 1792, 6, 201, 0, 0, 1792, 423, 1, 0, 0, 0, 1793, 1794, 3, 22, 1, 0, 1794, 1795, 1, 0, 0, 0, 1795, 1796, 6, 202, 0, 0, 1796, 425, 1, 0, 0, 0, 1797, 1798, 3, 24, 2, 0, 1798, 1799, 1, 0, 0, 0, 1799, 1800, 6, 203, 0, 0, 1800, 427, 1, 0, 0, 0, 1801, 1802, 3, 186, 83, 0, 1802, 1803, 1, 0, 0, 0, 1803, 1804, 6, 204, 17, 0, 1804, 1805, 6, 204, 18, 0, 1805, 429, 1, 0, 0, 0, 1806, 1807, 3, 306, 143, 0, 1807, 1808, 1, 0, 0, 0, 1808, 1809, 6, 205, 19, 0, 1809, 1810, 6, 205, 18, 0, 1810, 1811, 6, 205, 18, 0, 1811, 431, 1, 0, 0, 0, 1812, 1813, 3, 224, 102, 0, 1813, 1814, 1, 0, 0, 0, 1814, 1815, 6, 206, 41, 0, 1815, 433, 1, 0, 0, 0, 1816, 1817, 3, 228, 104, 0, 1817, 1818, 1, 0, 0, 0, 1818, 1819, 6, 207, 23, 0, 1819, 435, 1, 0, 0, 0, 1820, 1821, 3, 232, 106, 0, 1821, 1822, 1, 0, 0, 0, 1822, 1823, 6, 208, 22, 0, 1823, 437, 1, 0, 0, 0, 1824, 1825, 3, 252, 116, 0, 1825, 1826, 1, 0, 0, 0, 1826, 1827, 6, 209, 20, 0, 1827, 1828, 6, 209, 45, 0, 1828, 439, 1, 0, 0, 0, 1829, 1830, 3, 338, 159, 0, 1830, 1831, 1, 0, 0, 0, 1831, 1832, 6, 210, 43, 0, 1832, 441, 1, 0, 0, 0, 1833, 1834, 3, 208, 94, 0, 1834, 1835, 1, 0, 0, 0, 1835, 1836, 6, 211, 31, 0, 1836, 443, 1, 0, 0, 0, 1837, 1838, 3, 20, 0, 0, 1838, 1839, 1, 0, 0, 0, 1839, 1840, 6, 212, 0, 0, 1840, 445, 1, 0, 0, 0, 1841, 1842, 3, 22, 1, 0, 1842, 1843, 1, 0, 0, 0, 1843, 1844, 6, 213, 0, 0, 1844, 447, 1, 0, 0, 0, 1845, 1846, 3, 24, 2, 0, 1846, 1847, 1, 0, 0, 0, 1847, 1848, 6, 214, 0, 0, 1848, 449, 1, 0, 0, 0, 1849, 1850, 3, 186, 83, 0, 1850, 1851, 1, 0, 0, 0, 1851, 1852, 6, 215, 17, 0, 1852, 1853, 6, 215, 18, 0, 1853, 1854, 6, 215, 18, 0, 1854, 451, 1, 0, 0, 0, 1855, 1856, 3, 306, 143, 0, 1856, 1857, 1, 0, 0, 0, 1857, 1858, 6, 216, 19, 0, 1858, 1859, 6, 216, 18, 0, 1859, 1860, 6, 216, 18, 0, 1860, 1861, 6, 216, 18, 0, 1861, 453, 1, 0, 0, 0, 1862, 1863, 3, 228, 104, 0, 1863, 1864, 1, 0, 0, 0, 1864, 1865, 6, 217, 23, 0, 1865, 455, 1, 0, 0, 0, 1866, 1867, 3, 232, 106, 0, 1867, 1868, 1, 0, 0, 0, 1868, 1869, 6, 218, 22, 0, 1869, 457, 1, 0, 0, 0, 1870, 1871, 3, 518, 249, 0, 1871, 1872, 1, 0, 0, 0, 1872, 1873, 6, 219, 33, 0, 1873, 459, 1, 0, 0, 0, 1874, 1875, 3, 20, 0, 0, 1875, 1876, 1, 0, 0, 0, 1876, 1877, 6, 220, 0, 0, 1877, 461, 1, 0, 0, 0, 1878, 1879, 3, 22, 1, 0, 1879, 1880, 1, 0, 0, 0, 1880, 1881, 6, 221, 0, 0, 1881, 463, 1, 0, 0, 0, 1882, 1883, 3, 24, 2, 0, 1883, 1884, 1, 0, 0, 0, 1884, 1885, 6, 222, 0, 0, 1885, 465, 1, 0, 0, 0, 1886, 1887, 3, 186, 83, 0, 1887, 1888, 1, 0, 0, 0, 1888, 1889, 6, 223, 17, 0, 1889, 1890, 6, 223, 18, 0, 1890, 467, 1, 0, 0, 0, 1891, 1892, 3, 306, 143, 0, 1892, 1893, 1, 0, 0, 0, 1893, 1894, 6, 224, 19, 0, 1894, 1895, 6, 224, 18, 0, 1895, 1896, 6, 224, 18, 0, 1896, 469, 1, 0, 0, 0, 1897, 1898, 3, 300, 140, 0, 1898, 1899, 1, 0, 0, 0, 1899, 1900, 6, 225, 24, 0, 1900, 471, 1, 0, 0, 0, 1901, 1902, 3, 302, 141, 0, 1902, 1903, 1, 0, 0, 0, 1903, 1904, 6, 226, 25, 0, 1904, 473, 1, 0, 0, 0, 1905, 1906, 3, 232, 106, 0, 1906, 1907, 1, 0, 0, 0, 1907, 1908, 6, 227, 22, 0, 1908, 475, 1, 0, 0, 0, 1909, 1910, 3, 256, 118, 0, 1910, 1911, 1, 0, 0, 0, 1911, 1912, 6, 228, 34, 0, 1912, 477, 1, 0, 0, 0, 1913, 1914, 3, 296, 138, 0, 1914, 1915, 1, 0, 0, 0, 1915, 1916, 6, 229, 35, 0, 1916, 479, 1, 0, 0, 0, 1917, 1918, 3, 292, 136, 0, 1918, 1919, 1, 0, 0, 0, 1919, 1920, 6, 230, 36, 0, 1920, 481, 1, 0, 0, 0, 1921, 1922, 3, 298, 139, 0, 1922, 1923, 1, 0, 0, 0, 1923, 1924, 6, 231, 37, 0, 1924, 483, 1, 0, 0, 0, 1925, 1926, 3, 312, 146, 0, 1926, 1927, 1, 0, 0, 0, 1927, 1928, 6, 232, 26, 0, 1928, 485, 1, 0, 0, 0, 1929, 1930, 3, 308, 144, 0, 1930, 1931, 1, 0, 0, 0, 1931, 1932, 6, 233, 27, 0, 1932, 487, 1, 0, 0, 0, 1933, 1934, 3, 20, 0, 0, 1934, 1935, 1, 0, 0, 0, 1935, 1936, 6, 234, 0, 0, 1936, 489, 1, 0, 0, 0, 1937, 1938, 3, 22, 1, 0, 1938, 1939, 1, 0, 0, 0, 1939, 1940, 6, 235, 0, 0, 1940, 491, 1, 0, 0, 0, 1941, 1942, 3, 24, 2, 0, 1942, 1943, 1, 0, 0, 0, 1943, 1944, 6, 236, 0, 0, 1944, 493, 1, 0, 0, 0, 1945, 1946, 3, 186, 83, 0, 1946, 1947, 1, 0, 0, 0, 1947, 1948, 6, 237, 17, 0, 1948, 1949, 6, 237, 18, 0, 1949, 495, 1, 0, 0, 0, 1950, 1951, 3, 306, 143, 0, 1951, 1952, 1, 0, 0, 0, 1952, 1953, 6, 238, 19, 0, 1953, 1954, 6, 238, 18, 0, 1954, 1955, 6, 238, 18, 0, 1955, 497, 1, 0, 0, 0, 1956, 1957, 3, 232, 106, 0, 1957, 1958, 1, 0, 0, 0, 1958, 1959, 6, 239, 22, 0, 1959, 499, 1, 0, 0, 0, 1960, 1961, 3, 300, 140, 0, 1961, 1962, 1, 0, 0, 0, 1962, 1963, 6, 240, 24, 0, 1963, 501, 1, 0, 0, 0, 1964, 1965, 3, 302, 141, 0, 1965, 1966, 1, 0, 0, 0, 1966, 1967, 6, 241, 25, 0, 1967, 503, 1, 0, 0, 0, 1968, 1969, 3, 228, 104, 0, 1969, 1970, 1, 0, 0, 0, 1970, 1971, 6, 242, 23, 0, 1971, 505, 1, 0, 0, 0, 1972, 1973, 3, 256, 118, 0, 1973, 1974, 1, 0, 0, 0, 1974, 1975, 6, 243, 34, 0, 1975, 507, 1, 0, 0, 0, 1976, 1977, 3, 296, 138, 0, 1977, 1978, 1, 0, 0, 0, 1978, 1979, 6, 244, 35, 0, 1979, 509, 1, 0, 0, 0, 1980, 1981, 3, 292, 136, 0, 1981, 1982, 1, 0, 0, 0, 1982, 1983, 6, 245, 36, 0, 1983, 511, 1, 0, 0, 0, 1984, 1985, 3, 298, 139, 0, 1985, 1986, 1, 0, 0, 0, 1986, 1987, 6, 246, 37, 0, 1987, 513, 1, 0, 0, 0, 1988, 1993, 3, 190, 85, 0, 1989, 1993, 3, 188, 84, 0, 1990, 1993, 3, 204, 92, 0, 1991, 1993, 3, 282, 131, 0, 1992, 1988, 1, 0, 0, 0, 1992, 1989, 1, 0, 0, 0, 1992, 1990, 1, 0, 0, 0, 1992, 1991, 1, 0, 0, 0, 1993, 515, 1, 0, 0, 0, 1994, 1997, 3, 190, 85, 0, 1995, 1997, 3, 282, 131, 0, 1996, 1994, 1, 0, 0, 0, 1996, 1995, 1, 0, 0, 0, 1997, 2001, 1, 0, 0, 0, 1998, 2000, 3, 514, 247, 0, 1999, 1998, 1, 0, 0, 0, 2000, 2003, 1, 0, 0, 0, 2001, 1999, 1, 0, 0, 0, 2001, 2002, 1, 0, 0, 0, 2002, 2014, 1, 0, 0, 0, 2003, 2001, 1, 0, 0, 0, 2004, 2007, 3, 204, 92, 0, 2005, 2007, 3, 198, 89, 0, 2006, 2004, 1, 0, 0, 0, 2006, 2005, 1, 0, 0, 0, 2007, 2009, 1, 0, 0, 0, 2008, 2010, 3, 514, 247, 0, 2009, 2008, 1, 0, 0, 0, 2010, 2011, 1, 0, 0, 0, 2011, 2009, 1, 0, 0, 0, 2011, 2012, 1, 0, 0, 0, 2012, 2014, 1, 0, 0, 0, 2013, 1996, 1, 0, 0, 0, 2013, 2006, 1, 0, 0, 0, 2014, 517, 1, 0, 0, 0, 2015, 2018, 3, 516, 248, 0, 2016, 2018, 3, 310, 145, 0, 2017, 2015, 1, 0, 0, 0, 2017, 2016, 1, 0, 0, 0, 2018, 2019, 1, 0, 0, 0, 2019, 2017, 1, 0, 0, 0, 2019, 2020, 1, 0, 0, 0, 2020, 519, 1, 0, 0, 0, 2021, 2022, 3, 20, 0, 0, 2022, 2023, 1, 0, 0, 0, 2023, 2024, 6, 250, 0, 0, 2024, 521, 1, 0, 0, 0, 2025, 2026, 3, 22, 1, 0, 2026, 2027, 1, 0, 0, 0, 2027, 2028, 6, 251, 0, 0, 2028, 523, 1, 0, 0, 0, 2029, 2030, 3, 24, 2, 0, 2030, 2031, 1, 0, 0, 0, 2031, 2032, 6, 252, 0, 0, 2032, 525, 1, 0, 0, 0, 2033, 2037, 7, 37, 0, 0, 2034, 2036, 7, 38, 0, 0, 2035, 2034, 1, 0, 0, 0, 2036, 2039, 1, 0, 0, 0, 2037, 2035, 1, 0, 0, 0, 2037, 2038, 1, 0, 0, 0, 2038, 2047, 1, 0, 0, 0, 2039, 2037, 1, 0, 0, 0, 2040, 2042, 7, 39, 0, 0, 2041, 2043, 7, 38, 0, 0, 2042, 2041, 1, 0, 0, 0, 2043, 2044, 1, 0, 0, 0, 2044, 2042, 1, 0, 0, 0, 2044, 2045, 1, 0, 0, 0, 2045, 2047, 1, 0, 0, 0, 2046, 2033, 1, 0, 0, 0, 2046, 2040, 1, 0, 0, 0, 2047, 527, 1, 0, 0, 0, 2048, 2049, 3, 208, 94, 0, 2049, 2050, 1, 0, 0, 0, 2050, 2051, 6, 254, 31, 0, 2051, 529, 1, 0, 0, 0, 2052, 2053, 3, 312, 146, 0, 2053, 2054, 1, 0, 0, 0, 2054, 2055, 6, 255, 26, 0, 2055, 531, 1, 0, 0, 0, 2056, 2057, 3, 296, 138, 0, 2057, 2058, 1, 0, 0, 0, 2058, 2059, 6, 256, 35, 0, 2059, 533, 1, 0, 0, 0, 2060, 2061, 3, 186, 83, 0, 2061, 2062, 1, 0, 0, 0, 2062, 2063, 6, 257, 17, 0, 2063, 2064, 6, 257, 18, 0, 2064, 535, 1, 0, 0, 0, 2065, 2066, 3, 304, 142, 0, 2066, 2067, 6, 258, 46, 0, 2067, 2068, 1, 0, 0, 0, 2068, 2069, 6, 258, 38, 0, 2069, 2070, 6, 258, 47, 0, 2070, 537, 1, 0, 0, 0, 2071, 2072, 3, 20, 0, 0, 2072, 2073, 1, 0, 0, 0, 2073, 2074, 6, 259, 0, 0, 2074, 539, 1, 0, 0, 0, 2075, 2076, 3, 22, 1, 0, 2076, 2077, 1, 0, 0, 0, 2077, 2078, 6, 260, 0, 0, 2078, 541, 1, 0, 0, 0, 2079, 2080, 3, 24, 2, 0, 2080, 2081, 1, 0, 0, 0, 2081, 2082, 6, 261, 0, 0, 2082, 543, 1, 0, 0, 0, 2083, 2084, 5, 40, 0, 0, 2084, 2085, 6, 262, 48, 0, 2085, 2086, 1, 0, 0, 0, 2086, 2087, 6, 262, 38, 0, 2087, 545, 1, 0, 0, 0, 2088, 2092, 3, 548, 264, 0, 2089, 2092, 3, 550, 265, 0, 2090, 2092, 8, 40, 0, 0, 2091, 2088, 1, 0, 0, 0, 2091, 2089, 1, 0, 0, 0, 2091, 2090, 1, 0, 0, 0, 2092, 2093, 1, 0, 0, 0, 2093, 2091, 1, 0, 0, 0, 2093, 2094, 1, 0, 0, 0, 2094, 547, 1, 0, 0, 0, 2095, 2101, 5, 34, 0, 0, 2096, 2097, 5, 92, 0, 0, 2097, 2100, 9, 0, 0, 0, 2098, 2100, 8, 41, 0, 0, 2099, 2096, 1, 0, 0, 0, 2099, 2098, 1, 0, 0, 0, 2100, 2103, 1, 0, 0, 0, 2101, 2099, 1, 0, 0, 0, 2101, 2102, 1, 0, 0, 0, 2102, 2104, 1, 0, 0, 0, 2103, 2101, 1, 0, 0, 0, 2104, 2124, 5, 34, 0, 0, 2105, 2111, 5, 39, 0, 0, 2106, 2107, 5, 92, 0, 0, 2107, 2110, 9, 0, 0, 0, 2108, 2110, 8, 42, 0, 0, 2109, 2106, 1, 0, 0, 0, 2109, 2108, 1, 0, 0, 0, 2110, 2113, 1, 0, 0, 0, 2111, 2109, 1, 0, 0, 0, 2111, 2112, 1, 0, 0, 0, 2112, 2114, 1, 0, 0, 0, 2113, 2111, 1, 0, 0, 0, 2114, 2124, 5, 39, 0, 0, 2115, 2119, 5, 96, 0, 0, 2116, 2118, 8, 31, 0, 0, 2117, 2116, 1, 0, 0, 0, 2118, 2121, 1, 0, 0, 0, 2119, 2117, 1, 0, 0, 0, 2119, 2120, 1, 0, 0, 0, 2120, 2122, 1, 0, 0, 0, 2121, 2119, 1, 0, 0, 0, 2122, 2124, 5, 96, 0, 0, 2123, 2095, 1, 0, 0, 0, 2123, 2105, 1, 0, 0, 0, 2123, 2115, 1, 0, 0, 0, 2124, 549, 1, 0, 0, 0, 2125, 2129, 5, 35, 0, 0, 2126, 2128, 8, 0, 0, 0, 2127, 2126, 1, 0, 0, 0, 2128, 2131, 1, 0, 0, 0, 2129, 2127, 1, 0, 0, 0, 2129, 2130, 1, 0, 0, 0, 2130, 2133, 1, 0, 0, 0, 2131, 2129, 1, 0, 0, 0, 2132, 2134, 5, 13, 0, 0, 2133, 2132, 1, 0, 0, 0, 2133, 2134, 1, 0, 0, 0, 2134, 2136, 1, 0, 0, 0, 2135, 2137, 5, 10, 0, 0, 2136, 2135, 1, 0, 0, 0, 2136, 2137, 1, 0, 0, 0, 2137, 551, 1, 0, 0, 0, 2138, 2139, 5, 41, 0, 0, 2139, 2140, 4, 266, 7, 0, 2140, 2141, 6, 266, 49, 0, 2141, 2142, 1, 0, 0, 0, 2142, 2143, 6, 266, 19, 0, 2143, 553, 1, 0, 0, 0, 2144, 2145, 5, 41, 0, 0, 2145, 2146, 4, 267, 8, 0, 2146, 2147, 6, 267, 50, 0, 2147, 2148, 1, 0, 0, 0, 2148, 2149, 6, 267, 19, 0, 2149, 2150, 6, 267, 18, 0, 2150, 2151, 6, 267, 18, 0, 2151, 555, 1, 0, 0, 0, 2152, 2153, 3, 186, 83, 0, 2153, 2154, 1, 0, 0, 0, 2154, 2155, 6, 268, 17, 0, 2155, 2156, 6, 268, 18, 0, 2156, 2157, 6, 268, 18, 0, 2157, 557, 1, 0, 0, 0, 2158, 2159, 3, 20, 0, 0, 2159, 2160, 1, 0, 0, 0, 2160, 2161, 6, 269, 0, 0, 2161, 559, 1, 0, 0, 0, 2162, 2163, 3, 22, 1, 0, 2163, 2164, 1, 0, 0, 0, 2164, 2165, 6, 270, 0, 0, 2165, 561, 1, 0, 0, 0, 2166, 2167, 3, 24, 2, 0, 2167, 2168, 1, 0, 0, 0, 2168, 2169, 6, 271, 0, 0, 2169, 563, 1, 0, 0, 0, 2170, 2171, 3, 186, 83, 0, 2171, 2172, 1, 0, 0, 0, 2172, 2173, 6, 272, 17, 0, 2173, 2174, 6, 272, 18, 0, 2174, 565, 1, 0, 0, 0, 2175, 2176, 3, 306, 143, 0, 2176, 2177, 1, 0, 0, 0, 2177, 2178, 6, 273, 19, 0, 2178, 2179, 6, 273, 18, 0, 2179, 2180, 6, 273, 18, 0, 2180, 567, 1, 0, 0, 0, 2181, 2182, 3, 300, 140, 0, 2182, 2183, 1, 0, 0, 0, 2183, 2184, 6, 274, 24, 0, 2184, 569, 1, 0, 0, 0, 2185, 2186, 3, 302, 141, 0, 2186, 2187, 1, 0, 0, 0, 2187, 2188, 6, 275, 25, 0, 2188, 571, 1, 0, 0, 0, 2189, 2190, 3, 218, 99, 0, 2190, 2191, 1, 0, 0, 0, 2191, 2192, 6, 276, 32, 0, 2192, 573, 1, 0, 0, 0, 2193, 2194, 3, 228, 104, 0, 2194, 2195, 1, 0, 0, 0, 2195, 2196, 6, 277, 23, 0, 2196, 575, 1, 0, 0, 0, 2197, 2198, 3, 232, 106, 0, 2198, 2199, 1, 0, 0, 0, 2199, 2200, 6, 278, 22, 0, 2200, 577, 1, 0, 0, 0, 2201, 2202, 3, 256, 118, 0, 2202, 2203, 1, 0, 0, 0, 2203, 2204, 6, 279, 34, 0, 2204, 579, 1, 0, 0, 0, 2205, 2206, 3, 296, 138, 0, 2206, 2207, 1, 0, 0, 0, 2207, 2208, 6, 280, 35, 0, 2208, 581, 1, 0, 0, 0, 2209, 2210, 3, 292, 136, 0, 2210, 2211, 1, 0, 0, 0, 2211, 2212, 6, 281, 36, 0, 2212, 583, 1, 0, 0, 0, 2213, 2214, 3, 298, 139, 0, 2214, 2215, 1, 0, 0, 0, 2215, 2216, 6, 282, 37, 0, 2216, 585, 1, 0, 0, 0, 2217, 2218, 7, 4, 0, 0, 2218, 2219, 7, 17, 0, 0, 2219, 587, 1, 0, 0, 0, 2220, 2221, 3, 518, 249, 0, 2221, 2222, 1, 0, 0, 0, 2222, 2223, 6, 284, 33, 0, 2223, 589, 1, 0, 0, 0, 2224, 2225, 3, 20, 0, 0, 2225, 2226, 1, 0, 0, 0, 2226, 2227, 6, 285, 0, 0, 2227, 591, 1, 0, 0, 0, 2228, 2229, 3, 22, 1, 0, 2229, 2230, 1, 0, 0, 0, 2230, 2231, 6, 286, 0, 0, 2231, 593, 1, 0, 0, 0, 2232, 2233, 3, 24, 2, 0, 2233, 2234, 1, 0, 0, 0, 2234, 2235, 6, 287, 0, 0, 2235, 595, 1, 0, 0, 0, 2236, 2237, 3, 260, 120, 0, 2237, 2238, 1, 0, 0, 0, 2238, 2239, 6, 288, 51, 0, 2239, 597, 1, 0, 0, 0, 2240, 2241, 3, 234, 107, 0, 2241, 2242, 1, 0, 0, 0, 2242, 2243, 6, 289, 52, 0, 2243, 599, 1, 0, 0, 0, 2244, 2245, 3, 248, 114, 0, 2245, 2246, 1, 0, 0, 0, 2246, 2247, 6, 290, 53, 0, 2247, 601, 1, 0, 0, 0, 2248, 2249, 3, 226, 103, 0, 2249, 2250, 1, 0, 0, 0, 2250, 2251, 6, 291, 54, 0, 2251, 2252, 6, 291, 18, 0, 2252, 603, 1, 0, 0, 0, 2253, 2254, 3, 218, 99, 0, 2254, 2255, 1, 0, 0, 0, 2255, 2256, 6, 292, 32, 0, 2256, 605, 1, 0, 0, 0, 2257, 2258, 3, 208, 94, 0, 2258, 2259, 1, 0, 0, 0, 2259, 2260, 6, 293, 31, 0, 2260, 607, 1, 0, 0, 0, 2261, 2262, 3, 308, 144, 0, 2262, 2263, 1, 0, 0, 0, 2263, 2264, 6, 294, 27, 0, 2264, 609, 1, 0, 0, 0, 2265, 2266, 3, 312, 146, 0, 2266, 2267, 1, 0, 0, 0, 2267, 2268, 6, 295, 26, 0, 2268, 611, 1, 0, 0, 0, 2269, 2270, 3, 212, 96, 0, 2270, 2271, 1, 0, 0, 0, 2271, 2272, 6, 296, 55, 0, 2272, 613, 1, 0, 0, 0, 2273, 2274, 3, 210, 95, 0, 2274, 2275, 1, 0, 0, 0, 2275, 2276, 6, 297, 56, 0, 2276, 615, 1, 0, 0, 0, 2277, 2278, 3, 228, 104, 0, 2278, 2279, 1, 0, 0, 0, 2279, 2280, 6, 298, 23, 0, 2280, 617, 1, 0, 0, 0, 2281, 2282, 3, 232, 106, 0, 2282, 2283, 1, 0, 0, 0, 2283, 2284, 6, 299, 22, 0, 2284, 619, 1, 0, 0, 0, 2285, 2286, 3, 256, 118, 0, 2286, 2287, 1, 0, 0, 0, 2287, 2288, 6, 300, 34, 0, 2288, 621, 1, 0, 0, 0, 2289, 2290, 3, 296, 138, 0, 2290, 2291, 1, 0, 0, 0, 2291, 2292, 6, 301, 35, 0, 2292, 623, 1, 0, 0, 0, 2293, 2294, 3, 292, 136, 0, 2294, 2295, 1, 0, 0, 0, 2295, 2296, 6, 302, 36, 0, 2296, 625, 1, 0, 0, 0, 2297, 2298, 3, 298, 139, 0, 2298, 2299, 1, 0, 0, 0, 2299, 2300, 6, 303, 37, 0, 2300, 627, 1, 0, 0, 0, 2301, 2302, 3, 300, 140, 0, 2302, 2303, 1, 0, 0, 0, 2303, 2304, 6, 304, 24, 0, 2304, 629, 1, 0, 0, 0, 2305, 2306, 3, 302, 141, 0, 2306, 2307, 1, 0, 0, 0, 2307, 2308, 6, 305, 25, 0, 2308, 631, 1, 0, 0, 0, 2309, 2310, 3, 518, 249, 0, 2310, 2311, 1, 0, 0, 0, 2311, 2312, 6, 306, 33, 0, 2312, 633, 1, 0, 0, 0, 2313, 2314, 3, 20, 0, 0, 2314, 2315, 1, 0, 0, 0, 2315, 2316, 6, 307, 0, 0, 2316, 635, 1, 0, 0, 0, 2317, 2318, 3, 22, 1, 0, 2318, 2319, 1, 0, 0, 0, 2319, 2320, 6, 308, 0, 0, 2320, 637, 1, 0, 0, 0, 2321, 2322, 3, 24, 2, 0, 2322, 2323, 1, 0, 0, 0, 2323, 2324, 6, 309, 0, 0, 2324, 639, 1, 0, 0, 0, 2325, 2326, 3, 186, 83, 0, 2326, 2327, 1, 0, 0, 0, 2327, 2328, 6, 310, 17, 0, 2328, 2329, 6, 310, 18, 0, 2329, 641, 1, 0, 0, 0, 2330, 2331, 7, 10, 0, 0, 2331, 2332, 7, 5, 0, 0, 2332, 2333, 7, 21, 0, 0, 2333, 2334, 7, 9, 0, 0, 2334, 643, 1, 0, 0, 0, 2335, 2336, 3, 20, 0, 0, 2336, 2337, 1, 0, 0, 0, 2337, 2338, 6, 312, 0, 0, 2338, 645, 1, 0, 0, 0, 2339, 2340, 3, 22, 1, 0, 2340, 2341, 1, 0, 0, 0, 2341, 2342, 6, 313, 0, 0, 2342, 647, 1, 0, 0, 0, 2343, 2344, 3, 24, 2, 0, 2344, 2345, 1, 0, 0, 0, 2345, 2346, 6, 314, 0, 0, 2346, 649, 1, 0, 0, 0, 86, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 656, 660, 663, 672, 674, 685, 984, 1069, 1073, 1078, 1210, 1215, 1224, 1231, 1236, 1238, 1249, 1257, 1260, 1262, 1267, 1272, 1278, 1285, 1290, 1296, 1299, 1307, 1311, 1452, 1457, 1464, 1466, 1471, 1476, 1483, 1485, 1511, 1516, 1521, 1523, 1529, 1591, 1596, 1992, 1996, 2001, 2006, 2011, 2013, 2017, 2019, 2037, 2044, 2046, 2091, 2093, 2099, 2101, 2109, 2111, 2119, 2123, 2129, 2133, 2136, 57, 0, 1, 0, 5, 1, 0, 5, 2, 0, 5, 4, 0, 5, 5, 0, 5, 6, 0, 5, 7, 0, 5, 8, 0, 5, 9, 0, 5, 10, 0, 5, 11, 0, 5, 13, 0, 5, 14, 0, 5, 15, 0, 5, 17, 0, 5, 18, 0, 5, 19, 0, 7, 51, 0, 4, 0, 0, 7, 100, 0, 7, 74, 0, 7, 150, 0, 7, 64, 0, 7, 62, 0, 7, 97, 0, 7, 98, 0, 7, 102, 0, 7, 101, 0, 5, 3, 0, 7, 79, 0, 7, 41, 0, 7, 52, 0, 7, 57, 0, 7, 138, 0, 7, 76, 0, 7, 95, 0, 7, 94, 0, 7, 96, 0, 7, 99, 0, 5, 0, 0, 7, 17, 0, 7, 60, 0, 7, 59, 0, 7, 107, 0, 7, 58, 0, 5, 12, 0, 1, 258, 0, 5, 16, 0, 1, 262, 1, 1, 266, 2, 1, 267, 3, 7, 78, 0, 7, 65, 0, 7, 72, 0, 7, 61, 0, 7, 54, 0, 7, 53, 0] \ No newline at end of file diff --git a/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/parser/EsqlBaseLexer.java b/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/parser/EsqlBaseLexer.java index 22c4fa8988eee..969c98cba88a3 100644 --- a/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/parser/EsqlBaseLexer.java +++ b/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/parser/EsqlBaseLexer.java @@ -30,37 +30,41 @@ public class EsqlBaseLexer extends LexerConfig { SAMPLE=14, SORT=15, STATS=16, WHERE=17, FROM=18, TS=19, FORK=20, FUSE=21, INLINE=22, INLINESTATS=23, JOIN_LOOKUP=24, DEV_JOIN_FULL=25, DEV_JOIN_LEFT=26, DEV_JOIN_RIGHT=27, DEV_LOOKUP=28, MV_EXPAND=29, DROP=30, KEEP=31, DEV_INSIST=32, - RENAME=33, SET=34, SHOW=35, UNKNOWN_CMD=36, CHANGE_POINT_LINE_COMMENT=37, - CHANGE_POINT_MULTILINE_COMMENT=38, CHANGE_POINT_WS=39, ENRICH_POLICY_NAME=40, - ENRICH_LINE_COMMENT=41, ENRICH_MULTILINE_COMMENT=42, ENRICH_WS=43, ENRICH_FIELD_LINE_COMMENT=44, - ENRICH_FIELD_MULTILINE_COMMENT=45, ENRICH_FIELD_WS=46, EXPLAIN_WS=47, - EXPLAIN_LINE_COMMENT=48, EXPLAIN_MULTILINE_COMMENT=49, PIPE=50, QUOTED_STRING=51, - INTEGER_LITERAL=52, DECIMAL_LITERAL=53, AND=54, ASC=55, ASSIGN=56, BY=57, - CAST_OP=58, COLON=59, SEMICOLON=60, COMMA=61, DESC=62, DOT=63, FALSE=64, - FIRST=65, IN=66, IS=67, LAST=68, LIKE=69, NOT=70, NULL=71, NULLS=72, ON=73, - OR=74, PARAM=75, RLIKE=76, TRUE=77, WITH=78, EQ=79, CIEQ=80, NEQ=81, LT=82, - LTE=83, GT=84, GTE=85, PLUS=86, MINUS=87, ASTERISK=88, SLASH=89, PERCENT=90, - LEFT_BRACES=91, RIGHT_BRACES=92, DOUBLE_PARAMS=93, NAMED_OR_POSITIONAL_PARAM=94, - NAMED_OR_POSITIONAL_DOUBLE_PARAMS=95, OPENING_BRACKET=96, CLOSING_BRACKET=97, - LP=98, RP=99, UNQUOTED_IDENTIFIER=100, QUOTED_IDENTIFIER=101, EXPR_LINE_COMMENT=102, - EXPR_MULTILINE_COMMENT=103, EXPR_WS=104, METADATA=105, UNQUOTED_SOURCE=106, - FROM_LINE_COMMENT=107, FROM_MULTILINE_COMMENT=108, FROM_WS=109, FORK_WS=110, - FORK_LINE_COMMENT=111, FORK_MULTILINE_COMMENT=112, GROUP=113, SCORE=114, - KEY=115, FUSE_LINE_COMMENT=116, FUSE_MULTILINE_COMMENT=117, FUSE_WS=118, - INLINE_STATS=119, INLINE_LINE_COMMENT=120, INLINE_MULTILINE_COMMENT=121, - INLINE_WS=122, JOIN=123, USING=124, JOIN_LINE_COMMENT=125, JOIN_MULTILINE_COMMENT=126, - JOIN_WS=127, LOOKUP_LINE_COMMENT=128, LOOKUP_MULTILINE_COMMENT=129, LOOKUP_WS=130, - LOOKUP_FIELD_LINE_COMMENT=131, LOOKUP_FIELD_MULTILINE_COMMENT=132, LOOKUP_FIELD_WS=133, - MVEXPAND_LINE_COMMENT=134, MVEXPAND_MULTILINE_COMMENT=135, MVEXPAND_WS=136, - ID_PATTERN=137, PROJECT_LINE_COMMENT=138, PROJECT_MULTILINE_COMMENT=139, - PROJECT_WS=140, AS=141, RENAME_LINE_COMMENT=142, RENAME_MULTILINE_COMMENT=143, - RENAME_WS=144, SET_LINE_COMMENT=145, SET_MULTILINE_COMMENT=146, SET_WS=147, - INFO=148, SHOW_LINE_COMMENT=149, SHOW_MULTILINE_COMMENT=150, SHOW_WS=151; + DEV_PROMQL=33, RENAME=34, SET=35, SHOW=36, UNKNOWN_CMD=37, CHANGE_POINT_LINE_COMMENT=38, + CHANGE_POINT_MULTILINE_COMMENT=39, CHANGE_POINT_WS=40, ENRICH_POLICY_NAME=41, + ENRICH_LINE_COMMENT=42, ENRICH_MULTILINE_COMMENT=43, ENRICH_WS=44, ENRICH_FIELD_LINE_COMMENT=45, + ENRICH_FIELD_MULTILINE_COMMENT=46, ENRICH_FIELD_WS=47, EXPLAIN_WS=48, + EXPLAIN_LINE_COMMENT=49, EXPLAIN_MULTILINE_COMMENT=50, PIPE=51, QUOTED_STRING=52, + INTEGER_LITERAL=53, DECIMAL_LITERAL=54, AND=55, ASC=56, ASSIGN=57, BY=58, + CAST_OP=59, COLON=60, SEMICOLON=61, COMMA=62, DESC=63, DOT=64, FALSE=65, + FIRST=66, IN=67, IS=68, LAST=69, LIKE=70, NOT=71, NULL=72, NULLS=73, ON=74, + OR=75, PARAM=76, RLIKE=77, TRUE=78, WITH=79, EQ=80, CIEQ=81, NEQ=82, LT=83, + LTE=84, GT=85, GTE=86, PLUS=87, MINUS=88, ASTERISK=89, SLASH=90, PERCENT=91, + LEFT_BRACES=92, RIGHT_BRACES=93, DOUBLE_PARAMS=94, NAMED_OR_POSITIONAL_PARAM=95, + NAMED_OR_POSITIONAL_DOUBLE_PARAMS=96, OPENING_BRACKET=97, CLOSING_BRACKET=98, + LP=99, RP=100, UNQUOTED_IDENTIFIER=101, QUOTED_IDENTIFIER=102, EXPR_LINE_COMMENT=103, + EXPR_MULTILINE_COMMENT=104, EXPR_WS=105, METADATA=106, UNQUOTED_SOURCE=107, + FROM_LINE_COMMENT=108, FROM_MULTILINE_COMMENT=109, FROM_WS=110, FORK_WS=111, + FORK_LINE_COMMENT=112, FORK_MULTILINE_COMMENT=113, GROUP=114, SCORE=115, + KEY=116, FUSE_LINE_COMMENT=117, FUSE_MULTILINE_COMMENT=118, FUSE_WS=119, + INLINE_STATS=120, INLINE_LINE_COMMENT=121, INLINE_MULTILINE_COMMENT=122, + INLINE_WS=123, JOIN=124, USING=125, JOIN_LINE_COMMENT=126, JOIN_MULTILINE_COMMENT=127, + JOIN_WS=128, LOOKUP_LINE_COMMENT=129, LOOKUP_MULTILINE_COMMENT=130, LOOKUP_WS=131, + LOOKUP_FIELD_LINE_COMMENT=132, LOOKUP_FIELD_MULTILINE_COMMENT=133, LOOKUP_FIELD_WS=134, + MVEXPAND_LINE_COMMENT=135, MVEXPAND_MULTILINE_COMMENT=136, MVEXPAND_WS=137, + ID_PATTERN=138, PROJECT_LINE_COMMENT=139, PROJECT_MULTILINE_COMMENT=140, + PROJECT_WS=141, PROMQL_UNQUOTED_IDENTIFIER=142, PROMQL_PARAMS_LINE_COMMENT=143, + PROMQL_PARAMS_MULTILINE_COMMENT=144, PROMQL_PARAMS_WS=145, PROMQL_QUERY_TEXT=146, + PROMQL_QUERY_LINE_COMMENT=147, PROMQL_QUERY_MULTILINE_COMMENT=148, PROMQL_QUERY_WS=149, + AS=150, RENAME_LINE_COMMENT=151, RENAME_MULTILINE_COMMENT=152, RENAME_WS=153, + SET_LINE_COMMENT=154, SET_MULTILINE_COMMENT=155, SET_WS=156, INFO=157, + SHOW_LINE_COMMENT=158, SHOW_MULTILINE_COMMENT=159, SHOW_WS=160; public static final int CHANGE_POINT_MODE=1, ENRICH_MODE=2, ENRICH_FIELD_MODE=3, EXPLAIN_MODE=4, EXPRESSION_MODE=5, FROM_MODE=6, FORK_MODE=7, FUSE_MODE=8, INLINE_MODE=9, JOIN_MODE=10, LOOKUP_MODE=11, LOOKUP_FIELD_MODE=12, MVEXPAND_MODE=13, - PROJECT_MODE=14, RENAME_MODE=15, SET_MODE=16, SHOW_MODE=17; + PROJECT_MODE=14, PROMQL_PARAMS_MODE=15, PROMQL_QUERY_MODE=16, RENAME_MODE=17, + SET_MODE=18, SHOW_MODE=19; public static String[] channelNames = { "DEFAULT_TOKEN_CHANNEL", "HIDDEN" }; @@ -69,7 +73,8 @@ public class EsqlBaseLexer extends LexerConfig { "DEFAULT_MODE", "CHANGE_POINT_MODE", "ENRICH_MODE", "ENRICH_FIELD_MODE", "EXPLAIN_MODE", "EXPRESSION_MODE", "FROM_MODE", "FORK_MODE", "FUSE_MODE", "INLINE_MODE", "JOIN_MODE", "LOOKUP_MODE", "LOOKUP_FIELD_MODE", "MVEXPAND_MODE", - "PROJECT_MODE", "RENAME_MODE", "SET_MODE", "SHOW_MODE" + "PROJECT_MODE", "PROMQL_PARAMS_MODE", "PROMQL_QUERY_MODE", "RENAME_MODE", + "SET_MODE", "SHOW_MODE" }; private static String[] makeRuleNames() { @@ -79,17 +84,18 @@ private static String[] makeRuleNames() { "ROW", "SAMPLE", "SORT", "STATS", "WHERE", "FROM", "TS", "FORK", "FUSE", "INLINE", "INLINESTATS", "JOIN_LOOKUP", "DEV_JOIN_FULL", "DEV_JOIN_LEFT", "DEV_JOIN_RIGHT", "DEV_LOOKUP", "MV_EXPAND", "DROP", "KEEP", "DEV_INSIST", - "RENAME", "SET", "SHOW", "UNKNOWN_CMD", "CHANGE_POINT_PIPE", "CHANGE_POINT_RP", - "CHANGE_POINT_ON", "CHANGE_POINT_AS", "CHANGE_POINT_DOT", "CHANGE_POINT_COMMA", - "CHANGE_POINT_OPENING_BRACKET", "CHANGE_POINT_CLOSING_BRACKET", "CHANGE_POINT_QUOTED_IDENTIFIER", - "CHANGE_POINT_UNQUOTED_IDENTIFIER", "CHANGE_POINT_LINE_COMMENT", "CHANGE_POINT_MULTILINE_COMMENT", - "CHANGE_POINT_WS", "ENRICH_PIPE", "ENRICH_RP", "ENRICH_ON", "ENRICH_WITH", - "ENRICH_POLICY_NAME_BODY", "ENRICH_POLICY_NAME", "ENRICH_MODE_UNQUOTED_VALUE", - "ENRICH_QUOTED_POLICY_NAME", "ENRICH_LINE_COMMENT", "ENRICH_MULTILINE_COMMENT", - "ENRICH_WS", "ENRICH_FIELD_PIPE", "ENRICH_FIELD_RP", "ENRICH_FIELD_OPENING_BRACKET", - "ENRICH_FIELD_CLOSING_BRACKET", "ENRICH_FIELD_ASSIGN", "ENRICH_FIELD_COMMA", - "ENRICH_FIELD_DOT", "ENRICH_FIELD_WITH", "ENRICH_FIELD_ID_PATTERN", "ENRICH_FIELD_QUOTED_IDENTIFIER", - "ENRICH_FIELD_PARAM", "ENRICH_FIELD_NAMED_OR_POSITIONAL_PARAM", "ENRICH_FIELD_DOUBLE_PARAMS", + "DEV_PROMQL", "RENAME", "SET", "SHOW", "UNKNOWN_CMD", "CHANGE_POINT_PIPE", + "CHANGE_POINT_RP", "CHANGE_POINT_ON", "CHANGE_POINT_AS", "CHANGE_POINT_DOT", + "CHANGE_POINT_COMMA", "CHANGE_POINT_OPENING_BRACKET", "CHANGE_POINT_CLOSING_BRACKET", + "CHANGE_POINT_QUOTED_IDENTIFIER", "CHANGE_POINT_UNQUOTED_IDENTIFIER", + "CHANGE_POINT_LINE_COMMENT", "CHANGE_POINT_MULTILINE_COMMENT", "CHANGE_POINT_WS", + "ENRICH_PIPE", "ENRICH_RP", "ENRICH_ON", "ENRICH_WITH", "ENRICH_POLICY_NAME_BODY", + "ENRICH_POLICY_NAME", "ENRICH_MODE_UNQUOTED_VALUE", "ENRICH_QUOTED_POLICY_NAME", + "ENRICH_LINE_COMMENT", "ENRICH_MULTILINE_COMMENT", "ENRICH_WS", "ENRICH_FIELD_PIPE", + "ENRICH_FIELD_RP", "ENRICH_FIELD_OPENING_BRACKET", "ENRICH_FIELD_CLOSING_BRACKET", + "ENRICH_FIELD_ASSIGN", "ENRICH_FIELD_COMMA", "ENRICH_FIELD_DOT", "ENRICH_FIELD_WITH", + "ENRICH_FIELD_ID_PATTERN", "ENRICH_FIELD_QUOTED_IDENTIFIER", "ENRICH_FIELD_PARAM", + "ENRICH_FIELD_NAMED_OR_POSITIONAL_PARAM", "ENRICH_FIELD_DOUBLE_PARAMS", "ENRICH_FIELD_NAMED_OR_POSITIONAL_DOUBLE_PARAMS", "ENRICH_FIELD_LINE_COMMENT", "ENRICH_FIELD_MULTILINE_COMMENT", "ENRICH_FIELD_WS", "EXPLAIN_LP", "EXPLAIN_PIPE", "EXPLAIN_WS", "EXPLAIN_LINE_COMMENT", "EXPLAIN_MULTILINE_COMMENT", "PIPE", @@ -130,9 +136,14 @@ private static String[] makeRuleNames() { "PROJECT_COMMA", "PROJECT_PARAM", "PROJECT_NAMED_OR_POSITIONAL_PARAM", "PROJECT_DOUBLE_PARAMS", "PROJECT_NAMED_OR_POSITIONAL_DOUBLE_PARAMS", "UNQUOTED_ID_BODY_WITH_PATTERN", "UNQUOTED_ID_PATTERN", "ID_PATTERN", - "PROJECT_LINE_COMMENT", "PROJECT_MULTILINE_COMMENT", "PROJECT_WS", "RENAME_PIPE", - "RENAME_RP", "RENAME_OPENING_BRACKET", "RENAME_CLOSING_BRACKET", "RENAME_ASSIGN", - "RENAME_COMMA", "RENAME_DOT", "RENAME_PARAM", "RENAME_NAMED_OR_POSITIONAL_PARAM", + "PROJECT_LINE_COMMENT", "PROJECT_MULTILINE_COMMENT", "PROJECT_WS", "PROMQL_UNQUOTED_IDENTIFIER", + "PROMQL_QUOTED_STRING", "PROMQL_QUOTED_IDENTIFIER", "PROMQL_NAMED_PARAMS", + "PROMQL_PARAMS_PIPE", "PROMQL_LP", "PROMQL_PARAMS_LINE_COMMENT", "PROMQL_PARAMS_MULTILINE_COMMENT", + "PROMQL_PARAMS_WS", "PROMQL_NESTED_LP", "PROMQL_QUERY_TEXT", "PROMQL_STRING_LITERAL", + "PROMQL_QUERY_COMMENT", "PROMQL_NESTED_RP", "PROMQL_QUERY_RP", "PROMQL_QUERY_PIPE", + "PROMQL_QUERY_LINE_COMMENT", "PROMQL_QUERY_MULTILINE_COMMENT", "PROMQL_QUERY_WS", + "RENAME_PIPE", "RENAME_RP", "RENAME_OPENING_BRACKET", "RENAME_CLOSING_BRACKET", + "RENAME_ASSIGN", "RENAME_COMMA", "RENAME_DOT", "RENAME_PARAM", "RENAME_NAMED_OR_POSITIONAL_PARAM", "RENAME_DOUBLE_PARAMS", "RENAME_NAMED_OR_POSITIONAL_DOUBLE_PARAMS", "AS", "RENAME_ID_PATTERN", "RENAME_LINE_COMMENT", "RENAME_MULTILINE_COMMENT", "RENAME_WS", "SET_TRUE", "SET_FALSE", "SET_NULL", "SET_SEMICOLON", "SET_ASSIGN", @@ -152,18 +163,19 @@ private static String[] makeLiteralNames() { "'dissect'", "'eval'", "'grok'", "'limit'", "'rerank'", "'row'", "'sample'", "'sort'", null, "'where'", "'from'", "'ts'", "'fork'", "'fuse'", "'inline'", "'inlinestats'", "'lookup'", null, null, null, null, "'mv_expand'", "'drop'", - "'keep'", null, "'rename'", "'set'", "'show'", null, null, null, null, - null, null, null, null, null, null, null, null, null, null, "'|'", null, - null, null, "'and'", "'asc'", "'='", "'by'", "'::'", "':'", "';'", "','", - "'desc'", "'.'", "'false'", "'first'", "'in'", "'is'", "'last'", "'like'", - "'not'", "'null'", "'nulls'", "'on'", "'or'", "'?'", "'rlike'", "'true'", - "'with'", "'=='", "'=~'", "'!='", "'<'", "'<='", "'>'", "'>='", "'+'", - "'-'", "'*'", "'/'", "'%'", "'{'", "'}'", "'??'", null, null, null, "']'", - null, "')'", null, null, null, null, null, "'metadata'", null, null, - null, null, null, null, null, "'group'", "'score'", "'key'", null, null, - null, null, null, null, null, "'join'", "'USING'", null, null, null, + "'keep'", null, null, "'rename'", "'set'", "'show'", null, null, null, + null, null, null, null, null, null, null, null, null, null, null, "'|'", + null, null, null, "'and'", "'asc'", "'='", "'by'", "'::'", "':'", "';'", + "','", "'desc'", "'.'", "'false'", "'first'", "'in'", "'is'", "'last'", + "'like'", "'not'", "'null'", "'nulls'", "'on'", "'or'", "'?'", "'rlike'", + "'true'", "'with'", "'=='", "'=~'", "'!='", "'<'", "'<='", "'>'", "'>='", + "'+'", "'-'", "'*'", "'/'", "'%'", "'{'", "'}'", "'??'", null, null, + null, "']'", null, "')'", null, null, null, null, null, "'metadata'", + null, null, null, null, null, null, null, "'group'", "'score'", "'key'", + null, null, null, null, null, null, null, "'join'", "'USING'", null, null, null, null, null, null, null, null, null, null, null, null, null, - null, "'as'", null, null, null, null, null, null, "'info'" + null, null, null, null, null, null, null, null, null, null, null, "'as'", + null, null, null, null, null, null, "'info'" }; } private static final String[] _LITERAL_NAMES = makeLiteralNames(); @@ -174,7 +186,7 @@ private static String[] makeSymbolicNames() { "ROW", "SAMPLE", "SORT", "STATS", "WHERE", "FROM", "TS", "FORK", "FUSE", "INLINE", "INLINESTATS", "JOIN_LOOKUP", "DEV_JOIN_FULL", "DEV_JOIN_LEFT", "DEV_JOIN_RIGHT", "DEV_LOOKUP", "MV_EXPAND", "DROP", "KEEP", "DEV_INSIST", - "RENAME", "SET", "SHOW", "UNKNOWN_CMD", "CHANGE_POINT_LINE_COMMENT", + "DEV_PROMQL", "RENAME", "SET", "SHOW", "UNKNOWN_CMD", "CHANGE_POINT_LINE_COMMENT", "CHANGE_POINT_MULTILINE_COMMENT", "CHANGE_POINT_WS", "ENRICH_POLICY_NAME", "ENRICH_LINE_COMMENT", "ENRICH_MULTILINE_COMMENT", "ENRICH_WS", "ENRICH_FIELD_LINE_COMMENT", "ENRICH_FIELD_MULTILINE_COMMENT", "ENRICH_FIELD_WS", "EXPLAIN_WS", "EXPLAIN_LINE_COMMENT", @@ -195,9 +207,12 @@ private static String[] makeSymbolicNames() { "LOOKUP_MULTILINE_COMMENT", "LOOKUP_WS", "LOOKUP_FIELD_LINE_COMMENT", "LOOKUP_FIELD_MULTILINE_COMMENT", "LOOKUP_FIELD_WS", "MVEXPAND_LINE_COMMENT", "MVEXPAND_MULTILINE_COMMENT", "MVEXPAND_WS", "ID_PATTERN", "PROJECT_LINE_COMMENT", - "PROJECT_MULTILINE_COMMENT", "PROJECT_WS", "AS", "RENAME_LINE_COMMENT", - "RENAME_MULTILINE_COMMENT", "RENAME_WS", "SET_LINE_COMMENT", "SET_MULTILINE_COMMENT", - "SET_WS", "INFO", "SHOW_LINE_COMMENT", "SHOW_MULTILINE_COMMENT", "SHOW_WS" + "PROJECT_MULTILINE_COMMENT", "PROJECT_WS", "PROMQL_UNQUOTED_IDENTIFIER", + "PROMQL_PARAMS_LINE_COMMENT", "PROMQL_PARAMS_MULTILINE_COMMENT", "PROMQL_PARAMS_WS", + "PROMQL_QUERY_TEXT", "PROMQL_QUERY_LINE_COMMENT", "PROMQL_QUERY_MULTILINE_COMMENT", + "PROMQL_QUERY_WS", "AS", "RENAME_LINE_COMMENT", "RENAME_MULTILINE_COMMENT", + "RENAME_WS", "SET_LINE_COMMENT", "SET_MULTILINE_COMMENT", "SET_WS", "INFO", + "SHOW_LINE_COMMENT", "SHOW_MULTILINE_COMMENT", "SHOW_WS" }; } private static final String[] _SYMBOLIC_NAMES = makeSymbolicNames(); @@ -259,6 +274,51 @@ public EsqlBaseLexer(CharStream input) { @Override public ATN getATN() { return _ATN; } + @Override + public void action(RuleContext _localctx, int ruleIndex, int actionIndex) { + switch (ruleIndex) { + case 258: + PROMQL_LP_action((RuleContext)_localctx, actionIndex); + break; + case 262: + PROMQL_NESTED_LP_action((RuleContext)_localctx, actionIndex); + break; + case 266: + PROMQL_NESTED_RP_action((RuleContext)_localctx, actionIndex); + break; + case 267: + PROMQL_QUERY_RP_action((RuleContext)_localctx, actionIndex); + break; + } + } + private void PROMQL_LP_action(RuleContext _localctx, int actionIndex) { + switch (actionIndex) { + case 0: + this.incPromqlDepth(); + break; + } + } + private void PROMQL_NESTED_LP_action(RuleContext _localctx, int actionIndex) { + switch (actionIndex) { + case 1: + this.incPromqlDepth(); + break; + } + } + private void PROMQL_NESTED_RP_action(RuleContext _localctx, int actionIndex) { + switch (actionIndex) { + case 2: + this.decPromqlDepth(); + break; + } + } + private void PROMQL_QUERY_RP_action(RuleContext _localctx, int actionIndex) { + switch (actionIndex) { + case 3: + this.resetPromqlDepth(); + break; + } + } @Override public boolean sempred(RuleContext _localctx, int ruleIndex, int predIndex) { switch (ruleIndex) { @@ -274,6 +334,12 @@ public boolean sempred(RuleContext _localctx, int ruleIndex, int predIndex) { return DEV_LOOKUP_sempred((RuleContext)_localctx, predIndex); case 31: return DEV_INSIST_sempred((RuleContext)_localctx, predIndex); + case 32: + return DEV_PROMQL_sempred((RuleContext)_localctx, predIndex); + case 266: + return PROMQL_NESTED_RP_sempred((RuleContext)_localctx, predIndex); + case 267: + return PROMQL_QUERY_RP_sempred((RuleContext)_localctx, predIndex); } return true; } @@ -319,105 +385,133 @@ private boolean DEV_INSIST_sempred(RuleContext _localctx, int predIndex) { } return true; } + private boolean DEV_PROMQL_sempred(RuleContext _localctx, int predIndex) { + switch (predIndex) { + case 6: + return this.isDevVersion(); + } + return true; + } + private boolean PROMQL_NESTED_RP_sempred(RuleContext _localctx, int predIndex) { + switch (predIndex) { + case 7: + return this.isPromqlQuery(); + } + return true; + } + private boolean PROMQL_QUERY_RP_sempred(RuleContext _localctx, int predIndex) { + switch (predIndex) { + case 8: + return !this.isPromqlQuery(); + } + return true; + } public static final String _serializedATN = - "\u0004\u0000\u0097\u086e\u0006\uffff\uffff\u0006\uffff\uffff\u0006\uffff"+ + "\u0004\u0000\u00a0\u092b\u0006\uffff\uffff\u0006\uffff\uffff\u0006\uffff"+ + "\uffff\u0006\uffff\uffff\u0006\uffff\uffff\u0006\uffff\uffff\u0006\uffff"+ "\uffff\u0006\uffff\uffff\u0006\uffff\uffff\u0006\uffff\uffff\u0006\uffff"+ "\uffff\u0006\uffff\uffff\u0006\uffff\uffff\u0006\uffff\uffff\u0006\uffff"+ "\uffff\u0006\uffff\uffff\u0006\uffff\uffff\u0006\uffff\uffff\u0006\uffff"+ - "\uffff\u0006\uffff\uffff\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\u0007\n\u0002\u000b\u0007\u000b\u0002\f\u0007\f\u0002\r\u0007\r\u0002"+ - "\u000e\u0007\u000e\u0002\u000f\u0007\u000f\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\u0002\u001b\u0007\u001b\u0002\u001c\u0007\u001c\u0002"+ - "\u001d\u0007\u001d\u0002\u001e\u0007\u001e\u0002\u001f\u0007\u001f\u0002"+ - " \u0007 \u0002!\u0007!\u0002\"\u0007\"\u0002#\u0007#\u0002$\u0007$\u0002"+ - "%\u0007%\u0002&\u0007&\u0002\'\u0007\'\u0002(\u0007(\u0002)\u0007)\u0002"+ - "*\u0007*\u0002+\u0007+\u0002,\u0007,\u0002-\u0007-\u0002.\u0007.\u0002"+ - "/\u0007/\u00020\u00070\u00021\u00071\u00022\u00072\u00023\u00073\u0002"+ - "4\u00074\u00025\u00075\u00026\u00076\u00027\u00077\u00028\u00078\u0002"+ - "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\u0002I\u0007I\u0002J\u0007J\u0002K\u0007K\u0002L\u0007L\u0002"+ - "M\u0007M\u0002N\u0007N\u0002O\u0007O\u0002P\u0007P\u0002Q\u0007Q\u0002"+ - "R\u0007R\u0002S\u0007S\u0002T\u0007T\u0002U\u0007U\u0002V\u0007V\u0002"+ - "W\u0007W\u0002X\u0007X\u0002Y\u0007Y\u0002Z\u0007Z\u0002[\u0007[\u0002"+ - "\\\u0007\\\u0002]\u0007]\u0002^\u0007^\u0002_\u0007_\u0002`\u0007`\u0002"+ - "a\u0007a\u0002b\u0007b\u0002c\u0007c\u0002d\u0007d\u0002e\u0007e\u0002"+ - "f\u0007f\u0002g\u0007g\u0002h\u0007h\u0002i\u0007i\u0002j\u0007j\u0002"+ - "k\u0007k\u0002l\u0007l\u0002m\u0007m\u0002n\u0007n\u0002o\u0007o\u0002"+ - "p\u0007p\u0002q\u0007q\u0002r\u0007r\u0002s\u0007s\u0002t\u0007t\u0002"+ - "u\u0007u\u0002v\u0007v\u0002w\u0007w\u0002x\u0007x\u0002y\u0007y\u0002"+ - "z\u0007z\u0002{\u0007{\u0002|\u0007|\u0002}\u0007}\u0002~\u0007~\u0002"+ - "\u007f\u0007\u007f\u0002\u0080\u0007\u0080\u0002\u0081\u0007\u0081\u0002"+ - "\u0082\u0007\u0082\u0002\u0083\u0007\u0083\u0002\u0084\u0007\u0084\u0002"+ - "\u0085\u0007\u0085\u0002\u0086\u0007\u0086\u0002\u0087\u0007\u0087\u0002"+ - "\u0088\u0007\u0088\u0002\u0089\u0007\u0089\u0002\u008a\u0007\u008a\u0002"+ - "\u008b\u0007\u008b\u0002\u008c\u0007\u008c\u0002\u008d\u0007\u008d\u0002"+ - "\u008e\u0007\u008e\u0002\u008f\u0007\u008f\u0002\u0090\u0007\u0090\u0002"+ - "\u0091\u0007\u0091\u0002\u0092\u0007\u0092\u0002\u0093\u0007\u0093\u0002"+ - "\u0094\u0007\u0094\u0002\u0095\u0007\u0095\u0002\u0096\u0007\u0096\u0002"+ - "\u0097\u0007\u0097\u0002\u0098\u0007\u0098\u0002\u0099\u0007\u0099\u0002"+ - "\u009a\u0007\u009a\u0002\u009b\u0007\u009b\u0002\u009c\u0007\u009c\u0002"+ - "\u009d\u0007\u009d\u0002\u009e\u0007\u009e\u0002\u009f\u0007\u009f\u0002"+ - "\u00a0\u0007\u00a0\u0002\u00a1\u0007\u00a1\u0002\u00a2\u0007\u00a2\u0002"+ - "\u00a3\u0007\u00a3\u0002\u00a4\u0007\u00a4\u0002\u00a5\u0007\u00a5\u0002"+ - "\u00a6\u0007\u00a6\u0002\u00a7\u0007\u00a7\u0002\u00a8\u0007\u00a8\u0002"+ - "\u00a9\u0007\u00a9\u0002\u00aa\u0007\u00aa\u0002\u00ab\u0007\u00ab\u0002"+ - "\u00ac\u0007\u00ac\u0002\u00ad\u0007\u00ad\u0002\u00ae\u0007\u00ae\u0002"+ - "\u00af\u0007\u00af\u0002\u00b0\u0007\u00b0\u0002\u00b1\u0007\u00b1\u0002"+ - "\u00b2\u0007\u00b2\u0002\u00b3\u0007\u00b3\u0002\u00b4\u0007\u00b4\u0002"+ - "\u00b5\u0007\u00b5\u0002\u00b6\u0007\u00b6\u0002\u00b7\u0007\u00b7\u0002"+ - "\u00b8\u0007\u00b8\u0002\u00b9\u0007\u00b9\u0002\u00ba\u0007\u00ba\u0002"+ - "\u00bb\u0007\u00bb\u0002\u00bc\u0007\u00bc\u0002\u00bd\u0007\u00bd\u0002"+ - "\u00be\u0007\u00be\u0002\u00bf\u0007\u00bf\u0002\u00c0\u0007\u00c0\u0002"+ - "\u00c1\u0007\u00c1\u0002\u00c2\u0007\u00c2\u0002\u00c3\u0007\u00c3\u0002"+ - "\u00c4\u0007\u00c4\u0002\u00c5\u0007\u00c5\u0002\u00c6\u0007\u00c6\u0002"+ - "\u00c7\u0007\u00c7\u0002\u00c8\u0007\u00c8\u0002\u00c9\u0007\u00c9\u0002"+ - "\u00ca\u0007\u00ca\u0002\u00cb\u0007\u00cb\u0002\u00cc\u0007\u00cc\u0002"+ - "\u00cd\u0007\u00cd\u0002\u00ce\u0007\u00ce\u0002\u00cf\u0007\u00cf\u0002"+ - "\u00d0\u0007\u00d0\u0002\u00d1\u0007\u00d1\u0002\u00d2\u0007\u00d2\u0002"+ - "\u00d3\u0007\u00d3\u0002\u00d4\u0007\u00d4\u0002\u00d5\u0007\u00d5\u0002"+ - "\u00d6\u0007\u00d6\u0002\u00d7\u0007\u00d7\u0002\u00d8\u0007\u00d8\u0002"+ - "\u00d9\u0007\u00d9\u0002\u00da\u0007\u00da\u0002\u00db\u0007\u00db\u0002"+ - "\u00dc\u0007\u00dc\u0002\u00dd\u0007\u00dd\u0002\u00de\u0007\u00de\u0002"+ - "\u00df\u0007\u00df\u0002\u00e0\u0007\u00e0\u0002\u00e1\u0007\u00e1\u0002"+ - "\u00e2\u0007\u00e2\u0002\u00e3\u0007\u00e3\u0002\u00e4\u0007\u00e4\u0002"+ - "\u00e5\u0007\u00e5\u0002\u00e6\u0007\u00e6\u0002\u00e7\u0007\u00e7\u0002"+ - "\u00e8\u0007\u00e8\u0002\u00e9\u0007\u00e9\u0002\u00ea\u0007\u00ea\u0002"+ - "\u00eb\u0007\u00eb\u0002\u00ec\u0007\u00ec\u0002\u00ed\u0007\u00ed\u0002"+ - "\u00ee\u0007\u00ee\u0002\u00ef\u0007\u00ef\u0002\u00f0\u0007\u00f0\u0002"+ - "\u00f1\u0007\u00f1\u0002\u00f2\u0007\u00f2\u0002\u00f3\u0007\u00f3\u0002"+ - "\u00f4\u0007\u00f4\u0002\u00f5\u0007\u00f5\u0002\u00f6\u0007\u00f6\u0002"+ - "\u00f7\u0007\u00f7\u0002\u00f8\u0007\u00f8\u0002\u00f9\u0007\u00f9\u0002"+ - "\u00fa\u0007\u00fa\u0002\u00fb\u0007\u00fb\u0002\u00fc\u0007\u00fc\u0002"+ - "\u00fd\u0007\u00fd\u0002\u00fe\u0007\u00fe\u0002\u00ff\u0007\u00ff\u0002"+ - "\u0100\u0007\u0100\u0002\u0101\u0007\u0101\u0002\u0102\u0007\u0102\u0002"+ - "\u0103\u0007\u0103\u0002\u0104\u0007\u0104\u0002\u0105\u0007\u0105\u0002"+ - "\u0106\u0007\u0106\u0002\u0107\u0007\u0107\u0002\u0108\u0007\u0108\u0002"+ - "\u0109\u0007\u0109\u0002\u010a\u0007\u010a\u0002\u010b\u0007\u010b\u0002"+ - "\u010c\u0007\u010c\u0002\u010d\u0007\u010d\u0002\u010e\u0007\u010e\u0002"+ - "\u010f\u0007\u010f\u0002\u0110\u0007\u0110\u0002\u0111\u0007\u0111\u0002"+ - "\u0112\u0007\u0112\u0002\u0113\u0007\u0113\u0002\u0114\u0007\u0114\u0002"+ - "\u0115\u0007\u0115\u0002\u0116\u0007\u0116\u0002\u0117\u0007\u0117\u0002"+ - "\u0118\u0007\u0118\u0002\u0119\u0007\u0119\u0002\u011a\u0007\u011a\u0002"+ - "\u011b\u0007\u011b\u0002\u011c\u0007\u011c\u0002\u011d\u0007\u011d\u0002"+ - "\u011e\u0007\u011e\u0002\u011f\u0007\u011f\u0002\u0120\u0007\u0120\u0002"+ - "\u0121\u0007\u0121\u0002\u0122\u0007\u0122\u0002\u0123\u0007\u0123\u0002"+ - "\u0124\u0007\u0124\u0002\u0125\u0007\u0125\u0002\u0126\u0007\u0126\u0001"+ - "\u0000\u0001\u0000\u0001\u0000\u0001\u0000\u0005\u0000\u0265\b\u0000\n"+ - "\u0000\f\u0000\u0268\t\u0000\u0001\u0000\u0003\u0000\u026b\b\u0000\u0001"+ - "\u0000\u0003\u0000\u026e\b\u0000\u0001\u0000\u0001\u0000\u0001\u0001\u0001"+ - "\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0005\u0001\u0277\b\u0001\n"+ - "\u0001\f\u0001\u027a\t\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001"+ - "\u0001\u0001\u0001\u0001\u0002\u0004\u0002\u0282\b\u0002\u000b\u0002\f"+ - "\u0002\u0283\u0001\u0002\u0001\u0002\u0001\u0003\u0001\u0003\u0001\u0003"+ + "\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\u0007\n\u0002\u000b\u0007\u000b"+ + "\u0002\f\u0007\f\u0002\r\u0007\r\u0002\u000e\u0007\u000e\u0002\u000f\u0007"+ + "\u000f\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\u0002\u001b\u0007"+ + "\u001b\u0002\u001c\u0007\u001c\u0002\u001d\u0007\u001d\u0002\u001e\u0007"+ + "\u001e\u0002\u001f\u0007\u001f\u0002 \u0007 \u0002!\u0007!\u0002\"\u0007"+ + "\"\u0002#\u0007#\u0002$\u0007$\u0002%\u0007%\u0002&\u0007&\u0002\'\u0007"+ + "\'\u0002(\u0007(\u0002)\u0007)\u0002*\u0007*\u0002+\u0007+\u0002,\u0007"+ + ",\u0002-\u0007-\u0002.\u0007.\u0002/\u0007/\u00020\u00070\u00021\u0007"+ + "1\u00022\u00072\u00023\u00073\u00024\u00074\u00025\u00075\u00026\u0007"+ + "6\u00027\u00077\u00028\u00078\u00029\u00079\u0002:\u0007:\u0002;\u0007"+ + ";\u0002<\u0007<\u0002=\u0007=\u0002>\u0007>\u0002?\u0007?\u0002@\u0007"+ + "@\u0002A\u0007A\u0002B\u0007B\u0002C\u0007C\u0002D\u0007D\u0002E\u0007"+ + "E\u0002F\u0007F\u0002G\u0007G\u0002H\u0007H\u0002I\u0007I\u0002J\u0007"+ + "J\u0002K\u0007K\u0002L\u0007L\u0002M\u0007M\u0002N\u0007N\u0002O\u0007"+ + "O\u0002P\u0007P\u0002Q\u0007Q\u0002R\u0007R\u0002S\u0007S\u0002T\u0007"+ + "T\u0002U\u0007U\u0002V\u0007V\u0002W\u0007W\u0002X\u0007X\u0002Y\u0007"+ + "Y\u0002Z\u0007Z\u0002[\u0007[\u0002\\\u0007\\\u0002]\u0007]\u0002^\u0007"+ + "^\u0002_\u0007_\u0002`\u0007`\u0002a\u0007a\u0002b\u0007b\u0002c\u0007"+ + "c\u0002d\u0007d\u0002e\u0007e\u0002f\u0007f\u0002g\u0007g\u0002h\u0007"+ + "h\u0002i\u0007i\u0002j\u0007j\u0002k\u0007k\u0002l\u0007l\u0002m\u0007"+ + "m\u0002n\u0007n\u0002o\u0007o\u0002p\u0007p\u0002q\u0007q\u0002r\u0007"+ + "r\u0002s\u0007s\u0002t\u0007t\u0002u\u0007u\u0002v\u0007v\u0002w\u0007"+ + "w\u0002x\u0007x\u0002y\u0007y\u0002z\u0007z\u0002{\u0007{\u0002|\u0007"+ + "|\u0002}\u0007}\u0002~\u0007~\u0002\u007f\u0007\u007f\u0002\u0080\u0007"+ + "\u0080\u0002\u0081\u0007\u0081\u0002\u0082\u0007\u0082\u0002\u0083\u0007"+ + "\u0083\u0002\u0084\u0007\u0084\u0002\u0085\u0007\u0085\u0002\u0086\u0007"+ + "\u0086\u0002\u0087\u0007\u0087\u0002\u0088\u0007\u0088\u0002\u0089\u0007"+ + "\u0089\u0002\u008a\u0007\u008a\u0002\u008b\u0007\u008b\u0002\u008c\u0007"+ + "\u008c\u0002\u008d\u0007\u008d\u0002\u008e\u0007\u008e\u0002\u008f\u0007"+ + "\u008f\u0002\u0090\u0007\u0090\u0002\u0091\u0007\u0091\u0002\u0092\u0007"+ + "\u0092\u0002\u0093\u0007\u0093\u0002\u0094\u0007\u0094\u0002\u0095\u0007"+ + "\u0095\u0002\u0096\u0007\u0096\u0002\u0097\u0007\u0097\u0002\u0098\u0007"+ + "\u0098\u0002\u0099\u0007\u0099\u0002\u009a\u0007\u009a\u0002\u009b\u0007"+ + "\u009b\u0002\u009c\u0007\u009c\u0002\u009d\u0007\u009d\u0002\u009e\u0007"+ + "\u009e\u0002\u009f\u0007\u009f\u0002\u00a0\u0007\u00a0\u0002\u00a1\u0007"+ + "\u00a1\u0002\u00a2\u0007\u00a2\u0002\u00a3\u0007\u00a3\u0002\u00a4\u0007"+ + "\u00a4\u0002\u00a5\u0007\u00a5\u0002\u00a6\u0007\u00a6\u0002\u00a7\u0007"+ + "\u00a7\u0002\u00a8\u0007\u00a8\u0002\u00a9\u0007\u00a9\u0002\u00aa\u0007"+ + "\u00aa\u0002\u00ab\u0007\u00ab\u0002\u00ac\u0007\u00ac\u0002\u00ad\u0007"+ + "\u00ad\u0002\u00ae\u0007\u00ae\u0002\u00af\u0007\u00af\u0002\u00b0\u0007"+ + "\u00b0\u0002\u00b1\u0007\u00b1\u0002\u00b2\u0007\u00b2\u0002\u00b3\u0007"+ + "\u00b3\u0002\u00b4\u0007\u00b4\u0002\u00b5\u0007\u00b5\u0002\u00b6\u0007"+ + "\u00b6\u0002\u00b7\u0007\u00b7\u0002\u00b8\u0007\u00b8\u0002\u00b9\u0007"+ + "\u00b9\u0002\u00ba\u0007\u00ba\u0002\u00bb\u0007\u00bb\u0002\u00bc\u0007"+ + "\u00bc\u0002\u00bd\u0007\u00bd\u0002\u00be\u0007\u00be\u0002\u00bf\u0007"+ + "\u00bf\u0002\u00c0\u0007\u00c0\u0002\u00c1\u0007\u00c1\u0002\u00c2\u0007"+ + "\u00c2\u0002\u00c3\u0007\u00c3\u0002\u00c4\u0007\u00c4\u0002\u00c5\u0007"+ + "\u00c5\u0002\u00c6\u0007\u00c6\u0002\u00c7\u0007\u00c7\u0002\u00c8\u0007"+ + "\u00c8\u0002\u00c9\u0007\u00c9\u0002\u00ca\u0007\u00ca\u0002\u00cb\u0007"+ + "\u00cb\u0002\u00cc\u0007\u00cc\u0002\u00cd\u0007\u00cd\u0002\u00ce\u0007"+ + "\u00ce\u0002\u00cf\u0007\u00cf\u0002\u00d0\u0007\u00d0\u0002\u00d1\u0007"+ + "\u00d1\u0002\u00d2\u0007\u00d2\u0002\u00d3\u0007\u00d3\u0002\u00d4\u0007"+ + "\u00d4\u0002\u00d5\u0007\u00d5\u0002\u00d6\u0007\u00d6\u0002\u00d7\u0007"+ + "\u00d7\u0002\u00d8\u0007\u00d8\u0002\u00d9\u0007\u00d9\u0002\u00da\u0007"+ + "\u00da\u0002\u00db\u0007\u00db\u0002\u00dc\u0007\u00dc\u0002\u00dd\u0007"+ + "\u00dd\u0002\u00de\u0007\u00de\u0002\u00df\u0007\u00df\u0002\u00e0\u0007"+ + "\u00e0\u0002\u00e1\u0007\u00e1\u0002\u00e2\u0007\u00e2\u0002\u00e3\u0007"+ + "\u00e3\u0002\u00e4\u0007\u00e4\u0002\u00e5\u0007\u00e5\u0002\u00e6\u0007"+ + "\u00e6\u0002\u00e7\u0007\u00e7\u0002\u00e8\u0007\u00e8\u0002\u00e9\u0007"+ + "\u00e9\u0002\u00ea\u0007\u00ea\u0002\u00eb\u0007\u00eb\u0002\u00ec\u0007"+ + "\u00ec\u0002\u00ed\u0007\u00ed\u0002\u00ee\u0007\u00ee\u0002\u00ef\u0007"+ + "\u00ef\u0002\u00f0\u0007\u00f0\u0002\u00f1\u0007\u00f1\u0002\u00f2\u0007"+ + "\u00f2\u0002\u00f3\u0007\u00f3\u0002\u00f4\u0007\u00f4\u0002\u00f5\u0007"+ + "\u00f5\u0002\u00f6\u0007\u00f6\u0002\u00f7\u0007\u00f7\u0002\u00f8\u0007"+ + "\u00f8\u0002\u00f9\u0007\u00f9\u0002\u00fa\u0007\u00fa\u0002\u00fb\u0007"+ + "\u00fb\u0002\u00fc\u0007\u00fc\u0002\u00fd\u0007\u00fd\u0002\u00fe\u0007"+ + "\u00fe\u0002\u00ff\u0007\u00ff\u0002\u0100\u0007\u0100\u0002\u0101\u0007"+ + "\u0101\u0002\u0102\u0007\u0102\u0002\u0103\u0007\u0103\u0002\u0104\u0007"+ + "\u0104\u0002\u0105\u0007\u0105\u0002\u0106\u0007\u0106\u0002\u0107\u0007"+ + "\u0107\u0002\u0108\u0007\u0108\u0002\u0109\u0007\u0109\u0002\u010a\u0007"+ + "\u010a\u0002\u010b\u0007\u010b\u0002\u010c\u0007\u010c\u0002\u010d\u0007"+ + "\u010d\u0002\u010e\u0007\u010e\u0002\u010f\u0007\u010f\u0002\u0110\u0007"+ + "\u0110\u0002\u0111\u0007\u0111\u0002\u0112\u0007\u0112\u0002\u0113\u0007"+ + "\u0113\u0002\u0114\u0007\u0114\u0002\u0115\u0007\u0115\u0002\u0116\u0007"+ + "\u0116\u0002\u0117\u0007\u0117\u0002\u0118\u0007\u0118\u0002\u0119\u0007"+ + "\u0119\u0002\u011a\u0007\u011a\u0002\u011b\u0007\u011b\u0002\u011c\u0007"+ + "\u011c\u0002\u011d\u0007\u011d\u0002\u011e\u0007\u011e\u0002\u011f\u0007"+ + "\u011f\u0002\u0120\u0007\u0120\u0002\u0121\u0007\u0121\u0002\u0122\u0007"+ + "\u0122\u0002\u0123\u0007\u0123\u0002\u0124\u0007\u0124\u0002\u0125\u0007"+ + "\u0125\u0002\u0126\u0007\u0126\u0002\u0127\u0007\u0127\u0002\u0128\u0007"+ + "\u0128\u0002\u0129\u0007\u0129\u0002\u012a\u0007\u012a\u0002\u012b\u0007"+ + "\u012b\u0002\u012c\u0007\u012c\u0002\u012d\u0007\u012d\u0002\u012e\u0007"+ + "\u012e\u0002\u012f\u0007\u012f\u0002\u0130\u0007\u0130\u0002\u0131\u0007"+ + "\u0131\u0002\u0132\u0007\u0132\u0002\u0133\u0007\u0133\u0002\u0134\u0007"+ + "\u0134\u0002\u0135\u0007\u0135\u0002\u0136\u0007\u0136\u0002\u0137\u0007"+ + "\u0137\u0002\u0138\u0007\u0138\u0002\u0139\u0007\u0139\u0002\u013a\u0007"+ + "\u013a\u0001\u0000\u0001\u0000\u0001\u0000\u0001\u0000\u0005\u0000\u028f"+ + "\b\u0000\n\u0000\f\u0000\u0292\t\u0000\u0001\u0000\u0003\u0000\u0295\b"+ + "\u0000\u0001\u0000\u0003\u0000\u0298\b\u0000\u0001\u0000\u0001\u0000\u0001"+ + "\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0005\u0001\u02a1"+ + "\b\u0001\n\u0001\f\u0001\u02a4\t\u0001\u0001\u0001\u0001\u0001\u0001\u0001"+ + "\u0001\u0001\u0001\u0001\u0001\u0002\u0004\u0002\u02ac\b\u0002\u000b\u0002"+ + "\f\u0002\u02ad\u0001\u0002\u0001\u0002\u0001\u0003\u0001\u0003\u0001\u0003"+ "\u0001\u0003\u0001\u0003\u0001\u0003\u0001\u0003\u0001\u0003\u0001\u0003"+ "\u0001\u0003\u0001\u0003\u0001\u0003\u0001\u0003\u0001\u0003\u0001\u0003"+ "\u0001\u0004\u0001\u0004\u0001\u0004\u0001\u0004\u0001\u0004\u0001\u0004"+ @@ -459,96 +553,96 @@ private boolean DEV_INSIST_sempred(RuleContext _localctx, int predIndex) { "\u001e\u0001\u001e\u0001\u001e\u0001\u001e\u0001\u001e\u0001\u001f\u0001"+ "\u001f\u0001\u001f\u0001\u001f\u0001\u001f\u0001\u001f\u0001\u001f\u0001"+ "\u001f\u0001\u001f\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#\u0004#\u03a3\b#\u000b#\f#\u03a4\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"+ - "0\u00010\u00010\u00010\u00011\u00011\u00011\u00011\u00011\u00012\u0001"+ - "2\u00012\u00012\u00012\u00012\u00013\u00013\u00013\u00013\u00013\u0001"+ - "4\u00014\u00014\u00014\u00014\u00015\u00015\u00016\u00046\u03f8\b6\u000b"+ - "6\f6\u03f9\u00016\u00016\u00036\u03fe\b6\u00016\u00046\u0401\b6\u000b"+ - "6\f6\u0402\u00017\u00017\u00017\u00017\u00018\u00018\u00018\u00018\u0001"+ - "9\u00019\u00019\u00019\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@\u0001A\u0001A\u0001A\u0001"+ - "A\u0001B\u0001B\u0001B\u0001B\u0001C\u0001C\u0001C\u0001C\u0001D\u0001"+ - "D\u0001D\u0001D\u0001E\u0001E\u0001E\u0001E\u0001F\u0001F\u0001F\u0001"+ - "F\u0001G\u0001G\u0001G\u0001G\u0001H\u0001H\u0001H\u0001H\u0001I\u0001"+ - "I\u0001I\u0001I\u0001J\u0001J\u0001J\u0001J\u0001K\u0001K\u0001K\u0001"+ - "K\u0001L\u0001L\u0001L\u0001L\u0001M\u0001M\u0001M\u0001M\u0001M\u0001"+ - "N\u0001N\u0001N\u0001N\u0001N\u0001O\u0001O\u0001O\u0001O\u0001P\u0001"+ - "P\u0001P\u0001P\u0001Q\u0001Q\u0001Q\u0001Q\u0001R\u0001R\u0001R\u0001"+ - "R\u0001S\u0001S\u0001T\u0001T\u0001U\u0001U\u0001U\u0001V\u0001V\u0001"+ - "W\u0001W\u0003W\u0487\bW\u0001W\u0004W\u048a\bW\u000bW\fW\u048b\u0001"+ - "X\u0001X\u0001Y\u0001Y\u0001Z\u0001Z\u0001Z\u0003Z\u0495\bZ\u0001[\u0001"+ - "[\u0001\\\u0001\\\u0001\\\u0003\\\u049c\b\\\u0001]\u0001]\u0001]\u0005"+ - "]\u04a1\b]\n]\f]\u04a4\t]\u0001]\u0001]\u0001]\u0001]\u0001]\u0001]\u0005"+ - "]\u04ac\b]\n]\f]\u04af\t]\u0001]\u0001]\u0001]\u0001]\u0001]\u0003]\u04b6"+ - "\b]\u0001]\u0003]\u04b9\b]\u0003]\u04bb\b]\u0001^\u0004^\u04be\b^\u000b"+ - "^\f^\u04bf\u0001_\u0004_\u04c3\b_\u000b_\f_\u04c4\u0001_\u0001_\u0005"+ - "_\u04c9\b_\n_\f_\u04cc\t_\u0001_\u0001_\u0004_\u04d0\b_\u000b_\f_\u04d1"+ - "\u0001_\u0004_\u04d5\b_\u000b_\f_\u04d6\u0001_\u0001_\u0005_\u04db\b_"+ - "\n_\f_\u04de\t_\u0003_\u04e0\b_\u0001_\u0001_\u0001_\u0001_\u0004_\u04e6"+ - "\b_\u000b_\f_\u04e7\u0001_\u0001_\u0003_\u04ec\b_\u0001`\u0001`\u0001"+ - "`\u0001`\u0001a\u0001a\u0001a\u0001a\u0001b\u0001b\u0001c\u0001c\u0001"+ - "c\u0001d\u0001d\u0001d\u0001e\u0001e\u0001f\u0001f\u0001g\u0001g\u0001"+ - "h\u0001h\u0001h\u0001h\u0001h\u0001i\u0001i\u0001j\u0001j\u0001j\u0001"+ - "j\u0001j\u0001j\u0001k\u0001k\u0001k\u0001k\u0001k\u0001k\u0001l\u0001"+ - "l\u0001l\u0001m\u0001m\u0001m\u0001n\u0001n\u0001n\u0001n\u0001n\u0001"+ - "o\u0001o\u0001o\u0001o\u0001o\u0001p\u0001p\u0001p\u0001p\u0001q\u0001"+ - "q\u0001q\u0001q\u0001q\u0001r\u0001r\u0001r\u0001r\u0001r\u0001r\u0001"+ - "s\u0001s\u0001s\u0001t\u0001t\u0001t\u0001u\u0001u\u0001v\u0001v\u0001"+ - "v\u0001v\u0001v\u0001v\u0001w\u0001w\u0001w\u0001w\u0001w\u0001x\u0001"+ - "x\u0001x\u0001x\u0001x\u0001y\u0001y\u0001y\u0001z\u0001z\u0001z\u0001"+ - "{\u0001{\u0001{\u0001|\u0001|\u0001}\u0001}\u0001}\u0001~\u0001~\u0001"+ - "\u007f\u0001\u007f\u0001\u007f\u0001\u0080\u0001\u0080\u0001\u0081\u0001"+ - "\u0081\u0001\u0082\u0001\u0082\u0001\u0083\u0001\u0083\u0001\u0084\u0001"+ - "\u0084\u0001\u0085\u0001\u0085\u0001\u0086\u0001\u0086\u0001\u0087\u0001"+ - "\u0087\u0001\u0087\u0001\u0088\u0001\u0088\u0001\u0088\u0001\u0088\u0001"+ - "\u0089\u0001\u0089\u0001\u0089\u0003\u0089\u0579\b\u0089\u0001\u0089\u0005"+ - "\u0089\u057c\b\u0089\n\u0089\f\u0089\u057f\t\u0089\u0001\u0089\u0001\u0089"+ - "\u0004\u0089\u0583\b\u0089\u000b\u0089\f\u0089\u0584\u0003\u0089\u0587"+ - "\b\u0089\u0001\u008a\u0001\u008a\u0001\u008a\u0003\u008a\u058c\b\u008a"+ - "\u0001\u008a\u0005\u008a\u058f\b\u008a\n\u008a\f\u008a\u0592\t\u008a\u0001"+ - "\u008a\u0001\u008a\u0004\u008a\u0596\b\u008a\u000b\u008a\f\u008a\u0597"+ - "\u0003\u008a\u059a\b\u008a\u0001\u008b\u0001\u008b\u0001\u008b\u0001\u008b"+ - "\u0001\u008b\u0001\u008c\u0001\u008c\u0001\u008c\u0001\u008c\u0001\u008c"+ - "\u0001\u008d\u0001\u008d\u0001\u008d\u0001\u008d\u0001\u008d\u0001\u008e"+ - "\u0001\u008e\u0001\u008e\u0001\u008e\u0001\u008e\u0001\u008f\u0001\u008f"+ - "\u0005\u008f\u05b2\b\u008f\n\u008f\f\u008f\u05b5\t\u008f\u0001\u008f\u0001"+ - "\u008f\u0003\u008f\u05b9\b\u008f\u0001\u008f\u0004\u008f\u05bc\b\u008f"+ - "\u000b\u008f\f\u008f\u05bd\u0003\u008f\u05c0\b\u008f\u0001\u0090\u0001"+ - "\u0090\u0004\u0090\u05c4\b\u0090\u000b\u0090\f\u0090\u05c5\u0001\u0090"+ - "\u0001\u0090\u0001\u0091\u0001\u0091\u0001\u0092\u0001\u0092\u0001\u0092"+ + " \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"+ + "$\u0004$\u03d7\b$\u000b$\f$\u03d8\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\u00011\u00011\u0001"+ + "1\u00011\u00012\u00012\u00012\u00012\u00012\u00013\u00013\u00013\u0001"+ + "3\u00013\u00013\u00014\u00014\u00014\u00014\u00014\u00015\u00015\u0001"+ + "5\u00015\u00015\u00016\u00016\u00017\u00047\u042c\b7\u000b7\f7\u042d\u0001"+ + "7\u00017\u00037\u0432\b7\u00017\u00047\u0435\b7\u000b7\f7\u0436\u0001"+ + "8\u00018\u00018\u00018\u00019\u00019\u00019\u00019\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"+ + "@\u0001A\u0001A\u0001A\u0001A\u0001B\u0001B\u0001B\u0001B\u0001C\u0001"+ + "C\u0001C\u0001C\u0001D\u0001D\u0001D\u0001D\u0001E\u0001E\u0001E\u0001"+ + "E\u0001F\u0001F\u0001F\u0001F\u0001G\u0001G\u0001G\u0001G\u0001H\u0001"+ + "H\u0001H\u0001H\u0001I\u0001I\u0001I\u0001I\u0001J\u0001J\u0001J\u0001"+ + "J\u0001K\u0001K\u0001K\u0001K\u0001L\u0001L\u0001L\u0001L\u0001M\u0001"+ + "M\u0001M\u0001M\u0001N\u0001N\u0001N\u0001N\u0001N\u0001O\u0001O\u0001"+ + "O\u0001O\u0001O\u0001P\u0001P\u0001P\u0001P\u0001Q\u0001Q\u0001Q\u0001"+ + "Q\u0001R\u0001R\u0001R\u0001R\u0001S\u0001S\u0001S\u0001S\u0001T\u0001"+ + "T\u0001U\u0001U\u0001V\u0001V\u0001V\u0001W\u0001W\u0001X\u0001X\u0003"+ + "X\u04bb\bX\u0001X\u0004X\u04be\bX\u000bX\fX\u04bf\u0001Y\u0001Y\u0001"+ + "Z\u0001Z\u0001[\u0001[\u0001[\u0003[\u04c9\b[\u0001\\\u0001\\\u0001]\u0001"+ + "]\u0001]\u0003]\u04d0\b]\u0001^\u0001^\u0001^\u0005^\u04d5\b^\n^\f^\u04d8"+ + "\t^\u0001^\u0001^\u0001^\u0001^\u0001^\u0001^\u0005^\u04e0\b^\n^\f^\u04e3"+ + "\t^\u0001^\u0001^\u0001^\u0001^\u0001^\u0003^\u04ea\b^\u0001^\u0003^\u04ed"+ + "\b^\u0003^\u04ef\b^\u0001_\u0004_\u04f2\b_\u000b_\f_\u04f3\u0001`\u0004"+ + "`\u04f7\b`\u000b`\f`\u04f8\u0001`\u0001`\u0005`\u04fd\b`\n`\f`\u0500\t"+ + "`\u0001`\u0001`\u0004`\u0504\b`\u000b`\f`\u0505\u0001`\u0004`\u0509\b"+ + "`\u000b`\f`\u050a\u0001`\u0001`\u0005`\u050f\b`\n`\f`\u0512\t`\u0003`"+ + "\u0514\b`\u0001`\u0001`\u0001`\u0001`\u0004`\u051a\b`\u000b`\f`\u051b"+ + "\u0001`\u0001`\u0003`\u0520\b`\u0001a\u0001a\u0001a\u0001a\u0001b\u0001"+ + "b\u0001b\u0001b\u0001c\u0001c\u0001d\u0001d\u0001d\u0001e\u0001e\u0001"+ + "e\u0001f\u0001f\u0001g\u0001g\u0001h\u0001h\u0001i\u0001i\u0001i\u0001"+ + "i\u0001i\u0001j\u0001j\u0001k\u0001k\u0001k\u0001k\u0001k\u0001k\u0001"+ + "l\u0001l\u0001l\u0001l\u0001l\u0001l\u0001m\u0001m\u0001m\u0001n\u0001"+ + "n\u0001n\u0001o\u0001o\u0001o\u0001o\u0001o\u0001p\u0001p\u0001p\u0001"+ + "p\u0001p\u0001q\u0001q\u0001q\u0001q\u0001r\u0001r\u0001r\u0001r\u0001"+ + "r\u0001s\u0001s\u0001s\u0001s\u0001s\u0001s\u0001t\u0001t\u0001t\u0001"+ + "u\u0001u\u0001u\u0001v\u0001v\u0001w\u0001w\u0001w\u0001w\u0001w\u0001"+ + "w\u0001x\u0001x\u0001x\u0001x\u0001x\u0001y\u0001y\u0001y\u0001y\u0001"+ + "y\u0001z\u0001z\u0001z\u0001{\u0001{\u0001{\u0001|\u0001|\u0001|\u0001"+ + "}\u0001}\u0001~\u0001~\u0001~\u0001\u007f\u0001\u007f\u0001\u0080\u0001"+ + "\u0080\u0001\u0080\u0001\u0081\u0001\u0081\u0001\u0082\u0001\u0082\u0001"+ + "\u0083\u0001\u0083\u0001\u0084\u0001\u0084\u0001\u0085\u0001\u0085\u0001"+ + "\u0086\u0001\u0086\u0001\u0087\u0001\u0087\u0001\u0088\u0001\u0088\u0001"+ + "\u0088\u0001\u0089\u0001\u0089\u0001\u0089\u0001\u0089\u0001\u008a\u0001"+ + "\u008a\u0001\u008a\u0003\u008a\u05ad\b\u008a\u0001\u008a\u0005\u008a\u05b0"+ + "\b\u008a\n\u008a\f\u008a\u05b3\t\u008a\u0001\u008a\u0001\u008a\u0004\u008a"+ + "\u05b7\b\u008a\u000b\u008a\f\u008a\u05b8\u0003\u008a\u05bb\b\u008a\u0001"+ + "\u008b\u0001\u008b\u0001\u008b\u0003\u008b\u05c0\b\u008b\u0001\u008b\u0005"+ + "\u008b\u05c3\b\u008b\n\u008b\f\u008b\u05c6\t\u008b\u0001\u008b\u0001\u008b"+ + "\u0004\u008b\u05ca\b\u008b\u000b\u008b\f\u008b\u05cb\u0003\u008b\u05ce"+ + "\b\u008b\u0001\u008c\u0001\u008c\u0001\u008c\u0001\u008c\u0001\u008c\u0001"+ + "\u008d\u0001\u008d\u0001\u008d\u0001\u008d\u0001\u008d\u0001\u008e\u0001"+ + "\u008e\u0001\u008e\u0001\u008e\u0001\u008e\u0001\u008f\u0001\u008f\u0001"+ + "\u008f\u0001\u008f\u0001\u008f\u0001\u0090\u0001\u0090\u0005\u0090\u05e6"+ + "\b\u0090\n\u0090\f\u0090\u05e9\t\u0090\u0001\u0090\u0001\u0090\u0003\u0090"+ + "\u05ed\b\u0090\u0001\u0090\u0004\u0090\u05f0\b\u0090\u000b\u0090\f\u0090"+ + "\u05f1\u0003\u0090\u05f4\b\u0090\u0001\u0091\u0001\u0091\u0004\u0091\u05f8"+ + "\b\u0091\u000b\u0091\f\u0091\u05f9\u0001\u0091\u0001\u0091\u0001\u0092"+ "\u0001\u0092\u0001\u0093\u0001\u0093\u0001\u0093\u0001\u0093\u0001\u0094"+ "\u0001\u0094\u0001\u0094\u0001\u0094\u0001\u0095\u0001\u0095\u0001\u0095"+ - "\u0001\u0095\u0001\u0095\u0001\u0096\u0001\u0096\u0001\u0096\u0001\u0096"+ + "\u0001\u0095\u0001\u0096\u0001\u0096\u0001\u0096\u0001\u0096\u0001\u0096"+ "\u0001\u0097\u0001\u0097\u0001\u0097\u0001\u0097\u0001\u0098\u0001\u0098"+ "\u0001\u0098\u0001\u0098\u0001\u0099\u0001\u0099\u0001\u0099\u0001\u0099"+ - "\u0001\u009a\u0001\u009a\u0001\u009a\u0001\u009a\u0001\u009a\u0001\u009a"+ - "\u0001\u009a\u0001\u009a\u0001\u009a\u0001\u009b\u0001\u009b\u0001\u009b"+ - "\u0001\u009b\u0001\u009b\u0001\u009b\u0001\u009c\u0001\u009c\u0001\u009c"+ - "\u0001\u009c\u0001\u009c\u0001\u009d\u0001\u009d\u0001\u009d\u0003\u009d"+ - "\u0604\b\u009d\u0001\u009e\u0004\u009e\u0607\b\u009e\u000b\u009e\f\u009e"+ - "\u0608\u0001\u009f\u0001\u009f\u0001\u009f\u0001\u009f\u0001\u00a0\u0001"+ + "\u0001\u009a\u0001\u009a\u0001\u009a\u0001\u009a\u0001\u009b\u0001\u009b"+ + "\u0001\u009b\u0001\u009b\u0001\u009b\u0001\u009b\u0001\u009b\u0001\u009b"+ + "\u0001\u009b\u0001\u009c\u0001\u009c\u0001\u009c\u0001\u009c\u0001\u009c"+ + "\u0001\u009c\u0001\u009d\u0001\u009d\u0001\u009d\u0001\u009d\u0001\u009d"+ + "\u0001\u009e\u0001\u009e\u0001\u009e\u0003\u009e\u0638\b\u009e\u0001\u009f"+ + "\u0004\u009f\u063b\b\u009f\u000b\u009f\f\u009f\u063c\u0001\u00a0\u0001"+ "\u00a0\u0001\u00a0\u0001\u00a0\u0001\u00a1\u0001\u00a1\u0001\u00a1\u0001"+ "\u00a1\u0001\u00a2\u0001\u00a2\u0001\u00a2\u0001\u00a2\u0001\u00a3\u0001"+ "\u00a3\u0001\u00a3\u0001\u00a3\u0001\u00a4\u0001\u00a4\u0001\u00a4\u0001"+ - "\u00a4\u0001\u00a4\u0001\u00a5\u0001\u00a5\u0001\u00a5\u0001\u00a5\u0001"+ - "\u00a5\u0001\u00a5\u0001\u00a6\u0001\u00a6\u0001\u00a6\u0001\u00a6\u0001"+ - "\u00a6\u0001\u00a7\u0001\u00a7\u0001\u00a7\u0001\u00a7\u0001\u00a8\u0001"+ + "\u00a4\u0001\u00a5\u0001\u00a5\u0001\u00a5\u0001\u00a5\u0001\u00a5\u0001"+ + "\u00a6\u0001\u00a6\u0001\u00a6\u0001\u00a6\u0001\u00a6\u0001\u00a6\u0001"+ + "\u00a7\u0001\u00a7\u0001\u00a7\u0001\u00a7\u0001\u00a7\u0001\u00a8\u0001"+ "\u00a8\u0001\u00a8\u0001\u00a8\u0001\u00a9\u0001\u00a9\u0001\u00a9\u0001"+ - "\u00a9\u0001\u00aa\u0001\u00aa\u0001\u00aa\u0001\u00aa\u0001\u00aa\u0001"+ - "\u00ab\u0001\u00ab\u0001\u00ab\u0001\u00ab\u0001\u00ab\u0001\u00ab\u0001"+ - "\u00ac\u0001\u00ac\u0001\u00ac\u0001\u00ac\u0001\u00ac\u0001\u00ac\u0001"+ - "\u00ad\u0001\u00ad\u0001\u00ad\u0001\u00ad\u0001\u00ad\u0001\u00ad\u0001"+ + "\u00a9\u0001\u00aa\u0001\u00aa\u0001\u00aa\u0001\u00aa\u0001\u00ab\u0001"+ + "\u00ab\u0001\u00ab\u0001\u00ab\u0001\u00ab\u0001\u00ac\u0001\u00ac\u0001"+ + "\u00ac\u0001\u00ac\u0001\u00ac\u0001\u00ac\u0001\u00ad\u0001\u00ad\u0001"+ + "\u00ad\u0001\u00ad\u0001\u00ad\u0001\u00ad\u0001\u00ae\u0001\u00ae\u0001"+ "\u00ae\u0001\u00ae\u0001\u00ae\u0001\u00ae\u0001\u00af\u0001\u00af\u0001"+ - "\u00af\u0001\u00af\u0001\u00af\u0001\u00af\u0001\u00b0\u0001\u00b0\u0001"+ + "\u00af\u0001\u00af\u0001\u00b0\u0001\u00b0\u0001\u00b0\u0001\u00b0\u0001"+ "\u00b0\u0001\u00b0\u0001\u00b1\u0001\u00b1\u0001\u00b1\u0001\u00b1\u0001"+ "\u00b2\u0001\u00b2\u0001\u00b2\u0001\u00b2\u0001\u00b3\u0001\u00b3\u0001"+ "\u00b3\u0001\u00b3\u0001\u00b4\u0001\u00b4\u0001\u00b4\u0001\u00b4\u0001"+ @@ -557,34 +651,34 @@ private boolean DEV_INSIST_sempred(RuleContext _localctx, int predIndex) { "\u00b8\u0001\u00b8\u0001\u00b8\u0001\u00b8\u0001\u00b9\u0001\u00b9\u0001"+ "\u00b9\u0001\u00b9\u0001\u00ba\u0001\u00ba\u0001\u00ba\u0001\u00ba\u0001"+ "\u00bb\u0001\u00bb\u0001\u00bb\u0001\u00bb\u0001\u00bc\u0001\u00bc\u0001"+ - "\u00bc\u0001\u00bc\u0001\u00bc\u0001\u00bc\u0001\u00bc\u0001\u00bc\u0001"+ - "\u00bc\u0001\u00bd\u0001\u00bd\u0001\u00bd\u0001\u00bd\u0001\u00be\u0001"+ + "\u00bc\u0001\u00bc\u0001\u00bd\u0001\u00bd\u0001\u00bd\u0001\u00bd\u0001"+ + "\u00bd\u0001\u00bd\u0001\u00bd\u0001\u00bd\u0001\u00bd\u0001\u00be\u0001"+ "\u00be\u0001\u00be\u0001\u00be\u0001\u00bf\u0001\u00bf\u0001\u00bf\u0001"+ - "\u00bf\u0001\u00c0\u0001\u00c0\u0001\u00c0\u0001\u00c0\u0001\u00c0\u0001"+ - "\u00c1\u0001\u00c1\u0001\u00c1\u0001\u00c1\u0001\u00c1\u0001\u00c2\u0001"+ + "\u00bf\u0001\u00c0\u0001\u00c0\u0001\u00c0\u0001\u00c0\u0001\u00c1\u0001"+ + "\u00c1\u0001\u00c1\u0001\u00c1\u0001\u00c1\u0001\u00c2\u0001\u00c2\u0001"+ "\u00c2\u0001\u00c2\u0001\u00c2\u0001\u00c3\u0001\u00c3\u0001\u00c3\u0001"+ - "\u00c3\u0001\u00c3\u0001\u00c3\u0001\u00c4\u0001\u00c4\u0001\u00c4\u0001"+ - "\u00c4\u0001\u00c4\u0001\u00c4\u0001\u00c4\u0001\u00c4\u0001\u00c4\u0001"+ + "\u00c3\u0001\u00c4\u0001\u00c4\u0001\u00c4\u0001\u00c4\u0001\u00c4\u0001"+ + "\u00c4\u0001\u00c5\u0001\u00c5\u0001\u00c5\u0001\u00c5\u0001\u00c5\u0001"+ "\u00c5\u0001\u00c5\u0001\u00c5\u0001\u00c5\u0001\u00c6\u0001\u00c6\u0001"+ "\u00c6\u0001\u00c6\u0001\u00c7\u0001\u00c7\u0001\u00c7\u0001\u00c7\u0001"+ "\u00c8\u0001\u00c8\u0001\u00c8\u0001\u00c8\u0001\u00c9\u0001\u00c9\u0001"+ "\u00c9\u0001\u00c9\u0001\u00ca\u0001\u00ca\u0001\u00ca\u0001\u00ca\u0001"+ - "\u00cb\u0001\u00cb\u0001\u00cb\u0001\u00cb\u0001\u00cb\u0001\u00cc\u0001"+ - "\u00cc\u0001\u00cc\u0001\u00cc\u0001\u00cc\u0001\u00cc\u0001\u00cd\u0001"+ + "\u00cb\u0001\u00cb\u0001\u00cb\u0001\u00cb\u0001\u00cc\u0001\u00cc\u0001"+ + "\u00cc\u0001\u00cc\u0001\u00cc\u0001\u00cd\u0001\u00cd\u0001\u00cd\u0001"+ "\u00cd\u0001\u00cd\u0001\u00cd\u0001\u00ce\u0001\u00ce\u0001\u00ce\u0001"+ "\u00ce\u0001\u00cf\u0001\u00cf\u0001\u00cf\u0001\u00cf\u0001\u00d0\u0001"+ - "\u00d0\u0001\u00d0\u0001\u00d0\u0001\u00d0\u0001\u00d1\u0001\u00d1\u0001"+ + "\u00d0\u0001\u00d0\u0001\u00d0\u0001\u00d1\u0001\u00d1\u0001\u00d1\u0001"+ "\u00d1\u0001\u00d1\u0001\u00d2\u0001\u00d2\u0001\u00d2\u0001\u00d2\u0001"+ "\u00d3\u0001\u00d3\u0001\u00d3\u0001\u00d3\u0001\u00d4\u0001\u00d4\u0001"+ "\u00d4\u0001\u00d4\u0001\u00d5\u0001\u00d5\u0001\u00d5\u0001\u00d5\u0001"+ - "\u00d6\u0001\u00d6\u0001\u00d6\u0001\u00d6\u0001\u00d6\u0001\u00d6\u0001"+ - "\u00d7\u0001\u00d7\u0001\u00d7\u0001\u00d7\u0001\u00d7\u0001\u00d7\u0001"+ - "\u00d7\u0001\u00d8\u0001\u00d8\u0001\u00d8\u0001\u00d8\u0001\u00d9\u0001"+ + "\u00d6\u0001\u00d6\u0001\u00d6\u0001\u00d6\u0001\u00d7\u0001\u00d7\u0001"+ + "\u00d7\u0001\u00d7\u0001\u00d7\u0001\u00d7\u0001\u00d8\u0001\u00d8\u0001"+ + "\u00d8\u0001\u00d8\u0001\u00d8\u0001\u00d8\u0001\u00d8\u0001\u00d9\u0001"+ "\u00d9\u0001\u00d9\u0001\u00d9\u0001\u00da\u0001\u00da\u0001\u00da\u0001"+ "\u00da\u0001\u00db\u0001\u00db\u0001\u00db\u0001\u00db\u0001\u00dc\u0001"+ "\u00dc\u0001\u00dc\u0001\u00dc\u0001\u00dd\u0001\u00dd\u0001\u00dd\u0001"+ - "\u00dd\u0001\u00de\u0001\u00de\u0001\u00de\u0001\u00de\u0001\u00de\u0001"+ - "\u00df\u0001\u00df\u0001\u00df\u0001\u00df\u0001\u00df\u0001\u00df\u0001"+ + "\u00dd\u0001\u00de\u0001\u00de\u0001\u00de\u0001\u00de\u0001\u00df\u0001"+ + "\u00df\u0001\u00df\u0001\u00df\u0001\u00df\u0001\u00e0\u0001\u00e0\u0001"+ "\u00e0\u0001\u00e0\u0001\u00e0\u0001\u00e0\u0001\u00e1\u0001\u00e1\u0001"+ "\u00e1\u0001\u00e1\u0001\u00e2\u0001\u00e2\u0001\u00e2\u0001\u00e2\u0001"+ "\u00e3\u0001\u00e3\u0001\u00e3\u0001\u00e3\u0001\u00e4\u0001\u00e4\u0001"+ @@ -593,1166 +687,1296 @@ private boolean DEV_INSIST_sempred(RuleContext _localctx, int predIndex) { "\u00e7\u0001\u00e7\u0001\u00e8\u0001\u00e8\u0001\u00e8\u0001\u00e8\u0001"+ "\u00e9\u0001\u00e9\u0001\u00e9\u0001\u00e9\u0001\u00ea\u0001\u00ea\u0001"+ "\u00ea\u0001\u00ea\u0001\u00eb\u0001\u00eb\u0001\u00eb\u0001\u00eb\u0001"+ - "\u00ec\u0001\u00ec\u0001\u00ec\u0001\u00ec\u0001\u00ec\u0001\u00ed\u0001"+ - "\u00ed\u0001\u00ed\u0001\u00ed\u0001\u00ed\u0001\u00ed\u0001\u00ee\u0001"+ + "\u00ec\u0001\u00ec\u0001\u00ec\u0001\u00ec\u0001\u00ed\u0001\u00ed\u0001"+ + "\u00ed\u0001\u00ed\u0001\u00ed\u0001\u00ee\u0001\u00ee\u0001\u00ee\u0001"+ "\u00ee\u0001\u00ee\u0001\u00ee\u0001\u00ef\u0001\u00ef\u0001\u00ef\u0001"+ "\u00ef\u0001\u00f0\u0001\u00f0\u0001\u00f0\u0001\u00f0\u0001\u00f1\u0001"+ "\u00f1\u0001\u00f1\u0001\u00f1\u0001\u00f2\u0001\u00f2\u0001\u00f2\u0001"+ "\u00f2\u0001\u00f3\u0001\u00f3\u0001\u00f3\u0001\u00f3\u0001\u00f4\u0001"+ "\u00f4\u0001\u00f4\u0001\u00f4\u0001\u00f5\u0001\u00f5\u0001\u00f5\u0001"+ - "\u00f5\u0001\u00f6\u0001\u00f6\u0001\u00f6\u0001\u00f6\u0003\u00f6\u0795"+ - "\b\u00f6\u0001\u00f7\u0001\u00f7\u0003\u00f7\u0799\b\u00f7\u0001\u00f7"+ - "\u0005\u00f7\u079c\b\u00f7\n\u00f7\f\u00f7\u079f\t\u00f7\u0001\u00f7\u0001"+ - "\u00f7\u0003\u00f7\u07a3\b\u00f7\u0001\u00f7\u0004\u00f7\u07a6\b\u00f7"+ - "\u000b\u00f7\f\u00f7\u07a7\u0003\u00f7\u07aa\b\u00f7\u0001\u00f8\u0001"+ - "\u00f8\u0004\u00f8\u07ae\b\u00f8\u000b\u00f8\f\u00f8\u07af\u0001\u00f9"+ - "\u0001\u00f9\u0001\u00f9\u0001\u00f9\u0001\u00fa\u0001\u00fa\u0001\u00fa"+ - "\u0001\u00fa\u0001\u00fb\u0001\u00fb\u0001\u00fb\u0001\u00fb\u0001\u00fc"+ - "\u0001\u00fc\u0001\u00fc\u0001\u00fc\u0001\u00fc\u0001\u00fd\u0001\u00fd"+ - "\u0001\u00fd\u0001\u00fd\u0001\u00fd\u0001\u00fd\u0001\u00fe\u0001\u00fe"+ - "\u0001\u00fe\u0001\u00fe\u0001\u00ff\u0001\u00ff\u0001\u00ff\u0001\u00ff"+ - "\u0001\u0100\u0001\u0100\u0001\u0100\u0001\u0100\u0001\u0101\u0001\u0101"+ - "\u0001\u0101\u0001\u0101\u0001\u0102\u0001\u0102\u0001\u0102\u0001\u0102"+ - "\u0001\u0103\u0001\u0103\u0001\u0103\u0001\u0103\u0001\u0104\u0001\u0104"+ - "\u0001\u0104\u0001\u0104\u0001\u0105\u0001\u0105\u0001\u0105\u0001\u0105"+ - "\u0001\u0106\u0001\u0106\u0001\u0106\u0001\u0106\u0001\u0107\u0001\u0107"+ - "\u0001\u0107\u0001\u0108\u0001\u0108\u0001\u0108\u0001\u0108\u0001\u0109"+ - "\u0001\u0109\u0001\u0109\u0001\u0109\u0001\u010a\u0001\u010a\u0001\u010a"+ - "\u0001\u010a\u0001\u010b\u0001\u010b\u0001\u010b\u0001\u010b\u0001\u010c"+ - "\u0001\u010c\u0001\u010c\u0001\u010c\u0001\u010d\u0001\u010d\u0001\u010d"+ - "\u0001\u010d\u0001\u010e\u0001\u010e\u0001\u010e\u0001\u010e\u0001\u010f"+ - "\u0001\u010f\u0001\u010f\u0001\u010f\u0001\u010f\u0001\u0110\u0001\u0110"+ - "\u0001\u0110\u0001\u0110\u0001\u0111\u0001\u0111\u0001\u0111\u0001\u0111"+ - "\u0001\u0112\u0001\u0112\u0001\u0112\u0001\u0112\u0001\u0113\u0001\u0113"+ - "\u0001\u0113\u0001\u0113\u0001\u0114\u0001\u0114\u0001\u0114\u0001\u0114"+ - "\u0001\u0115\u0001\u0115\u0001\u0115\u0001\u0115\u0001\u0116\u0001\u0116"+ - "\u0001\u0116\u0001\u0116\u0001\u0117\u0001\u0117\u0001\u0117\u0001\u0117"+ - "\u0001\u0118\u0001\u0118\u0001\u0118\u0001\u0118\u0001\u0119\u0001\u0119"+ - "\u0001\u0119\u0001\u0119\u0001\u011a\u0001\u011a\u0001\u011a\u0001\u011a"+ - "\u0001\u011b\u0001\u011b\u0001\u011b\u0001\u011b\u0001\u011c\u0001\u011c"+ - "\u0001\u011c\u0001\u011c\u0001\u011d\u0001\u011d\u0001\u011d\u0001\u011d"+ - "\u0001\u011e\u0001\u011e\u0001\u011e\u0001\u011e\u0001\u011f\u0001\u011f"+ - "\u0001\u011f\u0001\u011f\u0001\u0120\u0001\u0120\u0001\u0120\u0001\u0120"+ - "\u0001\u0121\u0001\u0121\u0001\u0121\u0001\u0121\u0001\u0122\u0001\u0122"+ - "\u0001\u0122\u0001\u0122\u0001\u0122\u0001\u0123\u0001\u0123\u0001\u0123"+ - "\u0001\u0123\u0001\u0123\u0001\u0124\u0001\u0124\u0001\u0124\u0001\u0124"+ - "\u0001\u0125\u0001\u0125\u0001\u0125\u0001\u0125\u0001\u0126\u0001\u0126"+ - "\u0001\u0126\u0001\u0126\u0002\u0278\u04ad\u0000\u0127\u0012\u0001\u0014"+ - "\u0002\u0016\u0003\u0018\u0004\u001a\u0005\u001c\u0006\u001e\u0007 \b"+ - "\"\t$\n&\u000b(\f*\r,\u000e.\u000f0\u00102\u00114\u00126\u00138\u0014"+ - ":\u0015<\u0016>\u0017@\u0018B\u0019D\u001aF\u001bH\u001cJ\u001dL\u001e"+ - "N\u001fP R!T\"V#X$Z\u0000\\\u0000^\u0000`\u0000b\u0000d\u0000f\u0000h"+ - "\u0000j\u0000l\u0000n%p&r\'t\u0000v\u0000x\u0000z\u0000|\u0000~(\u0080"+ - "\u0000\u0082\u0000\u0084)\u0086*\u0088+\u008a\u0000\u008c\u0000\u008e"+ - "\u0000\u0090\u0000\u0092\u0000\u0094\u0000\u0096\u0000\u0098\u0000\u009a"+ - "\u0000\u009c\u0000\u009e\u0000\u00a0\u0000\u00a2\u0000\u00a4\u0000\u00a6"+ - ",\u00a8-\u00aa.\u00ac\u0000\u00ae\u0000\u00b0/\u00b20\u00b41\u00b62\u00b8"+ - "\u0000\u00ba\u0000\u00bc\u0000\u00be\u0000\u00c0\u0000\u00c2\u0000\u00c4"+ - "\u0000\u00c6\u0000\u00c8\u0000\u00ca\u0000\u00cc3\u00ce4\u00d05\u00d2"+ - "6\u00d47\u00d68\u00d89\u00da:\u00dc;\u00de<\u00e0=\u00e2>\u00e4?\u00e6"+ - "@\u00e8A\u00eaB\u00ecC\u00eeD\u00f0E\u00f2F\u00f4G\u00f6H\u00f8I\u00fa"+ - "J\u00fcK\u00feL\u0100M\u0102N\u0104O\u0106P\u0108Q\u010aR\u010cS\u010e"+ - "T\u0110U\u0112V\u0114W\u0116X\u0118Y\u011aZ\u011c[\u011e\\\u0120]\u0122"+ - "\u0000\u0124^\u0126_\u0128`\u012aa\u012cb\u012ec\u0130d\u0132\u0000\u0134"+ - "e\u0136f\u0138g\u013ah\u013c\u0000\u013e\u0000\u0140\u0000\u0142\u0000"+ - "\u0144\u0000\u0146i\u0148\u0000\u014a\u0000\u014c\u0000\u014ej\u0150\u0000"+ - "\u0152\u0000\u0154k\u0156l\u0158m\u015a\u0000\u015c\u0000\u015e\u0000"+ - "\u0160n\u0162o\u0164p\u0166\u0000\u0168\u0000\u016aq\u016cr\u016es\u0170"+ - "\u0000\u0172\u0000\u0174\u0000\u0176\u0000\u0178\u0000\u017a\u0000\u017c"+ - "\u0000\u017e\u0000\u0180\u0000\u0182\u0000\u0184t\u0186u\u0188v\u018a"+ - "w\u018cx\u018ey\u0190z\u0192\u0000\u0194{\u0196\u0000\u0198\u0000\u019a"+ - "|\u019c\u0000\u019e\u0000\u01a0\u0000\u01a2}\u01a4~\u01a6\u007f\u01a8"+ - "\u0000\u01aa\u0000\u01ac\u0000\u01ae\u0000\u01b0\u0000\u01b2\u0000\u01b4"+ - "\u0000\u01b6\u0000\u01b8\u0080\u01ba\u0081\u01bc\u0082\u01be\u0000\u01c0"+ - "\u0000\u01c2\u0000\u01c4\u0000\u01c6\u0000\u01c8\u0083\u01ca\u0084\u01cc"+ - "\u0085\u01ce\u0000\u01d0\u0000\u01d2\u0000\u01d4\u0000\u01d6\u0000\u01d8"+ - "\u0000\u01da\u0000\u01dc\u0000\u01de\u0000\u01e0\u0000\u01e2\u0000\u01e4"+ - "\u0086\u01e6\u0087\u01e8\u0088\u01ea\u0000\u01ec\u0000\u01ee\u0000\u01f0"+ - "\u0000\u01f2\u0000\u01f4\u0000\u01f6\u0000\u01f8\u0000\u01fa\u0000\u01fc"+ - "\u0000\u01fe\u0000\u0200\u0000\u0202\u0089\u0204\u008a\u0206\u008b\u0208"+ - "\u008c\u020a\u0000\u020c\u0000\u020e\u0000\u0210\u0000\u0212\u0000\u0214"+ - "\u0000\u0216\u0000\u0218\u0000\u021a\u0000\u021c\u0000\u021e\u0000\u0220"+ - "\u008d\u0222\u0000\u0224\u008e\u0226\u008f\u0228\u0090\u022a\u0000\u022c"+ - "\u0000\u022e\u0000\u0230\u0000\u0232\u0000\u0234\u0000\u0236\u0000\u0238"+ - "\u0000\u023a\u0000\u023c\u0000\u023e\u0000\u0240\u0000\u0242\u0000\u0244"+ - "\u0000\u0246\u0000\u0248\u0000\u024a\u0000\u024c\u0000\u024e\u0000\u0250"+ - "\u0091\u0252\u0092\u0254\u0093\u0256\u0000\u0258\u0094\u025a\u0095\u025c"+ - "\u0096\u025e\u0097\u0012\u0000\u0001\u0002\u0003\u0004\u0005\u0006\u0007"+ - "\b\t\n\u000b\f\r\u000e\u000f\u0010\u0011$\u0002\u0000\n\n\r\r\u0003\u0000"+ - "\t\n\r\r \u0002\u0000CCcc\u0002\u0000HHhh\u0002\u0000AAaa\u0002\u0000"+ - "NNnn\u0002\u0000GGgg\u0002\u0000EEee\u0002\u0000PPpp\u0002\u0000OOoo\u0002"+ - "\u0000IIii\u0002\u0000TTtt\u0002\u0000RRrr\u0002\u0000XXxx\u0002\u0000"+ - "LLll\u0002\u0000MMmm\u0002\u0000DDdd\u0002\u0000SSss\u0002\u0000VVvv\u0002"+ - "\u0000KKkk\u0002\u0000WWww\u0002\u0000FFff\u0002\u0000UUuu\u0006\u0000"+ - "\t\n\r\r //[[]]\f\u0000\t\n\r\r \"#(),,//::<<>?\\\\||\u0001\u000009"+ - "\u0002\u0000AZaz\b\u0000\"\"NNRRTT\\\\nnrrtt\u0004\u0000\n\n\r\r\"\"\\"+ - "\\\u0002\u0000++--\u0001\u0000``\u0002\u0000BBbb\u0002\u0000YYyy\f\u0000"+ - "\t\n\r\r \"\"(),,//::==[[]]||\u0002\u0000**//\u0002\u0000JJjj\u0886\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"+ - "\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\u0001Z"+ - "\u0001\u0000\u0000\u0000\u0001\\\u0001\u0000\u0000\u0000\u0001^\u0001"+ - "\u0000\u0000\u0000\u0001`\u0001\u0000\u0000\u0000\u0001b\u0001\u0000\u0000"+ - "\u0000\u0001d\u0001\u0000\u0000\u0000\u0001f\u0001\u0000\u0000\u0000\u0001"+ - "h\u0001\u0000\u0000\u0000\u0001j\u0001\u0000\u0000\u0000\u0001l\u0001"+ - "\u0000\u0000\u0000\u0001n\u0001\u0000\u0000\u0000\u0001p\u0001\u0000\u0000"+ - "\u0000\u0001r\u0001\u0000\u0000\u0000\u0002t\u0001\u0000\u0000\u0000\u0002"+ - "v\u0001\u0000\u0000\u0000\u0002x\u0001\u0000\u0000\u0000\u0002z\u0001"+ - "\u0000\u0000\u0000\u0002~\u0001\u0000\u0000\u0000\u0002\u0080\u0001\u0000"+ - "\u0000\u0000\u0002\u0082\u0001\u0000\u0000\u0000\u0002\u0084\u0001\u0000"+ - "\u0000\u0000\u0002\u0086\u0001\u0000\u0000\u0000\u0002\u0088\u0001\u0000"+ - "\u0000\u0000\u0003\u008a\u0001\u0000\u0000\u0000\u0003\u008c\u0001\u0000"+ - "\u0000\u0000\u0003\u008e\u0001\u0000\u0000\u0000\u0003\u0090\u0001\u0000"+ - "\u0000\u0000\u0003\u0092\u0001\u0000\u0000\u0000\u0003\u0094\u0001\u0000"+ - "\u0000\u0000\u0003\u0096\u0001\u0000\u0000\u0000\u0003\u0098\u0001\u0000"+ - "\u0000\u0000\u0003\u009a\u0001\u0000\u0000\u0000\u0003\u009c\u0001\u0000"+ - "\u0000\u0000\u0003\u009e\u0001\u0000\u0000\u0000\u0003\u00a0\u0001\u0000"+ - "\u0000\u0000\u0003\u00a2\u0001\u0000\u0000\u0000\u0003\u00a4\u0001\u0000"+ - "\u0000\u0000\u0003\u00a6\u0001\u0000\u0000\u0000\u0003\u00a8\u0001\u0000"+ - "\u0000\u0000\u0003\u00aa\u0001\u0000\u0000\u0000\u0004\u00ac\u0001\u0000"+ - "\u0000\u0000\u0004\u00ae\u0001\u0000\u0000\u0000\u0004\u00b0\u0001\u0000"+ - "\u0000\u0000\u0004\u00b2\u0001\u0000\u0000\u0000\u0004\u00b4\u0001\u0000"+ - "\u0000\u0000\u0005\u00b6\u0001\u0000\u0000\u0000\u0005\u00cc\u0001\u0000"+ - "\u0000\u0000\u0005\u00ce\u0001\u0000\u0000\u0000\u0005\u00d0\u0001\u0000"+ - "\u0000\u0000\u0005\u00d2\u0001\u0000\u0000\u0000\u0005\u00d4\u0001\u0000"+ - "\u0000\u0000\u0005\u00d6\u0001\u0000\u0000\u0000\u0005\u00d8\u0001\u0000"+ - "\u0000\u0000\u0005\u00da\u0001\u0000\u0000\u0000\u0005\u00dc\u0001\u0000"+ - "\u0000\u0000\u0005\u00de\u0001\u0000\u0000\u0000\u0005\u00e0\u0001\u0000"+ - "\u0000\u0000\u0005\u00e2\u0001\u0000\u0000\u0000\u0005\u00e4\u0001\u0000"+ - "\u0000\u0000\u0005\u00e6\u0001\u0000\u0000\u0000\u0005\u00e8\u0001\u0000"+ - "\u0000\u0000\u0005\u00ea\u0001\u0000\u0000\u0000\u0005\u00ec\u0001\u0000"+ - "\u0000\u0000\u0005\u00ee\u0001\u0000\u0000\u0000\u0005\u00f0\u0001\u0000"+ - "\u0000\u0000\u0005\u00f2\u0001\u0000\u0000\u0000\u0005\u00f4\u0001\u0000"+ - "\u0000\u0000\u0005\u00f6\u0001\u0000\u0000\u0000\u0005\u00f8\u0001\u0000"+ - "\u0000\u0000\u0005\u00fa\u0001\u0000\u0000\u0000\u0005\u00fc\u0001\u0000"+ - "\u0000\u0000\u0005\u00fe\u0001\u0000\u0000\u0000\u0005\u0100\u0001\u0000"+ - "\u0000\u0000\u0005\u0102\u0001\u0000\u0000\u0000\u0005\u0104\u0001\u0000"+ - "\u0000\u0000\u0005\u0106\u0001\u0000\u0000\u0000\u0005\u0108\u0001\u0000"+ - "\u0000\u0000\u0005\u010a\u0001\u0000\u0000\u0000\u0005\u010c\u0001\u0000"+ - "\u0000\u0000\u0005\u010e\u0001\u0000\u0000\u0000\u0005\u0110\u0001\u0000"+ - "\u0000\u0000\u0005\u0112\u0001\u0000\u0000\u0000\u0005\u0114\u0001\u0000"+ - "\u0000\u0000\u0005\u0116\u0001\u0000\u0000\u0000\u0005\u0118\u0001\u0000"+ - "\u0000\u0000\u0005\u011a\u0001\u0000\u0000\u0000\u0005\u011c\u0001\u0000"+ - "\u0000\u0000\u0005\u011e\u0001\u0000\u0000\u0000\u0005\u0120\u0001\u0000"+ - "\u0000\u0000\u0005\u0122\u0001\u0000\u0000\u0000\u0005\u0124\u0001\u0000"+ - "\u0000\u0000\u0005\u0126\u0001\u0000\u0000\u0000\u0005\u0128\u0001\u0000"+ - "\u0000\u0000\u0005\u012a\u0001\u0000\u0000\u0000\u0005\u012c\u0001\u0000"+ - "\u0000\u0000\u0005\u012e\u0001\u0000\u0000\u0000\u0005\u0130\u0001\u0000"+ - "\u0000\u0000\u0005\u0134\u0001\u0000\u0000\u0000\u0005\u0136\u0001\u0000"+ - "\u0000\u0000\u0005\u0138\u0001\u0000\u0000\u0000\u0005\u013a\u0001\u0000"+ - "\u0000\u0000\u0006\u013c\u0001\u0000\u0000\u0000\u0006\u013e\u0001\u0000"+ - "\u0000\u0000\u0006\u0140\u0001\u0000\u0000\u0000\u0006\u0142\u0001\u0000"+ - "\u0000\u0000\u0006\u0144\u0001\u0000\u0000\u0000\u0006\u0146\u0001\u0000"+ - "\u0000\u0000\u0006\u0148\u0001\u0000\u0000\u0000\u0006\u014a\u0001\u0000"+ - "\u0000\u0000\u0006\u014e\u0001\u0000\u0000\u0000\u0006\u0150\u0001\u0000"+ - "\u0000\u0000\u0006\u0152\u0001\u0000\u0000\u0000\u0006\u0154\u0001\u0000"+ - "\u0000\u0000\u0006\u0156\u0001\u0000\u0000\u0000\u0006\u0158\u0001\u0000"+ - "\u0000\u0000\u0007\u015a\u0001\u0000\u0000\u0000\u0007\u015c\u0001\u0000"+ - "\u0000\u0000\u0007\u015e\u0001\u0000\u0000\u0000\u0007\u0160\u0001\u0000"+ - "\u0000\u0000\u0007\u0162\u0001\u0000\u0000\u0000\u0007\u0164\u0001\u0000"+ - "\u0000\u0000\b\u0166\u0001\u0000\u0000\u0000\b\u0168\u0001\u0000\u0000"+ - "\u0000\b\u016a\u0001\u0000\u0000\u0000\b\u016c\u0001\u0000\u0000\u0000"+ - "\b\u016e\u0001\u0000\u0000\u0000\b\u0170\u0001\u0000\u0000\u0000\b\u0172"+ - "\u0001\u0000\u0000\u0000\b\u0174\u0001\u0000\u0000\u0000\b\u0176\u0001"+ - "\u0000\u0000\u0000\b\u0178\u0001\u0000\u0000\u0000\b\u017a\u0001\u0000"+ - "\u0000\u0000\b\u017c\u0001\u0000\u0000\u0000\b\u017e\u0001\u0000\u0000"+ - "\u0000\b\u0180\u0001\u0000\u0000\u0000\b\u0182\u0001\u0000\u0000\u0000"+ - "\b\u0184\u0001\u0000\u0000\u0000\b\u0186\u0001\u0000\u0000\u0000\b\u0188"+ - "\u0001\u0000\u0000\u0000\t\u018a\u0001\u0000\u0000\u0000\t\u018c\u0001"+ - "\u0000\u0000\u0000\t\u018e\u0001\u0000\u0000\u0000\t\u0190\u0001\u0000"+ - "\u0000\u0000\n\u0192\u0001\u0000\u0000\u0000\n\u0194\u0001\u0000\u0000"+ - "\u0000\n\u0196\u0001\u0000\u0000\u0000\n\u0198\u0001\u0000\u0000\u0000"+ - "\n\u019a\u0001\u0000\u0000\u0000\n\u019c\u0001\u0000\u0000\u0000\n\u019e"+ - "\u0001\u0000\u0000\u0000\n\u01a0\u0001\u0000\u0000\u0000\n\u01a2\u0001"+ - "\u0000\u0000\u0000\n\u01a4\u0001\u0000\u0000\u0000\n\u01a6\u0001\u0000"+ - "\u0000\u0000\u000b\u01a8\u0001\u0000\u0000\u0000\u000b\u01aa\u0001\u0000"+ - "\u0000\u0000\u000b\u01ac\u0001\u0000\u0000\u0000\u000b\u01ae\u0001\u0000"+ - "\u0000\u0000\u000b\u01b0\u0001\u0000\u0000\u0000\u000b\u01b2\u0001\u0000"+ - "\u0000\u0000\u000b\u01b4\u0001\u0000\u0000\u0000\u000b\u01b6\u0001\u0000"+ - "\u0000\u0000\u000b\u01b8\u0001\u0000\u0000\u0000\u000b\u01ba\u0001\u0000"+ - "\u0000\u0000\u000b\u01bc\u0001\u0000\u0000\u0000\f\u01be\u0001\u0000\u0000"+ - "\u0000\f\u01c0\u0001\u0000\u0000\u0000\f\u01c2\u0001\u0000\u0000\u0000"+ - "\f\u01c4\u0001\u0000\u0000\u0000\f\u01c6\u0001\u0000\u0000\u0000\f\u01c8"+ - "\u0001\u0000\u0000\u0000\f\u01ca\u0001\u0000\u0000\u0000\f\u01cc\u0001"+ - "\u0000\u0000\u0000\r\u01ce\u0001\u0000\u0000\u0000\r\u01d0\u0001\u0000"+ - "\u0000\u0000\r\u01d2\u0001\u0000\u0000\u0000\r\u01d4\u0001\u0000\u0000"+ - "\u0000\r\u01d6\u0001\u0000\u0000\u0000\r\u01d8\u0001\u0000\u0000\u0000"+ - "\r\u01da\u0001\u0000\u0000\u0000\r\u01dc\u0001\u0000\u0000\u0000\r\u01de"+ - "\u0001\u0000\u0000\u0000\r\u01e0\u0001\u0000\u0000\u0000\r\u01e2\u0001"+ - "\u0000\u0000\u0000\r\u01e4\u0001\u0000\u0000\u0000\r\u01e6\u0001\u0000"+ - "\u0000\u0000\r\u01e8\u0001\u0000\u0000\u0000\u000e\u01ea\u0001\u0000\u0000"+ - "\u0000\u000e\u01ec\u0001\u0000\u0000\u0000\u000e\u01ee\u0001\u0000\u0000"+ - "\u0000\u000e\u01f0\u0001\u0000\u0000\u0000\u000e\u01f2\u0001\u0000\u0000"+ - "\u0000\u000e\u01f4\u0001\u0000\u0000\u0000\u000e\u01f6\u0001\u0000\u0000"+ - "\u0000\u000e\u01f8\u0001\u0000\u0000\u0000\u000e\u01fa\u0001\u0000\u0000"+ - "\u0000\u000e\u01fc\u0001\u0000\u0000\u0000\u000e\u0202\u0001\u0000\u0000"+ - "\u0000\u000e\u0204\u0001\u0000\u0000\u0000\u000e\u0206\u0001\u0000\u0000"+ - "\u0000\u000e\u0208\u0001\u0000\u0000\u0000\u000f\u020a\u0001\u0000\u0000"+ - "\u0000\u000f\u020c\u0001\u0000\u0000\u0000\u000f\u020e\u0001\u0000\u0000"+ - "\u0000\u000f\u0210\u0001\u0000\u0000\u0000\u000f\u0212\u0001\u0000\u0000"+ - "\u0000\u000f\u0214\u0001\u0000\u0000\u0000\u000f\u0216\u0001\u0000\u0000"+ - "\u0000\u000f\u0218\u0001\u0000\u0000\u0000\u000f\u021a\u0001\u0000\u0000"+ - "\u0000\u000f\u021c\u0001\u0000\u0000\u0000\u000f\u021e\u0001\u0000\u0000"+ - "\u0000\u000f\u0220\u0001\u0000\u0000\u0000\u000f\u0222\u0001\u0000\u0000"+ - "\u0000\u000f\u0224\u0001\u0000\u0000\u0000\u000f\u0226\u0001\u0000\u0000"+ - "\u0000\u000f\u0228\u0001\u0000\u0000\u0000\u0010\u022a\u0001\u0000\u0000"+ - "\u0000\u0010\u022c\u0001\u0000\u0000\u0000\u0010\u022e\u0001\u0000\u0000"+ - "\u0000\u0010\u0230\u0001\u0000\u0000\u0000\u0010\u0232\u0001\u0000\u0000"+ - "\u0000\u0010\u0234\u0001\u0000\u0000\u0000\u0010\u0236\u0001\u0000\u0000"+ - "\u0000\u0010\u0238\u0001\u0000\u0000\u0000\u0010\u023a\u0001\u0000\u0000"+ - "\u0000\u0010\u023c\u0001\u0000\u0000\u0000\u0010\u023e\u0001\u0000\u0000"+ - "\u0000\u0010\u0240\u0001\u0000\u0000\u0000\u0010\u0242\u0001\u0000\u0000"+ - "\u0000\u0010\u0244\u0001\u0000\u0000\u0000\u0010\u0246\u0001\u0000\u0000"+ - "\u0000\u0010\u0248\u0001\u0000\u0000\u0000\u0010\u024a\u0001\u0000\u0000"+ - "\u0000\u0010\u024c\u0001\u0000\u0000\u0000\u0010\u024e\u0001\u0000\u0000"+ - "\u0000\u0010\u0250\u0001\u0000\u0000\u0000\u0010\u0252\u0001\u0000\u0000"+ - "\u0000\u0010\u0254\u0001\u0000\u0000\u0000\u0011\u0256\u0001\u0000\u0000"+ - "\u0000\u0011\u0258\u0001\u0000\u0000\u0000\u0011\u025a\u0001\u0000\u0000"+ - "\u0000\u0011\u025c\u0001\u0000\u0000\u0000\u0011\u025e\u0001\u0000\u0000"+ - "\u0000\u0012\u0260\u0001\u0000\u0000\u0000\u0014\u0271\u0001\u0000\u0000"+ - "\u0000\u0016\u0281\u0001\u0000\u0000\u0000\u0018\u0287\u0001\u0000\u0000"+ - "\u0000\u001a\u0296\u0001\u0000\u0000\u0000\u001c\u029f\u0001\u0000\u0000"+ - "\u0000\u001e\u02aa\u0001\u0000\u0000\u0000 \u02b7\u0001\u0000\u0000\u0000"+ - "\"\u02c1\u0001\u0000\u0000\u0000$\u02c8\u0001\u0000\u0000\u0000&\u02cf"+ - "\u0001\u0000\u0000\u0000(\u02d7\u0001\u0000\u0000\u0000*\u02e0\u0001\u0000"+ - "\u0000\u0000,\u02e6\u0001\u0000\u0000\u0000.\u02ef\u0001\u0000\u0000\u0000"+ - "0\u02f6\u0001\u0000\u0000\u00002\u02fe\u0001\u0000\u0000\u00004\u0306"+ - "\u0001\u0000\u0000\u00006\u030d\u0001\u0000\u0000\u00008\u0312\u0001\u0000"+ - "\u0000\u0000:\u0319\u0001\u0000\u0000\u0000<\u0320\u0001\u0000\u0000\u0000"+ - ">\u0329\u0001\u0000\u0000\u0000@\u0337\u0001\u0000\u0000\u0000B\u0340"+ - "\u0001\u0000\u0000\u0000D\u0348\u0001\u0000\u0000\u0000F\u0350\u0001\u0000"+ - "\u0000\u0000H\u0359\u0001\u0000\u0000\u0000J\u0365\u0001\u0000\u0000\u0000"+ - "L\u0371\u0001\u0000\u0000\u0000N\u0378\u0001\u0000\u0000\u0000P\u037f"+ - "\u0001\u0000\u0000\u0000R\u038b\u0001\u0000\u0000\u0000T\u0394\u0001\u0000"+ - "\u0000\u0000V\u039a\u0001\u0000\u0000\u0000X\u03a2\u0001\u0000\u0000\u0000"+ - "Z\u03a8\u0001\u0000\u0000\u0000\\\u03ad\u0001\u0000\u0000\u0000^\u03b3"+ - "\u0001\u0000\u0000\u0000`\u03b7\u0001\u0000\u0000\u0000b\u03bb\u0001\u0000"+ - "\u0000\u0000d\u03bf\u0001\u0000\u0000\u0000f\u03c3\u0001\u0000\u0000\u0000"+ - "h\u03c7\u0001\u0000\u0000\u0000j\u03cb\u0001\u0000\u0000\u0000l\u03cf"+ - "\u0001\u0000\u0000\u0000n\u03d3\u0001\u0000\u0000\u0000p\u03d7\u0001\u0000"+ - "\u0000\u0000r\u03db\u0001\u0000\u0000\u0000t\u03df\u0001\u0000\u0000\u0000"+ - "v\u03e4\u0001\u0000\u0000\u0000x\u03ea\u0001\u0000\u0000\u0000z\u03ef"+ - "\u0001\u0000\u0000\u0000|\u03f4\u0001\u0000\u0000\u0000~\u03fd\u0001\u0000"+ - "\u0000\u0000\u0080\u0404\u0001\u0000\u0000\u0000\u0082\u0408\u0001\u0000"+ - "\u0000\u0000\u0084\u040c\u0001\u0000\u0000\u0000\u0086\u0410\u0001\u0000"+ - "\u0000\u0000\u0088\u0414\u0001\u0000\u0000\u0000\u008a\u0418\u0001\u0000"+ - "\u0000\u0000\u008c\u041e\u0001\u0000\u0000\u0000\u008e\u0425\u0001\u0000"+ - "\u0000\u0000\u0090\u0429\u0001\u0000\u0000\u0000\u0092\u042d\u0001\u0000"+ - "\u0000\u0000\u0094\u0431\u0001\u0000\u0000\u0000\u0096\u0435\u0001\u0000"+ - "\u0000\u0000\u0098\u0439\u0001\u0000\u0000\u0000\u009a\u043d\u0001\u0000"+ - "\u0000\u0000\u009c\u0441\u0001\u0000\u0000\u0000\u009e\u0445\u0001\u0000"+ - "\u0000\u0000\u00a0\u0449\u0001\u0000\u0000\u0000\u00a2\u044d\u0001\u0000"+ - "\u0000\u0000\u00a4\u0451\u0001\u0000\u0000\u0000\u00a6\u0455\u0001\u0000"+ - "\u0000\u0000\u00a8\u0459\u0001\u0000\u0000\u0000\u00aa\u045d\u0001\u0000"+ - "\u0000\u0000\u00ac\u0461\u0001\u0000\u0000\u0000\u00ae\u0466\u0001\u0000"+ - "\u0000\u0000\u00b0\u046b\u0001\u0000\u0000\u0000\u00b2\u046f\u0001\u0000"+ - "\u0000\u0000\u00b4\u0473\u0001\u0000\u0000\u0000\u00b6\u0477\u0001\u0000"+ - "\u0000\u0000\u00b8\u047b\u0001\u0000\u0000\u0000\u00ba\u047d\u0001\u0000"+ - "\u0000\u0000\u00bc\u047f\u0001\u0000\u0000\u0000\u00be\u0482\u0001\u0000"+ - "\u0000\u0000\u00c0\u0484\u0001\u0000\u0000\u0000\u00c2\u048d\u0001\u0000"+ - "\u0000\u0000\u00c4\u048f\u0001\u0000\u0000\u0000\u00c6\u0494\u0001\u0000"+ - "\u0000\u0000\u00c8\u0496\u0001\u0000\u0000\u0000\u00ca\u049b\u0001\u0000"+ - "\u0000\u0000\u00cc\u04ba\u0001\u0000\u0000\u0000\u00ce\u04bd\u0001\u0000"+ - "\u0000\u0000\u00d0\u04eb\u0001\u0000\u0000\u0000\u00d2\u04ed\u0001\u0000"+ - "\u0000\u0000\u00d4\u04f1\u0001\u0000\u0000\u0000\u00d6\u04f5\u0001\u0000"+ - "\u0000\u0000\u00d8\u04f7\u0001\u0000\u0000\u0000\u00da\u04fa\u0001\u0000"+ - "\u0000\u0000\u00dc\u04fd\u0001\u0000\u0000\u0000\u00de\u04ff\u0001\u0000"+ - "\u0000\u0000\u00e0\u0501\u0001\u0000\u0000\u0000\u00e2\u0503\u0001\u0000"+ - "\u0000\u0000\u00e4\u0508\u0001\u0000\u0000\u0000\u00e6\u050a\u0001\u0000"+ - "\u0000\u0000\u00e8\u0510\u0001\u0000\u0000\u0000\u00ea\u0516\u0001\u0000"+ - "\u0000\u0000\u00ec\u0519\u0001\u0000\u0000\u0000\u00ee\u051c\u0001\u0000"+ - "\u0000\u0000\u00f0\u0521\u0001\u0000\u0000\u0000\u00f2\u0526\u0001\u0000"+ - "\u0000\u0000\u00f4\u052a\u0001\u0000\u0000\u0000\u00f6\u052f\u0001\u0000"+ - "\u0000\u0000\u00f8\u0535\u0001\u0000\u0000\u0000\u00fa\u0538\u0001\u0000"+ - "\u0000\u0000\u00fc\u053b\u0001\u0000\u0000\u0000\u00fe\u053d\u0001\u0000"+ - "\u0000\u0000\u0100\u0543\u0001\u0000\u0000\u0000\u0102\u0548\u0001\u0000"+ - "\u0000\u0000\u0104\u054d\u0001\u0000\u0000\u0000\u0106\u0550\u0001\u0000"+ - "\u0000\u0000\u0108\u0553\u0001\u0000\u0000\u0000\u010a\u0556\u0001\u0000"+ - "\u0000\u0000\u010c\u0558\u0001\u0000\u0000\u0000\u010e\u055b\u0001\u0000"+ - "\u0000\u0000\u0110\u055d\u0001\u0000\u0000\u0000\u0112\u0560\u0001\u0000"+ - "\u0000\u0000\u0114\u0562\u0001\u0000\u0000\u0000\u0116\u0564\u0001\u0000"+ - "\u0000\u0000\u0118\u0566\u0001\u0000\u0000\u0000\u011a\u0568\u0001\u0000"+ - "\u0000\u0000\u011c\u056a\u0001\u0000\u0000\u0000\u011e\u056c\u0001\u0000"+ - "\u0000\u0000\u0120\u056e\u0001\u0000\u0000\u0000\u0122\u0571\u0001\u0000"+ - "\u0000\u0000\u0124\u0586\u0001\u0000\u0000\u0000\u0126\u0599\u0001\u0000"+ - "\u0000\u0000\u0128\u059b\u0001\u0000\u0000\u0000\u012a\u05a0\u0001\u0000"+ - "\u0000\u0000\u012c\u05a5\u0001\u0000\u0000\u0000\u012e\u05aa\u0001\u0000"+ - "\u0000\u0000\u0130\u05bf\u0001\u0000\u0000\u0000\u0132\u05c1\u0001\u0000"+ - "\u0000\u0000\u0134\u05c9\u0001\u0000\u0000\u0000\u0136\u05cb\u0001\u0000"+ - "\u0000\u0000\u0138\u05cf\u0001\u0000\u0000\u0000\u013a\u05d3\u0001\u0000"+ - "\u0000\u0000\u013c\u05d7\u0001\u0000\u0000\u0000\u013e\u05dc\u0001\u0000"+ - "\u0000\u0000\u0140\u05e0\u0001\u0000\u0000\u0000\u0142\u05e4\u0001\u0000"+ - "\u0000\u0000\u0144\u05e8\u0001\u0000\u0000\u0000\u0146\u05ec\u0001\u0000"+ - "\u0000\u0000\u0148\u05f5\u0001\u0000\u0000\u0000\u014a\u05fb\u0001\u0000"+ - "\u0000\u0000\u014c\u0603\u0001\u0000\u0000\u0000\u014e\u0606\u0001\u0000"+ - "\u0000\u0000\u0150\u060a\u0001\u0000\u0000\u0000\u0152\u060e\u0001\u0000"+ - "\u0000\u0000\u0154\u0612\u0001\u0000\u0000\u0000\u0156\u0616\u0001\u0000"+ - "\u0000\u0000\u0158\u061a\u0001\u0000\u0000\u0000\u015a\u061e\u0001\u0000"+ - "\u0000\u0000\u015c\u0623\u0001\u0000\u0000\u0000\u015e\u0629\u0001\u0000"+ - "\u0000\u0000\u0160\u062e\u0001\u0000\u0000\u0000\u0162\u0632\u0001\u0000"+ - "\u0000\u0000\u0164\u0636\u0001\u0000\u0000\u0000\u0166\u063a\u0001\u0000"+ - "\u0000\u0000\u0168\u063f\u0001\u0000\u0000\u0000\u016a\u0645\u0001\u0000"+ - "\u0000\u0000\u016c\u064b\u0001\u0000\u0000\u0000\u016e\u0651\u0001\u0000"+ - "\u0000\u0000\u0170\u0655\u0001\u0000\u0000\u0000\u0172\u065b\u0001\u0000"+ - "\u0000\u0000\u0174\u065f\u0001\u0000\u0000\u0000\u0176\u0663\u0001\u0000"+ - "\u0000\u0000\u0178\u0667\u0001\u0000\u0000\u0000\u017a\u066b\u0001\u0000"+ - "\u0000\u0000\u017c\u066f\u0001\u0000\u0000\u0000\u017e\u0673\u0001\u0000"+ - "\u0000\u0000\u0180\u0677\u0001\u0000\u0000\u0000\u0182\u067b\u0001\u0000"+ - "\u0000\u0000\u0184\u067f\u0001\u0000\u0000\u0000\u0186\u0683\u0001\u0000"+ - "\u0000\u0000\u0188\u0687\u0001\u0000\u0000\u0000\u018a\u068b\u0001\u0000"+ - "\u0000\u0000\u018c\u0694\u0001\u0000\u0000\u0000\u018e\u0698\u0001\u0000"+ - "\u0000\u0000\u0190\u069c\u0001\u0000\u0000\u0000\u0192\u06a0\u0001\u0000"+ - "\u0000\u0000\u0194\u06a5\u0001\u0000\u0000\u0000\u0196\u06aa\u0001\u0000"+ - "\u0000\u0000\u0198\u06ae\u0001\u0000\u0000\u0000\u019a\u06b4\u0001\u0000"+ - "\u0000\u0000\u019c\u06bd\u0001\u0000\u0000\u0000\u019e\u06c1\u0001\u0000"+ - "\u0000\u0000\u01a0\u06c5\u0001\u0000\u0000\u0000\u01a2\u06c9\u0001\u0000"+ - "\u0000\u0000\u01a4\u06cd\u0001\u0000\u0000\u0000\u01a6\u06d1\u0001\u0000"+ - "\u0000\u0000\u01a8\u06d5\u0001\u0000\u0000\u0000\u01aa\u06da\u0001\u0000"+ - "\u0000\u0000\u01ac\u06e0\u0001\u0000\u0000\u0000\u01ae\u06e4\u0001\u0000"+ - "\u0000\u0000\u01b0\u06e8\u0001\u0000\u0000\u0000\u01b2\u06ec\u0001\u0000"+ - "\u0000\u0000\u01b4\u06f1\u0001\u0000\u0000\u0000\u01b6\u06f5\u0001\u0000"+ - "\u0000\u0000\u01b8\u06f9\u0001\u0000\u0000\u0000\u01ba\u06fd\u0001\u0000"+ - "\u0000\u0000\u01bc\u0701\u0001\u0000\u0000\u0000\u01be\u0705\u0001\u0000"+ - "\u0000\u0000\u01c0\u070b\u0001\u0000\u0000\u0000\u01c2\u0712\u0001\u0000"+ - "\u0000\u0000\u01c4\u0716\u0001\u0000\u0000\u0000\u01c6\u071a\u0001\u0000"+ - "\u0000\u0000\u01c8\u071e\u0001\u0000\u0000\u0000\u01ca\u0722\u0001\u0000"+ - "\u0000\u0000\u01cc\u0726\u0001\u0000\u0000\u0000\u01ce\u072a\u0001\u0000"+ - "\u0000\u0000\u01d0\u072f\u0001\u0000\u0000\u0000\u01d2\u0735\u0001\u0000"+ - "\u0000\u0000\u01d4\u0739\u0001\u0000\u0000\u0000\u01d6\u073d\u0001\u0000"+ - "\u0000\u0000\u01d8\u0741\u0001\u0000\u0000\u0000\u01da\u0745\u0001\u0000"+ - "\u0000\u0000\u01dc\u0749\u0001\u0000\u0000\u0000\u01de\u074d\u0001\u0000"+ - "\u0000\u0000\u01e0\u0751\u0001\u0000\u0000\u0000\u01e2\u0755\u0001\u0000"+ - "\u0000\u0000\u01e4\u0759\u0001\u0000\u0000\u0000\u01e6\u075d\u0001\u0000"+ - "\u0000\u0000\u01e8\u0761\u0001\u0000\u0000\u0000\u01ea\u0765\u0001\u0000"+ - "\u0000\u0000\u01ec\u076a\u0001\u0000\u0000\u0000\u01ee\u0770\u0001\u0000"+ - "\u0000\u0000\u01f0\u0774\u0001\u0000\u0000\u0000\u01f2\u0778\u0001\u0000"+ - "\u0000\u0000\u01f4\u077c\u0001\u0000\u0000\u0000\u01f6\u0780\u0001\u0000"+ - "\u0000\u0000\u01f8\u0784\u0001\u0000\u0000\u0000\u01fa\u0788\u0001\u0000"+ - "\u0000\u0000\u01fc\u078c\u0001\u0000\u0000\u0000\u01fe\u0794\u0001\u0000"+ - "\u0000\u0000\u0200\u07a9\u0001\u0000\u0000\u0000\u0202\u07ad\u0001\u0000"+ - "\u0000\u0000\u0204\u07b1\u0001\u0000\u0000\u0000\u0206\u07b5\u0001\u0000"+ - "\u0000\u0000\u0208\u07b9\u0001\u0000\u0000\u0000\u020a\u07bd\u0001\u0000"+ - "\u0000\u0000\u020c\u07c2\u0001\u0000\u0000\u0000\u020e\u07c8\u0001\u0000"+ - "\u0000\u0000\u0210\u07cc\u0001\u0000\u0000\u0000\u0212\u07d0\u0001\u0000"+ - "\u0000\u0000\u0214\u07d4\u0001\u0000\u0000\u0000\u0216\u07d8\u0001\u0000"+ - "\u0000\u0000\u0218\u07dc\u0001\u0000\u0000\u0000\u021a\u07e0\u0001\u0000"+ - "\u0000\u0000\u021c\u07e4\u0001\u0000\u0000\u0000\u021e\u07e8\u0001\u0000"+ - "\u0000\u0000\u0220\u07ec\u0001\u0000\u0000\u0000\u0222\u07ef\u0001\u0000"+ - "\u0000\u0000\u0224\u07f3\u0001\u0000\u0000\u0000\u0226\u07f7\u0001\u0000"+ - "\u0000\u0000\u0228\u07fb\u0001\u0000\u0000\u0000\u022a\u07ff\u0001\u0000"+ - "\u0000\u0000\u022c\u0803\u0001\u0000\u0000\u0000\u022e\u0807\u0001\u0000"+ - "\u0000\u0000\u0230\u080b\u0001\u0000\u0000\u0000\u0232\u0810\u0001\u0000"+ - "\u0000\u0000\u0234\u0814\u0001\u0000\u0000\u0000\u0236\u0818\u0001\u0000"+ - "\u0000\u0000\u0238\u081c\u0001\u0000\u0000\u0000\u023a\u0820\u0001\u0000"+ - "\u0000\u0000\u023c\u0824\u0001\u0000\u0000\u0000\u023e\u0828\u0001\u0000"+ - "\u0000\u0000\u0240\u082c\u0001\u0000\u0000\u0000\u0242\u0830\u0001\u0000"+ - "\u0000\u0000\u0244\u0834\u0001\u0000\u0000\u0000\u0246\u0838\u0001\u0000"+ - "\u0000\u0000\u0248\u083c\u0001\u0000\u0000\u0000\u024a\u0840\u0001\u0000"+ - "\u0000\u0000\u024c\u0844\u0001\u0000\u0000\u0000\u024e\u0848\u0001\u0000"+ - "\u0000\u0000\u0250\u084c\u0001\u0000\u0000\u0000\u0252\u0850\u0001\u0000"+ - "\u0000\u0000\u0254\u0854\u0001\u0000\u0000\u0000\u0256\u0858\u0001\u0000"+ - "\u0000\u0000\u0258\u085d\u0001\u0000\u0000\u0000\u025a\u0862\u0001\u0000"+ - "\u0000\u0000\u025c\u0866\u0001\u0000\u0000\u0000\u025e\u086a\u0001\u0000"+ - "\u0000\u0000\u0260\u0261\u0005/\u0000\u0000\u0261\u0262\u0005/\u0000\u0000"+ - "\u0262\u0266\u0001\u0000\u0000\u0000\u0263\u0265\b\u0000\u0000\u0000\u0264"+ - "\u0263\u0001\u0000\u0000\u0000\u0265\u0268\u0001\u0000\u0000\u0000\u0266"+ - "\u0264\u0001\u0000\u0000\u0000\u0266\u0267\u0001\u0000\u0000\u0000\u0267"+ - "\u026a\u0001\u0000\u0000\u0000\u0268\u0266\u0001\u0000\u0000\u0000\u0269"+ - "\u026b\u0005\r\u0000\u0000\u026a\u0269\u0001\u0000\u0000\u0000\u026a\u026b"+ - "\u0001\u0000\u0000\u0000\u026b\u026d\u0001\u0000\u0000\u0000\u026c\u026e"+ - "\u0005\n\u0000\u0000\u026d\u026c\u0001\u0000\u0000\u0000\u026d\u026e\u0001"+ - "\u0000\u0000\u0000\u026e\u026f\u0001\u0000\u0000\u0000\u026f\u0270\u0006"+ - "\u0000\u0000\u0000\u0270\u0013\u0001\u0000\u0000\u0000\u0271\u0272\u0005"+ - "/\u0000\u0000\u0272\u0273\u0005*\u0000\u0000\u0273\u0278\u0001\u0000\u0000"+ - "\u0000\u0274\u0277\u0003\u0014\u0001\u0000\u0275\u0277\t\u0000\u0000\u0000"+ - "\u0276\u0274\u0001\u0000\u0000\u0000\u0276\u0275\u0001\u0000\u0000\u0000"+ - "\u0277\u027a\u0001\u0000\u0000\u0000\u0278\u0279\u0001\u0000\u0000\u0000"+ - "\u0278\u0276\u0001\u0000\u0000\u0000\u0279\u027b\u0001\u0000\u0000\u0000"+ - "\u027a\u0278\u0001\u0000\u0000\u0000\u027b\u027c\u0005*\u0000\u0000\u027c"+ - "\u027d\u0005/\u0000\u0000\u027d\u027e\u0001\u0000\u0000\u0000\u027e\u027f"+ - "\u0006\u0001\u0000\u0000\u027f\u0015\u0001\u0000\u0000\u0000\u0280\u0282"+ - "\u0007\u0001\u0000\u0000\u0281\u0280\u0001\u0000\u0000\u0000\u0282\u0283"+ - "\u0001\u0000\u0000\u0000\u0283\u0281\u0001\u0000\u0000\u0000\u0283\u0284"+ - "\u0001\u0000\u0000\u0000\u0284\u0285\u0001\u0000\u0000\u0000\u0285\u0286"+ - "\u0006\u0002\u0000\u0000\u0286\u0017\u0001\u0000\u0000\u0000\u0287\u0288"+ - "\u0007\u0002\u0000\u0000\u0288\u0289\u0007\u0003\u0000\u0000\u0289\u028a"+ - "\u0007\u0004\u0000\u0000\u028a\u028b\u0007\u0005\u0000\u0000\u028b\u028c"+ - "\u0007\u0006\u0000\u0000\u028c\u028d\u0007\u0007\u0000\u0000\u028d\u028e"+ - "\u0005_\u0000\u0000\u028e\u028f\u0007\b\u0000\u0000\u028f\u0290\u0007"+ - "\t\u0000\u0000\u0290\u0291\u0007\n\u0000\u0000\u0291\u0292\u0007\u0005"+ - "\u0000\u0000\u0292\u0293\u0007\u000b\u0000\u0000\u0293\u0294\u0001\u0000"+ - "\u0000\u0000\u0294\u0295\u0006\u0003\u0001\u0000\u0295\u0019\u0001\u0000"+ - "\u0000\u0000\u0296\u0297\u0007\u0007\u0000\u0000\u0297\u0298\u0007\u0005"+ - "\u0000\u0000\u0298\u0299\u0007\f\u0000\u0000\u0299\u029a\u0007\n\u0000"+ - "\u0000\u029a\u029b\u0007\u0002\u0000\u0000\u029b\u029c\u0007\u0003\u0000"+ - "\u0000\u029c\u029d\u0001\u0000\u0000\u0000\u029d\u029e\u0006\u0004\u0002"+ - "\u0000\u029e\u001b\u0001\u0000\u0000\u0000\u029f\u02a0\u0004\u0005\u0000"+ - "\u0000\u02a0\u02a1\u0007\u0007\u0000\u0000\u02a1\u02a2\u0007\r\u0000\u0000"+ - "\u02a2\u02a3\u0007\b\u0000\u0000\u02a3\u02a4\u0007\u000e\u0000\u0000\u02a4"+ - "\u02a5\u0007\u0004\u0000\u0000\u02a5\u02a6\u0007\n\u0000\u0000\u02a6\u02a7"+ - "\u0007\u0005\u0000\u0000\u02a7\u02a8\u0001\u0000\u0000\u0000\u02a8\u02a9"+ - "\u0006\u0005\u0003\u0000\u02a9\u001d\u0001\u0000\u0000\u0000\u02aa\u02ab"+ - "\u0007\u0002\u0000\u0000\u02ab\u02ac\u0007\t\u0000\u0000\u02ac\u02ad\u0007"+ - "\u000f\u0000\u0000\u02ad\u02ae\u0007\b\u0000\u0000\u02ae\u02af\u0007\u000e"+ - "\u0000\u0000\u02af\u02b0\u0007\u0007\u0000\u0000\u02b0\u02b1\u0007\u000b"+ - "\u0000\u0000\u02b1\u02b2\u0007\n\u0000\u0000\u02b2\u02b3\u0007\t\u0000"+ - "\u0000\u02b3\u02b4\u0007\u0005\u0000\u0000\u02b4\u02b5\u0001\u0000\u0000"+ - "\u0000\u02b5\u02b6\u0006\u0006\u0004\u0000\u02b6\u001f\u0001\u0000\u0000"+ - "\u0000\u02b7\u02b8\u0007\u0010\u0000\u0000\u02b8\u02b9\u0007\n\u0000\u0000"+ - "\u02b9\u02ba\u0007\u0011\u0000\u0000\u02ba\u02bb\u0007\u0011\u0000\u0000"+ - "\u02bb\u02bc\u0007\u0007\u0000\u0000\u02bc\u02bd\u0007\u0002\u0000\u0000"+ - "\u02bd\u02be\u0007\u000b\u0000\u0000\u02be\u02bf\u0001\u0000\u0000\u0000"+ - "\u02bf\u02c0\u0006\u0007\u0004\u0000\u02c0!\u0001\u0000\u0000\u0000\u02c1"+ - "\u02c2\u0007\u0007\u0000\u0000\u02c2\u02c3\u0007\u0012\u0000\u0000\u02c3"+ - "\u02c4\u0007\u0004\u0000\u0000\u02c4\u02c5\u0007\u000e\u0000\u0000\u02c5"+ - "\u02c6\u0001\u0000\u0000\u0000\u02c6\u02c7\u0006\b\u0004\u0000\u02c7#"+ - "\u0001\u0000\u0000\u0000\u02c8\u02c9\u0007\u0006\u0000\u0000\u02c9\u02ca"+ - "\u0007\f\u0000\u0000\u02ca\u02cb\u0007\t\u0000\u0000\u02cb\u02cc\u0007"+ - "\u0013\u0000\u0000\u02cc\u02cd\u0001\u0000\u0000\u0000\u02cd\u02ce\u0006"+ - "\t\u0004\u0000\u02ce%\u0001\u0000\u0000\u0000\u02cf\u02d0\u0007\u000e"+ - "\u0000\u0000\u02d0\u02d1\u0007\n\u0000\u0000\u02d1\u02d2\u0007\u000f\u0000"+ - "\u0000\u02d2\u02d3\u0007\n\u0000\u0000\u02d3\u02d4\u0007\u000b\u0000\u0000"+ - "\u02d4\u02d5\u0001\u0000\u0000\u0000\u02d5\u02d6\u0006\n\u0004\u0000\u02d6"+ - "\'\u0001\u0000\u0000\u0000\u02d7\u02d8\u0007\f\u0000\u0000\u02d8\u02d9"+ - "\u0007\u0007\u0000\u0000\u02d9\u02da\u0007\f\u0000\u0000\u02da\u02db\u0007"+ - "\u0004\u0000\u0000\u02db\u02dc\u0007\u0005\u0000\u0000\u02dc\u02dd\u0007"+ - "\u0013\u0000\u0000\u02dd\u02de\u0001\u0000\u0000\u0000\u02de\u02df\u0006"+ - "\u000b\u0004\u0000\u02df)\u0001\u0000\u0000\u0000\u02e0\u02e1\u0007\f"+ - "\u0000\u0000\u02e1\u02e2\u0007\t\u0000\u0000\u02e2\u02e3\u0007\u0014\u0000"+ - "\u0000\u02e3\u02e4\u0001\u0000\u0000\u0000\u02e4\u02e5\u0006\f\u0004\u0000"+ - "\u02e5+\u0001\u0000\u0000\u0000\u02e6\u02e7\u0007\u0011\u0000\u0000\u02e7"+ - "\u02e8\u0007\u0004\u0000\u0000\u02e8\u02e9\u0007\u000f\u0000\u0000\u02e9"+ - "\u02ea\u0007\b\u0000\u0000\u02ea\u02eb\u0007\u000e\u0000\u0000\u02eb\u02ec"+ - "\u0007\u0007\u0000\u0000\u02ec\u02ed\u0001\u0000\u0000\u0000\u02ed\u02ee"+ - "\u0006\r\u0004\u0000\u02ee-\u0001\u0000\u0000\u0000\u02ef\u02f0\u0007"+ - "\u0011\u0000\u0000\u02f0\u02f1\u0007\t\u0000\u0000\u02f1\u02f2\u0007\f"+ - "\u0000\u0000\u02f2\u02f3\u0007\u000b\u0000\u0000\u02f3\u02f4\u0001\u0000"+ - "\u0000\u0000\u02f4\u02f5\u0006\u000e\u0004\u0000\u02f5/\u0001\u0000\u0000"+ - "\u0000\u02f6\u02f7\u0007\u0011\u0000\u0000\u02f7\u02f8\u0007\u000b\u0000"+ - "\u0000\u02f8\u02f9\u0007\u0004\u0000\u0000\u02f9\u02fa\u0007\u000b\u0000"+ - "\u0000\u02fa\u02fb\u0007\u0011\u0000\u0000\u02fb\u02fc\u0001\u0000\u0000"+ - "\u0000\u02fc\u02fd\u0006\u000f\u0004\u0000\u02fd1\u0001\u0000\u0000\u0000"+ - "\u02fe\u02ff\u0007\u0014\u0000\u0000\u02ff\u0300\u0007\u0003\u0000\u0000"+ - "\u0300\u0301\u0007\u0007\u0000\u0000\u0301\u0302\u0007\f\u0000\u0000\u0302"+ - "\u0303\u0007\u0007\u0000\u0000\u0303\u0304\u0001\u0000\u0000\u0000\u0304"+ - "\u0305\u0006\u0010\u0004\u0000\u03053\u0001\u0000\u0000\u0000\u0306\u0307"+ - "\u0007\u0015\u0000\u0000\u0307\u0308\u0007\f\u0000\u0000\u0308\u0309\u0007"+ - "\t\u0000\u0000\u0309\u030a\u0007\u000f\u0000\u0000\u030a\u030b\u0001\u0000"+ - "\u0000\u0000\u030b\u030c\u0006\u0011\u0005\u0000\u030c5\u0001\u0000\u0000"+ - "\u0000\u030d\u030e\u0007\u000b\u0000\u0000\u030e\u030f\u0007\u0011\u0000"+ - "\u0000\u030f\u0310\u0001\u0000\u0000\u0000\u0310\u0311\u0006\u0012\u0005"+ - "\u0000\u03117\u0001\u0000\u0000\u0000\u0312\u0313\u0007\u0015\u0000\u0000"+ - "\u0313\u0314\u0007\t\u0000\u0000\u0314\u0315\u0007\f\u0000\u0000\u0315"+ - "\u0316\u0007\u0013\u0000\u0000\u0316\u0317\u0001\u0000\u0000\u0000\u0317"+ - "\u0318\u0006\u0013\u0006\u0000\u03189\u0001\u0000\u0000\u0000\u0319\u031a"+ - "\u0007\u0015\u0000\u0000\u031a\u031b\u0007\u0016\u0000\u0000\u031b\u031c"+ - "\u0007\u0011\u0000\u0000\u031c\u031d\u0007\u0007\u0000\u0000\u031d\u031e"+ - "\u0001\u0000\u0000\u0000\u031e\u031f\u0006\u0014\u0007\u0000\u031f;\u0001"+ - "\u0000\u0000\u0000\u0320\u0321\u0007\n\u0000\u0000\u0321\u0322\u0007\u0005"+ - "\u0000\u0000\u0322\u0323\u0007\u000e\u0000\u0000\u0323\u0324\u0007\n\u0000"+ - "\u0000\u0324\u0325\u0007\u0005\u0000\u0000\u0325\u0326\u0007\u0007\u0000"+ - "\u0000\u0326\u0327\u0001\u0000\u0000\u0000\u0327\u0328\u0006\u0015\b\u0000"+ - "\u0328=\u0001\u0000\u0000\u0000\u0329\u032a\u0007\n\u0000\u0000\u032a"+ - "\u032b\u0007\u0005\u0000\u0000\u032b\u032c\u0007\u000e\u0000\u0000\u032c"+ - "\u032d\u0007\n\u0000\u0000\u032d\u032e\u0007\u0005\u0000\u0000\u032e\u032f"+ - "\u0007\u0007\u0000\u0000\u032f\u0330\u0007\u0011\u0000\u0000\u0330\u0331"+ - "\u0007\u000b\u0000\u0000\u0331\u0332\u0007\u0004\u0000\u0000\u0332\u0333"+ - "\u0007\u000b\u0000\u0000\u0333\u0334\u0007\u0011\u0000\u0000\u0334\u0335"+ - "\u0001\u0000\u0000\u0000\u0335\u0336\u0006\u0016\u0004\u0000\u0336?\u0001"+ - "\u0000\u0000\u0000\u0337\u0338\u0007\u000e\u0000\u0000\u0338\u0339\u0007"+ - "\t\u0000\u0000\u0339\u033a\u0007\t\u0000\u0000\u033a\u033b\u0007\u0013"+ - "\u0000\u0000\u033b\u033c\u0007\u0016\u0000\u0000\u033c\u033d\u0007\b\u0000"+ - "\u0000\u033d\u033e\u0001\u0000\u0000\u0000\u033e\u033f\u0006\u0017\t\u0000"+ - "\u033fA\u0001\u0000\u0000\u0000\u0340\u0341\u0004\u0018\u0001\u0000\u0341"+ - "\u0342\u0007\u0015\u0000\u0000\u0342\u0343\u0007\u0016\u0000\u0000\u0343"+ - "\u0344\u0007\u000e\u0000\u0000\u0344\u0345\u0007\u000e\u0000\u0000\u0345"+ - "\u0346\u0001\u0000\u0000\u0000\u0346\u0347\u0006\u0018\t\u0000\u0347C"+ - "\u0001\u0000\u0000\u0000\u0348\u0349\u0004\u0019\u0002\u0000\u0349\u034a"+ - "\u0007\u000e\u0000\u0000\u034a\u034b\u0007\u0007\u0000\u0000\u034b\u034c"+ - "\u0007\u0015\u0000\u0000\u034c\u034d\u0007\u000b\u0000\u0000\u034d\u034e"+ - "\u0001\u0000\u0000\u0000\u034e\u034f\u0006\u0019\t\u0000\u034fE\u0001"+ - "\u0000\u0000\u0000\u0350\u0351\u0004\u001a\u0003\u0000\u0351\u0352\u0007"+ - "\f\u0000\u0000\u0352\u0353\u0007\n\u0000\u0000\u0353\u0354\u0007\u0006"+ - "\u0000\u0000\u0354\u0355\u0007\u0003\u0000\u0000\u0355\u0356\u0007\u000b"+ - "\u0000\u0000\u0356\u0357\u0001\u0000\u0000\u0000\u0357\u0358\u0006\u001a"+ - "\t\u0000\u0358G\u0001\u0000\u0000\u0000\u0359\u035a\u0004\u001b\u0004"+ - "\u0000\u035a\u035b\u0007\u000e\u0000\u0000\u035b\u035c\u0007\t\u0000\u0000"+ - "\u035c\u035d\u0007\t\u0000\u0000\u035d\u035e\u0007\u0013\u0000\u0000\u035e"+ - "\u035f\u0007\u0016\u0000\u0000\u035f\u0360\u0007\b\u0000\u0000\u0360\u0361"+ - "\u0005_\u0000\u0000\u0361\u0362\u0005\u8001\uf414\u0000\u0000\u0362\u0363"+ - "\u0001\u0000\u0000\u0000\u0363\u0364\u0006\u001b\n\u0000\u0364I\u0001"+ - "\u0000\u0000\u0000\u0365\u0366\u0007\u000f\u0000\u0000\u0366\u0367\u0007"+ - "\u0012\u0000\u0000\u0367\u0368\u0005_\u0000\u0000\u0368\u0369\u0007\u0007"+ - "\u0000\u0000\u0369\u036a\u0007\r\u0000\u0000\u036a\u036b\u0007\b\u0000"+ - "\u0000\u036b\u036c\u0007\u0004\u0000\u0000\u036c\u036d\u0007\u0005\u0000"+ - "\u0000\u036d\u036e\u0007\u0010\u0000\u0000\u036e\u036f\u0001\u0000\u0000"+ - "\u0000\u036f\u0370\u0006\u001c\u000b\u0000\u0370K\u0001\u0000\u0000\u0000"+ - "\u0371\u0372\u0007\u0010\u0000\u0000\u0372\u0373\u0007\f\u0000\u0000\u0373"+ - "\u0374\u0007\t\u0000\u0000\u0374\u0375\u0007\b\u0000\u0000\u0375\u0376"+ - "\u0001\u0000\u0000\u0000\u0376\u0377\u0006\u001d\f\u0000\u0377M\u0001"+ - "\u0000\u0000\u0000\u0378\u0379\u0007\u0013\u0000\u0000\u0379\u037a\u0007"+ - "\u0007\u0000\u0000\u037a\u037b\u0007\u0007\u0000\u0000\u037b\u037c\u0007"+ - "\b\u0000\u0000\u037c\u037d\u0001\u0000\u0000\u0000\u037d\u037e\u0006\u001e"+ - "\f\u0000\u037eO\u0001\u0000\u0000\u0000\u037f\u0380\u0004\u001f\u0005"+ - "\u0000\u0380\u0381\u0007\n\u0000\u0000\u0381\u0382\u0007\u0005\u0000\u0000"+ - "\u0382\u0383\u0007\u0011\u0000\u0000\u0383\u0384\u0007\n\u0000\u0000\u0384"+ - "\u0385\u0007\u0011\u0000\u0000\u0385\u0386\u0007\u000b\u0000\u0000\u0386"+ - "\u0387\u0005_\u0000\u0000\u0387\u0388\u0005\u8001\uf414\u0000\u0000\u0388"+ - "\u0389\u0001\u0000\u0000\u0000\u0389\u038a\u0006\u001f\f\u0000\u038aQ"+ - "\u0001\u0000\u0000\u0000\u038b\u038c\u0007\f\u0000\u0000\u038c\u038d\u0007"+ - "\u0007\u0000\u0000\u038d\u038e\u0007\u0005\u0000\u0000\u038e\u038f\u0007"+ - "\u0004\u0000\u0000\u038f\u0390\u0007\u000f\u0000\u0000\u0390\u0391\u0007"+ - "\u0007\u0000\u0000\u0391\u0392\u0001\u0000\u0000\u0000\u0392\u0393\u0006"+ - " \r\u0000\u0393S\u0001\u0000\u0000\u0000\u0394\u0395\u0007\u0011\u0000"+ - "\u0000\u0395\u0396\u0007\u0007\u0000\u0000\u0396\u0397\u0007\u000b\u0000"+ - "\u0000\u0397\u0398\u0001\u0000\u0000\u0000\u0398\u0399\u0006!\u000e\u0000"+ - "\u0399U\u0001\u0000\u0000\u0000\u039a\u039b\u0007\u0011\u0000\u0000\u039b"+ - "\u039c\u0007\u0003\u0000\u0000\u039c\u039d\u0007\t\u0000\u0000\u039d\u039e"+ - "\u0007\u0014\u0000\u0000\u039e\u039f\u0001\u0000\u0000\u0000\u039f\u03a0"+ - "\u0006\"\u000f\u0000\u03a0W\u0001\u0000\u0000\u0000\u03a1\u03a3\b\u0017"+ - "\u0000\u0000\u03a2\u03a1\u0001\u0000\u0000\u0000\u03a3\u03a4\u0001\u0000"+ - "\u0000\u0000\u03a4\u03a2\u0001\u0000\u0000\u0000\u03a4\u03a5\u0001\u0000"+ - "\u0000\u0000\u03a5\u03a6\u0001\u0000\u0000\u0000\u03a6\u03a7\u0006#\u0004"+ - "\u0000\u03a7Y\u0001\u0000\u0000\u0000\u03a8\u03a9\u0003\u00b6R\u0000\u03a9"+ - "\u03aa\u0001\u0000\u0000\u0000\u03aa\u03ab\u0006$\u0010\u0000\u03ab\u03ac"+ - "\u0006$\u0011\u0000\u03ac[\u0001\u0000\u0000\u0000\u03ad\u03ae\u0003\u012e"+ - "\u008e\u0000\u03ae\u03af\u0001\u0000\u0000\u0000\u03af\u03b0\u0006%\u0012"+ - "\u0000\u03b0\u03b1\u0006%\u0011\u0000\u03b1\u03b2\u0006%\u0011\u0000\u03b2"+ - "]\u0001\u0000\u0000\u0000\u03b3\u03b4\u0003\u00f8s\u0000\u03b4\u03b5\u0001"+ - "\u0000\u0000\u0000\u03b5\u03b6\u0006&\u0013\u0000\u03b6_\u0001\u0000\u0000"+ - "\u0000\u03b7\u03b8\u0003\u0220\u0107\u0000\u03b8\u03b9\u0001\u0000\u0000"+ - "\u0000\u03b9\u03ba\u0006\'\u0014\u0000\u03baa\u0001\u0000\u0000\u0000"+ - "\u03bb\u03bc\u0003\u00e4i\u0000\u03bc\u03bd\u0001\u0000\u0000\u0000\u03bd"+ - "\u03be\u0006(\u0015\u0000\u03bec\u0001\u0000\u0000\u0000\u03bf\u03c0\u0003"+ - "\u00e0g\u0000\u03c0\u03c1\u0001\u0000\u0000\u0000\u03c1\u03c2\u0006)\u0016"+ - "\u0000\u03c2e\u0001\u0000\u0000\u0000\u03c3\u03c4\u0003\u0128\u008b\u0000"+ - "\u03c4\u03c5\u0001\u0000\u0000\u0000\u03c5\u03c6\u0006*\u0017\u0000\u03c6"+ - "g\u0001\u0000\u0000\u0000\u03c7\u03c8\u0003\u012a\u008c\u0000\u03c8\u03c9"+ - "\u0001\u0000\u0000\u0000\u03c9\u03ca\u0006+\u0018\u0000\u03cai\u0001\u0000"+ - "\u0000\u0000\u03cb\u03cc\u0003\u0134\u0091\u0000\u03cc\u03cd\u0001\u0000"+ - "\u0000\u0000\u03cd\u03ce\u0006,\u0019\u0000\u03cek\u0001\u0000\u0000\u0000"+ - "\u03cf\u03d0\u0003\u0130\u008f\u0000\u03d0\u03d1\u0001\u0000\u0000\u0000"+ - "\u03d1\u03d2\u0006-\u001a\u0000\u03d2m\u0001\u0000\u0000\u0000\u03d3\u03d4"+ - "\u0003\u0012\u0000\u0000\u03d4\u03d5\u0001\u0000\u0000\u0000\u03d5\u03d6"+ - "\u0006.\u0000\u0000\u03d6o\u0001\u0000\u0000\u0000\u03d7\u03d8\u0003\u0014"+ - "\u0001\u0000\u03d8\u03d9\u0001\u0000\u0000\u0000\u03d9\u03da\u0006/\u0000"+ - "\u0000\u03daq\u0001\u0000\u0000\u0000\u03db\u03dc\u0003\u0016\u0002\u0000"+ - "\u03dc\u03dd\u0001\u0000\u0000\u0000\u03dd\u03de\u00060\u0000\u0000\u03de"+ - "s\u0001\u0000\u0000\u0000\u03df\u03e0\u0003\u00b6R\u0000\u03e0\u03e1\u0001"+ - "\u0000\u0000\u0000\u03e1\u03e2\u00061\u0010\u0000\u03e2\u03e3\u00061\u0011"+ - "\u0000\u03e3u\u0001\u0000\u0000\u0000\u03e4\u03e5\u0003\u012e\u008e\u0000"+ - "\u03e5\u03e6\u0001\u0000\u0000\u0000\u03e6\u03e7\u00062\u0012\u0000\u03e7"+ - "\u03e8\u00062\u0011\u0000\u03e8\u03e9\u00062\u0011\u0000\u03e9w\u0001"+ - "\u0000\u0000\u0000\u03ea\u03eb\u0003\u00f8s\u0000\u03eb\u03ec\u0001\u0000"+ - "\u0000\u0000\u03ec\u03ed\u00063\u0013\u0000\u03ed\u03ee\u00063\u001b\u0000"+ - "\u03eey\u0001\u0000\u0000\u0000\u03ef\u03f0\u0003\u0102x\u0000\u03f0\u03f1"+ - "\u0001\u0000\u0000\u0000\u03f1\u03f2\u00064\u001c\u0000\u03f2\u03f3\u0006"+ - "4\u001b\u0000\u03f3{\u0001\u0000\u0000\u0000\u03f4\u03f5\b\u0018\u0000"+ - "\u0000\u03f5}\u0001\u0000\u0000\u0000\u03f6\u03f8\u0003|5\u0000\u03f7"+ - "\u03f6\u0001\u0000\u0000\u0000\u03f8\u03f9\u0001\u0000\u0000\u0000\u03f9"+ - "\u03f7\u0001\u0000\u0000\u0000\u03f9\u03fa\u0001\u0000\u0000\u0000\u03fa"+ - "\u03fb\u0001\u0000\u0000\u0000\u03fb\u03fc\u0003\u00dce\u0000\u03fc\u03fe"+ - "\u0001\u0000\u0000\u0000\u03fd\u03f7\u0001\u0000\u0000\u0000\u03fd\u03fe"+ - "\u0001\u0000\u0000\u0000\u03fe\u0400\u0001\u0000\u0000\u0000\u03ff\u0401"+ - "\u0003|5\u0000\u0400\u03ff\u0001\u0000\u0000\u0000\u0401\u0402\u0001\u0000"+ - "\u0000\u0000\u0402\u0400\u0001\u0000\u0000\u0000\u0402\u0403\u0001\u0000"+ - "\u0000\u0000\u0403\u007f\u0001\u0000\u0000\u0000\u0404\u0405\u0003~6\u0000"+ - "\u0405\u0406\u0001\u0000\u0000\u0000\u0406\u0407\u00067\u001d\u0000\u0407"+ - "\u0081\u0001\u0000\u0000\u0000\u0408\u0409\u0003\u00cc]\u0000\u0409\u040a"+ - "\u0001\u0000\u0000\u0000\u040a\u040b\u00068\u001e\u0000\u040b\u0083\u0001"+ - "\u0000\u0000\u0000\u040c\u040d\u0003\u0012\u0000\u0000\u040d\u040e\u0001"+ - "\u0000\u0000\u0000\u040e\u040f\u00069\u0000\u0000\u040f\u0085\u0001\u0000"+ - "\u0000\u0000\u0410\u0411\u0003\u0014\u0001\u0000\u0411\u0412\u0001\u0000"+ - "\u0000\u0000\u0412\u0413\u0006:\u0000\u0000\u0413\u0087\u0001\u0000\u0000"+ - "\u0000\u0414\u0415\u0003\u0016\u0002\u0000\u0415\u0416\u0001\u0000\u0000"+ - "\u0000\u0416\u0417\u0006;\u0000\u0000\u0417\u0089\u0001\u0000\u0000\u0000"+ - "\u0418\u0419\u0003\u00b6R\u0000\u0419\u041a\u0001\u0000\u0000\u0000\u041a"+ - "\u041b\u0006<\u0010\u0000\u041b\u041c\u0006<\u0011\u0000\u041c\u041d\u0006"+ - "<\u0011\u0000\u041d\u008b\u0001\u0000\u0000\u0000\u041e\u041f\u0003\u012e"+ - "\u008e\u0000\u041f\u0420\u0001\u0000\u0000\u0000\u0420\u0421\u0006=\u0012"+ - "\u0000\u0421\u0422\u0006=\u0011\u0000\u0422\u0423\u0006=\u0011\u0000\u0423"+ - "\u0424\u0006=\u0011\u0000\u0424\u008d\u0001\u0000\u0000\u0000\u0425\u0426"+ - "\u0003\u0128\u008b\u0000\u0426\u0427\u0001\u0000\u0000\u0000\u0427\u0428"+ - "\u0006>\u0017\u0000\u0428\u008f\u0001\u0000\u0000\u0000\u0429\u042a\u0003"+ - "\u012a\u008c\u0000\u042a\u042b\u0001\u0000\u0000\u0000\u042b\u042c\u0006"+ - "?\u0018\u0000\u042c\u0091\u0001\u0000\u0000\u0000\u042d\u042e\u0003\u00d6"+ - "b\u0000\u042e\u042f\u0001\u0000\u0000\u0000\u042f\u0430\u0006@\u001f\u0000"+ - "\u0430\u0093\u0001\u0000\u0000\u0000\u0431\u0432\u0003\u00e0g\u0000\u0432"+ - "\u0433\u0001\u0000\u0000\u0000\u0433\u0434\u0006A\u0016\u0000\u0434\u0095"+ - "\u0001\u0000\u0000\u0000\u0435\u0436\u0003\u00e4i\u0000\u0436\u0437\u0001"+ - "\u0000\u0000\u0000\u0437\u0438\u0006B\u0015\u0000\u0438\u0097\u0001\u0000"+ - "\u0000\u0000\u0439\u043a\u0003\u0102x\u0000\u043a\u043b\u0001\u0000\u0000"+ - "\u0000\u043b\u043c\u0006C\u001c\u0000\u043c\u0099\u0001\u0000\u0000\u0000"+ - "\u043d\u043e\u0003\u0202\u00f8\u0000\u043e\u043f\u0001\u0000\u0000\u0000"+ - "\u043f\u0440\u0006D \u0000\u0440\u009b\u0001\u0000\u0000\u0000\u0441\u0442"+ - "\u0003\u0134\u0091\u0000\u0442\u0443\u0001\u0000\u0000\u0000\u0443\u0444"+ - "\u0006E\u0019\u0000\u0444\u009d\u0001\u0000\u0000\u0000\u0445\u0446\u0003"+ - "\u00fcu\u0000\u0446\u0447\u0001\u0000\u0000\u0000\u0447\u0448\u0006F!"+ - "\u0000\u0448\u009f\u0001\u0000\u0000\u0000\u0449\u044a\u0003\u0124\u0089"+ - "\u0000\u044a\u044b\u0001\u0000\u0000\u0000\u044b\u044c\u0006G\"\u0000"+ - "\u044c\u00a1\u0001\u0000\u0000\u0000\u044d\u044e\u0003\u0120\u0087\u0000"+ - "\u044e\u044f\u0001\u0000\u0000\u0000\u044f\u0450\u0006H#\u0000\u0450\u00a3"+ - "\u0001\u0000\u0000\u0000\u0451\u0452\u0003\u0126\u008a\u0000\u0452\u0453"+ - "\u0001\u0000\u0000\u0000\u0453\u0454\u0006I$\u0000\u0454\u00a5\u0001\u0000"+ - "\u0000\u0000\u0455\u0456\u0003\u0012\u0000\u0000\u0456\u0457\u0001\u0000"+ - "\u0000\u0000\u0457\u0458\u0006J\u0000\u0000\u0458\u00a7\u0001\u0000\u0000"+ - "\u0000\u0459\u045a\u0003\u0014\u0001\u0000\u045a\u045b\u0001\u0000\u0000"+ - "\u0000\u045b\u045c\u0006K\u0000\u0000\u045c\u00a9\u0001\u0000\u0000\u0000"+ - "\u045d\u045e\u0003\u0016\u0002\u0000\u045e\u045f\u0001\u0000\u0000\u0000"+ - "\u045f\u0460\u0006L\u0000\u0000\u0460\u00ab\u0001\u0000\u0000\u0000\u0461"+ - "\u0462\u0003\u012c\u008d\u0000\u0462\u0463\u0001\u0000\u0000\u0000\u0463"+ - "\u0464\u0006M%\u0000\u0464\u0465\u0006M&\u0000\u0465\u00ad\u0001\u0000"+ - "\u0000\u0000\u0466\u0467\u0003\u00b6R\u0000\u0467\u0468\u0001\u0000\u0000"+ - "\u0000\u0468\u0469\u0006N\u0010\u0000\u0469\u046a\u0006N\u0011\u0000\u046a"+ - "\u00af\u0001\u0000\u0000\u0000\u046b\u046c\u0003\u0016\u0002\u0000\u046c"+ - "\u046d\u0001\u0000\u0000\u0000\u046d\u046e\u0006O\u0000\u0000\u046e\u00b1"+ - "\u0001\u0000\u0000\u0000\u046f\u0470\u0003\u0012\u0000\u0000\u0470\u0471"+ - "\u0001\u0000\u0000\u0000\u0471\u0472\u0006P\u0000\u0000\u0472\u00b3\u0001"+ - "\u0000\u0000\u0000\u0473\u0474\u0003\u0014\u0001\u0000\u0474\u0475\u0001"+ - "\u0000\u0000\u0000\u0475\u0476\u0006Q\u0000\u0000\u0476\u00b5\u0001\u0000"+ - "\u0000\u0000\u0477\u0478\u0005|\u0000\u0000\u0478\u0479\u0001\u0000\u0000"+ - "\u0000\u0479\u047a\u0006R\u0011\u0000\u047a\u00b7\u0001\u0000\u0000\u0000"+ - "\u047b\u047c\u0007\u0019\u0000\u0000\u047c\u00b9\u0001\u0000\u0000\u0000"+ - "\u047d\u047e\u0007\u001a\u0000\u0000\u047e\u00bb\u0001\u0000\u0000\u0000"+ - "\u047f\u0480\u0005\\\u0000\u0000\u0480\u0481\u0007\u001b\u0000\u0000\u0481"+ - "\u00bd\u0001\u0000\u0000\u0000\u0482\u0483\b\u001c\u0000\u0000\u0483\u00bf"+ - "\u0001\u0000\u0000\u0000\u0484\u0486\u0007\u0007\u0000\u0000\u0485\u0487"+ - "\u0007\u001d\u0000\u0000\u0486\u0485\u0001\u0000\u0000\u0000\u0486\u0487"+ - "\u0001\u0000\u0000\u0000\u0487\u0489\u0001\u0000\u0000\u0000\u0488\u048a"+ - "\u0003\u00b8S\u0000\u0489\u0488\u0001\u0000\u0000\u0000\u048a\u048b\u0001"+ - "\u0000\u0000\u0000\u048b\u0489\u0001\u0000\u0000\u0000\u048b\u048c\u0001"+ - "\u0000\u0000\u0000\u048c\u00c1\u0001\u0000\u0000\u0000\u048d\u048e\u0005"+ - "@\u0000\u0000\u048e\u00c3\u0001\u0000\u0000\u0000\u048f\u0490\u0005`\u0000"+ - "\u0000\u0490\u00c5\u0001\u0000\u0000\u0000\u0491\u0495\b\u001e\u0000\u0000"+ - "\u0492\u0493\u0005`\u0000\u0000\u0493\u0495\u0005`\u0000\u0000\u0494\u0491"+ - "\u0001\u0000\u0000\u0000\u0494\u0492\u0001\u0000\u0000\u0000\u0495\u00c7"+ - "\u0001\u0000\u0000\u0000\u0496\u0497\u0005_\u0000\u0000\u0497\u00c9\u0001"+ - "\u0000\u0000\u0000\u0498\u049c\u0003\u00baT\u0000\u0499\u049c\u0003\u00b8"+ - "S\u0000\u049a\u049c\u0003\u00c8[\u0000\u049b\u0498\u0001\u0000\u0000\u0000"+ - "\u049b\u0499\u0001\u0000\u0000\u0000\u049b\u049a\u0001\u0000\u0000\u0000"+ - "\u049c\u00cb\u0001\u0000\u0000\u0000\u049d\u04a2\u0005\"\u0000\u0000\u049e"+ - "\u04a1\u0003\u00bcU\u0000\u049f\u04a1\u0003\u00beV\u0000\u04a0\u049e\u0001"+ - "\u0000\u0000\u0000\u04a0\u049f\u0001\u0000\u0000\u0000\u04a1\u04a4\u0001"+ - "\u0000\u0000\u0000\u04a2\u04a0\u0001\u0000\u0000\u0000\u04a2\u04a3\u0001"+ - "\u0000\u0000\u0000\u04a3\u04a5\u0001\u0000\u0000\u0000\u04a4\u04a2\u0001"+ - "\u0000\u0000\u0000\u04a5\u04bb\u0005\"\u0000\u0000\u04a6\u04a7\u0005\""+ - "\u0000\u0000\u04a7\u04a8\u0005\"\u0000\u0000\u04a8\u04a9\u0005\"\u0000"+ - "\u0000\u04a9\u04ad\u0001\u0000\u0000\u0000\u04aa\u04ac\b\u0000\u0000\u0000"+ - "\u04ab\u04aa\u0001\u0000\u0000\u0000\u04ac\u04af\u0001\u0000\u0000\u0000"+ - "\u04ad\u04ae\u0001\u0000\u0000\u0000\u04ad\u04ab\u0001\u0000\u0000\u0000"+ - "\u04ae\u04b0\u0001\u0000\u0000\u0000\u04af\u04ad\u0001\u0000\u0000\u0000"+ - "\u04b0\u04b1\u0005\"\u0000\u0000\u04b1\u04b2\u0005\"\u0000\u0000\u04b2"+ - "\u04b3\u0005\"\u0000\u0000\u04b3\u04b5\u0001\u0000\u0000\u0000\u04b4\u04b6"+ - "\u0005\"\u0000\u0000\u04b5\u04b4\u0001\u0000\u0000\u0000\u04b5\u04b6\u0001"+ - "\u0000\u0000\u0000\u04b6\u04b8\u0001\u0000\u0000\u0000\u04b7\u04b9\u0005"+ - "\"\u0000\u0000\u04b8\u04b7\u0001\u0000\u0000\u0000\u04b8\u04b9\u0001\u0000"+ - "\u0000\u0000\u04b9\u04bb\u0001\u0000\u0000\u0000\u04ba\u049d\u0001\u0000"+ - "\u0000\u0000\u04ba\u04a6\u0001\u0000\u0000\u0000\u04bb\u00cd\u0001\u0000"+ - "\u0000\u0000\u04bc\u04be\u0003\u00b8S\u0000\u04bd\u04bc\u0001\u0000\u0000"+ - "\u0000\u04be\u04bf\u0001\u0000\u0000\u0000\u04bf\u04bd\u0001\u0000\u0000"+ - "\u0000\u04bf\u04c0\u0001\u0000\u0000\u0000\u04c0\u00cf\u0001\u0000\u0000"+ - "\u0000\u04c1\u04c3\u0003\u00b8S\u0000\u04c2\u04c1\u0001\u0000\u0000\u0000"+ - "\u04c3\u04c4\u0001\u0000\u0000\u0000\u04c4\u04c2\u0001\u0000\u0000\u0000"+ - "\u04c4\u04c5\u0001\u0000\u0000\u0000\u04c5\u04c6\u0001\u0000\u0000\u0000"+ - "\u04c6\u04ca\u0003\u00e4i\u0000\u04c7\u04c9\u0003\u00b8S\u0000\u04c8\u04c7"+ - "\u0001\u0000\u0000\u0000\u04c9\u04cc\u0001\u0000\u0000\u0000\u04ca\u04c8"+ - "\u0001\u0000\u0000\u0000\u04ca\u04cb\u0001\u0000\u0000\u0000\u04cb\u04ec"+ - "\u0001\u0000\u0000\u0000\u04cc\u04ca\u0001\u0000\u0000\u0000\u04cd\u04cf"+ - "\u0003\u00e4i\u0000\u04ce\u04d0\u0003\u00b8S\u0000\u04cf\u04ce\u0001\u0000"+ - "\u0000\u0000\u04d0\u04d1\u0001\u0000\u0000\u0000\u04d1\u04cf\u0001\u0000"+ - "\u0000\u0000\u04d1\u04d2\u0001\u0000\u0000\u0000\u04d2\u04ec\u0001\u0000"+ - "\u0000\u0000\u04d3\u04d5\u0003\u00b8S\u0000\u04d4\u04d3\u0001\u0000\u0000"+ - "\u0000\u04d5\u04d6\u0001\u0000\u0000\u0000\u04d6\u04d4\u0001\u0000\u0000"+ - "\u0000\u04d6\u04d7\u0001\u0000\u0000\u0000\u04d7\u04df\u0001\u0000\u0000"+ - "\u0000\u04d8\u04dc\u0003\u00e4i\u0000\u04d9\u04db\u0003\u00b8S\u0000\u04da"+ - "\u04d9\u0001\u0000\u0000\u0000\u04db\u04de\u0001\u0000\u0000\u0000\u04dc"+ - "\u04da\u0001\u0000\u0000\u0000\u04dc\u04dd\u0001\u0000\u0000\u0000\u04dd"+ - "\u04e0\u0001\u0000\u0000\u0000\u04de\u04dc\u0001\u0000\u0000\u0000\u04df"+ - "\u04d8\u0001\u0000\u0000\u0000\u04df\u04e0\u0001\u0000\u0000\u0000\u04e0"+ - "\u04e1\u0001\u0000\u0000\u0000\u04e1\u04e2\u0003\u00c0W\u0000\u04e2\u04ec"+ - "\u0001\u0000\u0000\u0000\u04e3\u04e5\u0003\u00e4i\u0000\u04e4\u04e6\u0003"+ - "\u00b8S\u0000\u04e5\u04e4\u0001\u0000\u0000\u0000\u04e6\u04e7\u0001\u0000"+ - "\u0000\u0000\u04e7\u04e5\u0001\u0000\u0000\u0000\u04e7\u04e8\u0001\u0000"+ - "\u0000\u0000\u04e8\u04e9\u0001\u0000\u0000\u0000\u04e9\u04ea\u0003\u00c0"+ - "W\u0000\u04ea\u04ec\u0001\u0000\u0000\u0000\u04eb\u04c2\u0001\u0000\u0000"+ - "\u0000\u04eb\u04cd\u0001\u0000\u0000\u0000\u04eb\u04d4\u0001\u0000\u0000"+ - "\u0000\u04eb\u04e3\u0001\u0000\u0000\u0000\u04ec\u00d1\u0001\u0000\u0000"+ - "\u0000\u04ed\u04ee\u0007\u0004\u0000\u0000\u04ee\u04ef\u0007\u0005\u0000"+ - "\u0000\u04ef\u04f0\u0007\u0010\u0000\u0000\u04f0\u00d3\u0001\u0000\u0000"+ - "\u0000\u04f1\u04f2\u0007\u0004\u0000\u0000\u04f2\u04f3\u0007\u0011\u0000"+ - "\u0000\u04f3\u04f4\u0007\u0002\u0000\u0000\u04f4\u00d5\u0001\u0000\u0000"+ - "\u0000\u04f5\u04f6\u0005=\u0000\u0000\u04f6\u00d7\u0001\u0000\u0000\u0000"+ - "\u04f7\u04f8\u0007\u001f\u0000\u0000\u04f8\u04f9\u0007 \u0000\u0000\u04f9"+ - "\u00d9\u0001\u0000\u0000\u0000\u04fa\u04fb\u0005:\u0000\u0000\u04fb\u04fc"+ - "\u0005:\u0000\u0000\u04fc\u00db\u0001\u0000\u0000\u0000\u04fd\u04fe\u0005"+ - ":\u0000\u0000\u04fe\u00dd\u0001\u0000\u0000\u0000\u04ff\u0500\u0005;\u0000"+ - "\u0000\u0500\u00df\u0001\u0000\u0000\u0000\u0501\u0502\u0005,\u0000\u0000"+ - "\u0502\u00e1\u0001\u0000\u0000\u0000\u0503\u0504\u0007\u0010\u0000\u0000"+ - "\u0504\u0505\u0007\u0007\u0000\u0000\u0505\u0506\u0007\u0011\u0000\u0000"+ - "\u0506\u0507\u0007\u0002\u0000\u0000\u0507\u00e3\u0001\u0000\u0000\u0000"+ - "\u0508\u0509\u0005.\u0000\u0000\u0509\u00e5\u0001\u0000\u0000\u0000\u050a"+ - "\u050b\u0007\u0015\u0000\u0000\u050b\u050c\u0007\u0004\u0000\u0000\u050c"+ - "\u050d\u0007\u000e\u0000\u0000\u050d\u050e\u0007\u0011\u0000\u0000\u050e"+ - "\u050f\u0007\u0007\u0000\u0000\u050f\u00e7\u0001\u0000\u0000\u0000\u0510"+ - "\u0511\u0007\u0015\u0000\u0000\u0511\u0512\u0007\n\u0000\u0000\u0512\u0513"+ - "\u0007\f\u0000\u0000\u0513\u0514\u0007\u0011\u0000\u0000\u0514\u0515\u0007"+ - "\u000b\u0000\u0000\u0515\u00e9\u0001\u0000\u0000\u0000\u0516\u0517\u0007"+ - "\n\u0000\u0000\u0517\u0518\u0007\u0005\u0000\u0000\u0518\u00eb\u0001\u0000"+ - "\u0000\u0000\u0519\u051a\u0007\n\u0000\u0000\u051a\u051b\u0007\u0011\u0000"+ - "\u0000\u051b\u00ed\u0001\u0000\u0000\u0000\u051c\u051d\u0007\u000e\u0000"+ - "\u0000\u051d\u051e\u0007\u0004\u0000\u0000\u051e\u051f\u0007\u0011\u0000"+ - "\u0000\u051f\u0520\u0007\u000b\u0000\u0000\u0520\u00ef\u0001\u0000\u0000"+ - "\u0000\u0521\u0522\u0007\u000e\u0000\u0000\u0522\u0523\u0007\n\u0000\u0000"+ - "\u0523\u0524\u0007\u0013\u0000\u0000\u0524\u0525\u0007\u0007\u0000\u0000"+ - "\u0525\u00f1\u0001\u0000\u0000\u0000\u0526\u0527\u0007\u0005\u0000\u0000"+ - "\u0527\u0528\u0007\t\u0000\u0000\u0528\u0529\u0007\u000b\u0000\u0000\u0529"+ - "\u00f3\u0001\u0000\u0000\u0000\u052a\u052b\u0007\u0005\u0000\u0000\u052b"+ - "\u052c\u0007\u0016\u0000\u0000\u052c\u052d\u0007\u000e\u0000\u0000\u052d"+ - "\u052e\u0007\u000e\u0000\u0000\u052e\u00f5\u0001\u0000\u0000\u0000\u052f"+ - "\u0530\u0007\u0005\u0000\u0000\u0530\u0531\u0007\u0016\u0000\u0000\u0531"+ - "\u0532\u0007\u000e\u0000\u0000\u0532\u0533\u0007\u000e\u0000\u0000\u0533"+ - "\u0534\u0007\u0011\u0000\u0000\u0534\u00f7\u0001\u0000\u0000\u0000\u0535"+ - "\u0536\u0007\t\u0000\u0000\u0536\u0537\u0007\u0005\u0000\u0000\u0537\u00f9"+ - "\u0001\u0000\u0000\u0000\u0538\u0539\u0007\t\u0000\u0000\u0539\u053a\u0007"+ - "\f\u0000\u0000\u053a\u00fb\u0001\u0000\u0000\u0000\u053b\u053c\u0005?"+ - "\u0000\u0000\u053c\u00fd\u0001\u0000\u0000\u0000\u053d\u053e\u0007\f\u0000"+ - "\u0000\u053e\u053f\u0007\u000e\u0000\u0000\u053f\u0540\u0007\n\u0000\u0000"+ - "\u0540\u0541\u0007\u0013\u0000\u0000\u0541\u0542\u0007\u0007\u0000\u0000"+ - "\u0542\u00ff\u0001\u0000\u0000\u0000\u0543\u0544\u0007\u000b\u0000\u0000"+ - "\u0544\u0545\u0007\f\u0000\u0000\u0545\u0546\u0007\u0016\u0000\u0000\u0546"+ - "\u0547\u0007\u0007\u0000\u0000\u0547\u0101\u0001\u0000\u0000\u0000\u0548"+ - "\u0549\u0007\u0014\u0000\u0000\u0549\u054a\u0007\n\u0000\u0000\u054a\u054b"+ - "\u0007\u000b\u0000\u0000\u054b\u054c\u0007\u0003\u0000\u0000\u054c\u0103"+ - "\u0001\u0000\u0000\u0000\u054d\u054e\u0005=\u0000\u0000\u054e\u054f\u0005"+ - "=\u0000\u0000\u054f\u0105\u0001\u0000\u0000\u0000\u0550\u0551\u0005=\u0000"+ - "\u0000\u0551\u0552\u0005~\u0000\u0000\u0552\u0107\u0001\u0000\u0000\u0000"+ - "\u0553\u0554\u0005!\u0000\u0000\u0554\u0555\u0005=\u0000\u0000\u0555\u0109"+ - "\u0001\u0000\u0000\u0000\u0556\u0557\u0005<\u0000\u0000\u0557\u010b\u0001"+ - "\u0000\u0000\u0000\u0558\u0559\u0005<\u0000\u0000\u0559\u055a\u0005=\u0000"+ - "\u0000\u055a\u010d\u0001\u0000\u0000\u0000\u055b\u055c\u0005>\u0000\u0000"+ - "\u055c\u010f\u0001\u0000\u0000\u0000\u055d\u055e\u0005>\u0000\u0000\u055e"+ - "\u055f\u0005=\u0000\u0000\u055f\u0111\u0001\u0000\u0000\u0000\u0560\u0561"+ - "\u0005+\u0000\u0000\u0561\u0113\u0001\u0000\u0000\u0000\u0562\u0563\u0005"+ - "-\u0000\u0000\u0563\u0115\u0001\u0000\u0000\u0000\u0564\u0565\u0005*\u0000"+ - "\u0000\u0565\u0117\u0001\u0000\u0000\u0000\u0566\u0567\u0005/\u0000\u0000"+ - "\u0567\u0119\u0001\u0000\u0000\u0000\u0568\u0569\u0005%\u0000\u0000\u0569"+ - "\u011b\u0001\u0000\u0000\u0000\u056a\u056b\u0005{\u0000\u0000\u056b\u011d"+ - "\u0001\u0000\u0000\u0000\u056c\u056d\u0005}\u0000\u0000\u056d\u011f\u0001"+ - "\u0000\u0000\u0000\u056e\u056f\u0005?\u0000\u0000\u056f\u0570\u0005?\u0000"+ - "\u0000\u0570\u0121\u0001\u0000\u0000\u0000\u0571\u0572\u00032\u0010\u0000"+ - "\u0572\u0573\u0001\u0000\u0000\u0000\u0573\u0574\u0006\u0088\'\u0000\u0574"+ - "\u0123\u0001\u0000\u0000\u0000\u0575\u0578\u0003\u00fcu\u0000\u0576\u0579"+ - "\u0003\u00baT\u0000\u0577\u0579\u0003\u00c8[\u0000\u0578\u0576\u0001\u0000"+ - "\u0000\u0000\u0578\u0577\u0001\u0000\u0000\u0000\u0579\u057d\u0001\u0000"+ - "\u0000\u0000\u057a\u057c\u0003\u00ca\\\u0000\u057b\u057a\u0001\u0000\u0000"+ - "\u0000\u057c\u057f\u0001\u0000\u0000\u0000\u057d\u057b\u0001\u0000\u0000"+ - "\u0000\u057d\u057e\u0001\u0000\u0000\u0000\u057e\u0587\u0001\u0000\u0000"+ - "\u0000\u057f\u057d\u0001\u0000\u0000\u0000\u0580\u0582\u0003\u00fcu\u0000"+ - "\u0581\u0583\u0003\u00b8S\u0000\u0582\u0581\u0001\u0000\u0000\u0000\u0583"+ - "\u0584\u0001\u0000\u0000\u0000\u0584\u0582\u0001\u0000\u0000\u0000\u0584"+ - "\u0585\u0001\u0000\u0000\u0000\u0585\u0587\u0001\u0000\u0000\u0000\u0586"+ - "\u0575\u0001\u0000\u0000\u0000\u0586\u0580\u0001\u0000\u0000\u0000\u0587"+ - "\u0125\u0001\u0000\u0000\u0000\u0588\u058b\u0003\u0120\u0087\u0000\u0589"+ - "\u058c\u0003\u00baT\u0000\u058a\u058c\u0003\u00c8[\u0000\u058b\u0589\u0001"+ - "\u0000\u0000\u0000\u058b\u058a\u0001\u0000\u0000\u0000\u058c\u0590\u0001"+ - "\u0000\u0000\u0000\u058d\u058f\u0003\u00ca\\\u0000\u058e\u058d\u0001\u0000"+ - "\u0000\u0000\u058f\u0592\u0001\u0000\u0000\u0000\u0590\u058e\u0001\u0000"+ - "\u0000\u0000\u0590\u0591\u0001\u0000\u0000\u0000\u0591\u059a\u0001\u0000"+ - "\u0000\u0000\u0592\u0590\u0001\u0000\u0000\u0000\u0593\u0595\u0003\u0120"+ - "\u0087\u0000\u0594\u0596\u0003\u00b8S\u0000\u0595\u0594\u0001\u0000\u0000"+ - "\u0000\u0596\u0597\u0001\u0000\u0000\u0000\u0597\u0595\u0001\u0000\u0000"+ - "\u0000\u0597\u0598\u0001\u0000\u0000\u0000\u0598\u059a\u0001\u0000\u0000"+ - "\u0000\u0599\u0588\u0001\u0000\u0000\u0000\u0599\u0593\u0001\u0000\u0000"+ - "\u0000\u059a\u0127\u0001\u0000\u0000\u0000\u059b\u059c\u0005[\u0000\u0000"+ - "\u059c\u059d\u0001\u0000\u0000\u0000\u059d\u059e\u0006\u008b\u0004\u0000"+ - "\u059e\u059f\u0006\u008b\u0004\u0000\u059f\u0129\u0001\u0000\u0000\u0000"+ - "\u05a0\u05a1\u0005]\u0000\u0000\u05a1\u05a2\u0001\u0000\u0000\u0000\u05a2"+ - "\u05a3\u0006\u008c\u0011\u0000\u05a3\u05a4\u0006\u008c\u0011\u0000\u05a4"+ - "\u012b\u0001\u0000\u0000\u0000\u05a5\u05a6\u0005(\u0000\u0000\u05a6\u05a7"+ - "\u0001\u0000\u0000\u0000\u05a7\u05a8\u0006\u008d\u0004\u0000\u05a8\u05a9"+ - "\u0006\u008d\u0004\u0000\u05a9\u012d\u0001\u0000\u0000\u0000\u05aa\u05ab"+ - "\u0005)\u0000\u0000\u05ab\u05ac\u0001\u0000\u0000\u0000\u05ac\u05ad\u0006"+ - "\u008e\u0011\u0000\u05ad\u05ae\u0006\u008e\u0011\u0000\u05ae\u012f\u0001"+ - "\u0000\u0000\u0000\u05af\u05b3\u0003\u00baT\u0000\u05b0\u05b2\u0003\u00ca"+ - "\\\u0000\u05b1\u05b0\u0001\u0000\u0000\u0000\u05b2\u05b5\u0001\u0000\u0000"+ - "\u0000\u05b3\u05b1\u0001\u0000\u0000\u0000\u05b3\u05b4\u0001\u0000\u0000"+ - "\u0000\u05b4\u05c0\u0001\u0000\u0000\u0000\u05b5\u05b3\u0001\u0000\u0000"+ - "\u0000\u05b6\u05b9\u0003\u00c8[\u0000\u05b7\u05b9\u0003\u00c2X\u0000\u05b8"+ - "\u05b6\u0001\u0000\u0000\u0000\u05b8\u05b7\u0001\u0000\u0000\u0000\u05b9"+ - "\u05bb\u0001\u0000\u0000\u0000\u05ba\u05bc\u0003\u00ca\\\u0000\u05bb\u05ba"+ - "\u0001\u0000\u0000\u0000\u05bc\u05bd\u0001\u0000\u0000\u0000\u05bd\u05bb"+ - "\u0001\u0000\u0000\u0000\u05bd\u05be\u0001\u0000\u0000\u0000\u05be\u05c0"+ - "\u0001\u0000\u0000\u0000\u05bf\u05af\u0001\u0000\u0000\u0000\u05bf\u05b8"+ - "\u0001\u0000\u0000\u0000\u05c0\u0131\u0001\u0000\u0000\u0000\u05c1\u05c3"+ - "\u0003\u00c4Y\u0000\u05c2\u05c4\u0003\u00c6Z\u0000\u05c3\u05c2\u0001\u0000"+ - "\u0000\u0000\u05c4\u05c5\u0001\u0000\u0000\u0000\u05c5\u05c3\u0001\u0000"+ - "\u0000\u0000\u05c5\u05c6\u0001\u0000\u0000\u0000\u05c6\u05c7\u0001\u0000"+ - "\u0000\u0000\u05c7\u05c8\u0003\u00c4Y\u0000\u05c8\u0133\u0001\u0000\u0000"+ - "\u0000\u05c9\u05ca\u0003\u0132\u0090\u0000\u05ca\u0135\u0001\u0000\u0000"+ - "\u0000\u05cb\u05cc\u0003\u0012\u0000\u0000\u05cc\u05cd\u0001\u0000\u0000"+ - "\u0000\u05cd\u05ce\u0006\u0092\u0000\u0000\u05ce\u0137\u0001\u0000\u0000"+ - "\u0000\u05cf\u05d0\u0003\u0014\u0001\u0000\u05d0\u05d1\u0001\u0000\u0000"+ - "\u0000\u05d1\u05d2\u0006\u0093\u0000\u0000\u05d2\u0139\u0001\u0000\u0000"+ - "\u0000\u05d3\u05d4\u0003\u0016\u0002\u0000\u05d4\u05d5\u0001\u0000\u0000"+ - "\u0000\u05d5\u05d6\u0006\u0094\u0000\u0000\u05d6\u013b\u0001\u0000\u0000"+ - "\u0000\u05d7\u05d8\u0003\u00b6R\u0000\u05d8\u05d9\u0001\u0000\u0000\u0000"+ - "\u05d9\u05da\u0006\u0095\u0010\u0000\u05da\u05db\u0006\u0095\u0011\u0000"+ - "\u05db\u013d\u0001\u0000\u0000\u0000\u05dc\u05dd\u0003\u00dce\u0000\u05dd"+ - "\u05de\u0001\u0000\u0000\u0000\u05de\u05df\u0006\u0096(\u0000\u05df\u013f"+ - "\u0001\u0000\u0000\u0000\u05e0\u05e1\u0003\u00dad\u0000\u05e1\u05e2\u0001"+ - "\u0000\u0000\u0000\u05e2\u05e3\u0006\u0097)\u0000\u05e3\u0141\u0001\u0000"+ - "\u0000\u0000\u05e4\u05e5\u0003\u00e0g\u0000\u05e5\u05e6\u0001\u0000\u0000"+ - "\u0000\u05e6\u05e7\u0006\u0098\u0016\u0000\u05e7\u0143\u0001\u0000\u0000"+ - "\u0000\u05e8\u05e9\u0003\u00d6b\u0000\u05e9\u05ea\u0001\u0000\u0000\u0000"+ - "\u05ea\u05eb\u0006\u0099\u001f\u0000\u05eb\u0145\u0001\u0000\u0000\u0000"+ - "\u05ec\u05ed\u0007\u000f\u0000\u0000\u05ed\u05ee\u0007\u0007\u0000\u0000"+ - "\u05ee\u05ef\u0007\u000b\u0000\u0000\u05ef\u05f0\u0007\u0004\u0000\u0000"+ - "\u05f0\u05f1\u0007\u0010\u0000\u0000\u05f1\u05f2\u0007\u0004\u0000\u0000"+ - "\u05f2\u05f3\u0007\u000b\u0000\u0000\u05f3\u05f4\u0007\u0004\u0000\u0000"+ - "\u05f4\u0147\u0001\u0000\u0000\u0000\u05f5\u05f6\u0003\u012e\u008e\u0000"+ - "\u05f6\u05f7\u0001\u0000\u0000\u0000\u05f7\u05f8\u0006\u009b\u0012\u0000"+ - "\u05f8\u05f9\u0006\u009b\u0011\u0000\u05f9\u05fa\u0006\u009b\u0011\u0000"+ - "\u05fa\u0149\u0001\u0000\u0000\u0000\u05fb\u05fc\u0003\u012c\u008d\u0000"+ - "\u05fc\u05fd\u0001\u0000\u0000\u0000\u05fd\u05fe\u0006\u009c%\u0000\u05fe"+ - "\u05ff\u0006\u009c&\u0000\u05ff\u014b\u0001\u0000\u0000\u0000\u0600\u0604"+ - "\b!\u0000\u0000\u0601\u0602\u0005/\u0000\u0000\u0602\u0604\b\"\u0000\u0000"+ - "\u0603\u0600\u0001\u0000\u0000\u0000\u0603\u0601\u0001\u0000\u0000\u0000"+ - "\u0604\u014d\u0001\u0000\u0000\u0000\u0605\u0607\u0003\u014c\u009d\u0000"+ - "\u0606\u0605\u0001\u0000\u0000\u0000\u0607\u0608\u0001\u0000\u0000\u0000"+ - "\u0608\u0606\u0001\u0000\u0000\u0000\u0608\u0609\u0001\u0000\u0000\u0000"+ - "\u0609\u014f\u0001\u0000\u0000\u0000\u060a\u060b\u0003\u014e\u009e\u0000"+ - "\u060b\u060c\u0001\u0000\u0000\u0000\u060c\u060d\u0006\u009f*\u0000\u060d"+ - "\u0151\u0001\u0000\u0000\u0000\u060e\u060f\u0003\u00cc]\u0000\u060f\u0610"+ - "\u0001\u0000\u0000\u0000\u0610\u0611\u0006\u00a0\u001e\u0000\u0611\u0153"+ - "\u0001\u0000\u0000\u0000\u0612\u0613\u0003\u0012\u0000\u0000\u0613\u0614"+ - "\u0001\u0000\u0000\u0000\u0614\u0615\u0006\u00a1\u0000\u0000\u0615\u0155"+ - "\u0001\u0000\u0000\u0000\u0616\u0617\u0003\u0014\u0001\u0000\u0617\u0618"+ - "\u0001\u0000\u0000\u0000\u0618\u0619\u0006\u00a2\u0000\u0000\u0619\u0157"+ - "\u0001\u0000\u0000\u0000\u061a\u061b\u0003\u0016\u0002\u0000\u061b\u061c"+ - "\u0001\u0000\u0000\u0000\u061c\u061d\u0006\u00a3\u0000\u0000\u061d\u0159"+ - "\u0001\u0000\u0000\u0000\u061e\u061f\u0003\u012c\u008d\u0000\u061f\u0620"+ - "\u0001\u0000\u0000\u0000\u0620\u0621\u0006\u00a4%\u0000\u0621\u0622\u0006"+ - "\u00a4&\u0000\u0622\u015b\u0001\u0000\u0000\u0000\u0623\u0624\u0003\u012e"+ - "\u008e\u0000\u0624\u0625\u0001\u0000\u0000\u0000\u0625\u0626\u0006\u00a5"+ - "\u0012\u0000\u0626\u0627\u0006\u00a5\u0011\u0000\u0627\u0628\u0006\u00a5"+ - "\u0011\u0000\u0628\u015d\u0001\u0000\u0000\u0000\u0629\u062a\u0003\u00b6"+ - "R\u0000\u062a\u062b\u0001\u0000\u0000\u0000\u062b\u062c\u0006\u00a6\u0010"+ - "\u0000\u062c\u062d\u0006\u00a6\u0011\u0000\u062d\u015f\u0001\u0000\u0000"+ - "\u0000\u062e\u062f\u0003\u0016\u0002\u0000\u062f\u0630\u0001\u0000\u0000"+ - "\u0000\u0630\u0631\u0006\u00a7\u0000\u0000\u0631\u0161\u0001\u0000\u0000"+ - "\u0000\u0632\u0633\u0003\u0012\u0000\u0000\u0633\u0634\u0001\u0000\u0000"+ - "\u0000\u0634\u0635\u0006\u00a8\u0000\u0000\u0635\u0163\u0001\u0000\u0000"+ - "\u0000\u0636\u0637\u0003\u0014\u0001\u0000\u0637\u0638\u0001\u0000\u0000"+ - "\u0000\u0638\u0639\u0006\u00a9\u0000\u0000\u0639\u0165\u0001\u0000\u0000"+ - "\u0000\u063a\u063b\u0003\u00b6R\u0000\u063b\u063c\u0001\u0000\u0000\u0000"+ - "\u063c\u063d\u0006\u00aa\u0010\u0000\u063d\u063e\u0006\u00aa\u0011\u0000"+ - "\u063e\u0167\u0001\u0000\u0000\u0000\u063f\u0640\u0003\u012e\u008e\u0000"+ - "\u0640\u0641\u0001\u0000\u0000\u0000\u0641\u0642\u0006\u00ab\u0012\u0000"+ - "\u0642\u0643\u0006\u00ab\u0011\u0000\u0643\u0644\u0006\u00ab\u0011\u0000"+ - "\u0644\u0169\u0001\u0000\u0000\u0000\u0645\u0646\u0007\u0006\u0000\u0000"+ - "\u0646\u0647\u0007\f\u0000\u0000\u0647\u0648\u0007\t\u0000\u0000\u0648"+ - "\u0649\u0007\u0016\u0000\u0000\u0649\u064a\u0007\b\u0000\u0000\u064a\u016b"+ - "\u0001\u0000\u0000\u0000\u064b\u064c\u0007\u0011\u0000\u0000\u064c\u064d"+ - "\u0007\u0002\u0000\u0000\u064d\u064e\u0007\t\u0000\u0000\u064e\u064f\u0007"+ - "\f\u0000\u0000\u064f\u0650\u0007\u0007\u0000\u0000\u0650\u016d\u0001\u0000"+ - "\u0000\u0000\u0651\u0652\u0007\u0013\u0000\u0000\u0652\u0653\u0007\u0007"+ - "\u0000\u0000\u0653\u0654\u0007 \u0000\u0000\u0654\u016f\u0001\u0000\u0000"+ - "\u0000\u0655\u0656\u0003\u0102x\u0000\u0656\u0657\u0001\u0000\u0000\u0000"+ - "\u0657\u0658\u0006\u00af\u001c\u0000\u0658\u0659\u0006\u00af\u0011\u0000"+ - "\u0659\u065a\u0006\u00af\u0004\u0000\u065a\u0171\u0001\u0000\u0000\u0000"+ - "\u065b\u065c\u0003\u00e0g\u0000\u065c\u065d\u0001\u0000\u0000\u0000\u065d"+ - "\u065e\u0006\u00b0\u0016\u0000\u065e\u0173\u0001\u0000\u0000\u0000\u065f"+ - "\u0660\u0003\u00e4i\u0000\u0660\u0661\u0001\u0000\u0000\u0000\u0661\u0662"+ - "\u0006\u00b1\u0015\u0000\u0662\u0175\u0001\u0000\u0000\u0000\u0663\u0664"+ - "\u0003\u00fcu\u0000\u0664\u0665\u0001\u0000\u0000\u0000\u0665\u0666\u0006"+ - "\u00b2!\u0000\u0666\u0177\u0001\u0000\u0000\u0000\u0667\u0668\u0003\u0124"+ - "\u0089\u0000\u0668\u0669\u0001\u0000\u0000\u0000\u0669\u066a\u0006\u00b3"+ - "\"\u0000\u066a\u0179\u0001\u0000\u0000\u0000\u066b\u066c\u0003\u0120\u0087"+ - "\u0000\u066c\u066d\u0001\u0000\u0000\u0000\u066d\u066e\u0006\u00b4#\u0000"+ - "\u066e\u017b\u0001\u0000\u0000\u0000\u066f\u0670\u0003\u0126\u008a\u0000"+ - "\u0670\u0671\u0001\u0000\u0000\u0000\u0671\u0672\u0006\u00b5$\u0000\u0672"+ - "\u017d\u0001\u0000\u0000\u0000\u0673\u0674\u0003\u00d8c\u0000\u0674\u0675"+ - "\u0001\u0000\u0000\u0000\u0675\u0676\u0006\u00b6+\u0000\u0676\u017f\u0001"+ - "\u0000\u0000\u0000\u0677\u0678\u0003\u0134\u0091\u0000\u0678\u0679\u0001"+ - "\u0000\u0000\u0000\u0679\u067a\u0006\u00b7\u0019\u0000\u067a\u0181\u0001"+ - "\u0000\u0000\u0000\u067b\u067c\u0003\u0130\u008f\u0000\u067c\u067d\u0001"+ - "\u0000\u0000\u0000\u067d\u067e\u0006\u00b8\u001a\u0000\u067e\u0183\u0001"+ - "\u0000\u0000\u0000\u067f\u0680\u0003\u0012\u0000\u0000\u0680\u0681\u0001"+ - "\u0000\u0000\u0000\u0681\u0682\u0006\u00b9\u0000\u0000\u0682\u0185\u0001"+ - "\u0000\u0000\u0000\u0683\u0684\u0003\u0014\u0001\u0000\u0684\u0685\u0001"+ - "\u0000\u0000\u0000\u0685\u0686\u0006\u00ba\u0000\u0000\u0686\u0187\u0001"+ - "\u0000\u0000\u0000\u0687\u0688\u0003\u0016\u0002\u0000\u0688\u0689\u0001"+ - "\u0000\u0000\u0000\u0689\u068a\u0006\u00bb\u0000\u0000\u068a\u0189\u0001"+ - "\u0000\u0000\u0000\u068b\u068c\u0007\u0011\u0000\u0000\u068c\u068d\u0007"+ - "\u000b\u0000\u0000\u068d\u068e\u0007\u0004\u0000\u0000\u068e\u068f\u0007"+ - "\u000b\u0000\u0000\u068f\u0690\u0007\u0011\u0000\u0000\u0690\u0691\u0001"+ - "\u0000\u0000\u0000\u0691\u0692\u0006\u00bc\u0011\u0000\u0692\u0693\u0006"+ - "\u00bc\u0004\u0000\u0693\u018b\u0001\u0000\u0000\u0000\u0694\u0695\u0003"+ - "\u0012\u0000\u0000\u0695\u0696\u0001\u0000\u0000\u0000\u0696\u0697\u0006"+ - "\u00bd\u0000\u0000\u0697\u018d\u0001\u0000\u0000\u0000\u0698\u0699\u0003"+ - "\u0014\u0001\u0000\u0699\u069a\u0001\u0000\u0000\u0000\u069a\u069b\u0006"+ - "\u00be\u0000\u0000\u069b\u018f\u0001\u0000\u0000\u0000\u069c\u069d\u0003"+ - "\u0016\u0002\u0000\u069d\u069e\u0001\u0000\u0000\u0000\u069e\u069f\u0006"+ - "\u00bf\u0000\u0000\u069f\u0191\u0001\u0000\u0000\u0000\u06a0\u06a1\u0003"+ - "\u00b6R\u0000\u06a1\u06a2\u0001\u0000\u0000\u0000\u06a2\u06a3\u0006\u00c0"+ - "\u0010\u0000\u06a3\u06a4\u0006\u00c0\u0011\u0000\u06a4\u0193\u0001\u0000"+ - "\u0000\u0000\u06a5\u06a6\u0007#\u0000\u0000\u06a6\u06a7\u0007\t\u0000"+ - "\u0000\u06a7\u06a8\u0007\n\u0000\u0000\u06a8\u06a9\u0007\u0005\u0000\u0000"+ - "\u06a9\u0195\u0001\u0000\u0000\u0000\u06aa\u06ab\u0003\u0220\u0107\u0000"+ - "\u06ab\u06ac\u0001\u0000\u0000\u0000\u06ac\u06ad\u0006\u00c2\u0014\u0000"+ - "\u06ad\u0197\u0001\u0000\u0000\u0000\u06ae\u06af\u0003\u00f8s\u0000\u06af"+ - "\u06b0\u0001\u0000\u0000\u0000\u06b0\u06b1\u0006\u00c3\u0013\u0000\u06b1"+ - "\u06b2\u0006\u00c3\u0011\u0000\u06b2\u06b3\u0006\u00c3\u0004\u0000\u06b3"+ - "\u0199\u0001\u0000\u0000\u0000\u06b4\u06b5\u0007\u0016\u0000\u0000\u06b5"+ - "\u06b6\u0007\u0011\u0000\u0000\u06b6\u06b7\u0007\n\u0000\u0000\u06b7\u06b8"+ - "\u0007\u0005\u0000\u0000\u06b8\u06b9\u0007\u0006\u0000\u0000\u06b9\u06ba"+ - "\u0001\u0000\u0000\u0000\u06ba\u06bb\u0006\u00c4\u0011\u0000\u06bb\u06bc"+ - "\u0006\u00c4\u0004\u0000\u06bc\u019b\u0001\u0000\u0000\u0000\u06bd\u06be"+ - "\u0003\u014e\u009e\u0000\u06be\u06bf\u0001\u0000\u0000\u0000\u06bf\u06c0"+ - "\u0006\u00c5*\u0000\u06c0\u019d\u0001\u0000\u0000\u0000\u06c1\u06c2\u0003"+ - "\u00cc]\u0000\u06c2\u06c3\u0001\u0000\u0000\u0000\u06c3\u06c4\u0006\u00c6"+ - "\u001e\u0000\u06c4\u019f\u0001\u0000\u0000\u0000\u06c5\u06c6\u0003\u00dc"+ - "e\u0000\u06c6\u06c7\u0001\u0000\u0000\u0000\u06c7\u06c8\u0006\u00c7(\u0000"+ - "\u06c8\u01a1\u0001\u0000\u0000\u0000\u06c9\u06ca\u0003\u0012\u0000\u0000"+ - "\u06ca\u06cb\u0001\u0000\u0000\u0000\u06cb\u06cc\u0006\u00c8\u0000\u0000"+ - "\u06cc\u01a3\u0001\u0000\u0000\u0000\u06cd\u06ce\u0003\u0014\u0001\u0000"+ - "\u06ce\u06cf\u0001\u0000\u0000\u0000\u06cf\u06d0\u0006\u00c9\u0000\u0000"+ - "\u06d0\u01a5\u0001\u0000\u0000\u0000\u06d1\u06d2\u0003\u0016\u0002\u0000"+ - "\u06d2\u06d3\u0001\u0000\u0000\u0000\u06d3\u06d4\u0006\u00ca\u0000\u0000"+ - "\u06d4\u01a7\u0001\u0000\u0000\u0000\u06d5\u06d6\u0003\u00b6R\u0000\u06d6"+ - "\u06d7\u0001\u0000\u0000\u0000\u06d7\u06d8\u0006\u00cb\u0010\u0000\u06d8"+ - "\u06d9\u0006\u00cb\u0011\u0000\u06d9\u01a9\u0001\u0000\u0000\u0000\u06da"+ - "\u06db\u0003\u012e\u008e\u0000\u06db\u06dc\u0001\u0000\u0000\u0000\u06dc"+ - "\u06dd\u0006\u00cc\u0012\u0000\u06dd\u06de\u0006\u00cc\u0011\u0000\u06de"+ - "\u06df\u0006\u00cc\u0011\u0000\u06df\u01ab\u0001\u0000\u0000\u0000\u06e0"+ - "\u06e1\u0003\u00dce\u0000\u06e1\u06e2\u0001\u0000\u0000\u0000\u06e2\u06e3"+ - "\u0006\u00cd(\u0000\u06e3\u01ad\u0001\u0000\u0000\u0000\u06e4\u06e5\u0003"+ - "\u00e0g\u0000\u06e5\u06e6\u0001\u0000\u0000\u0000\u06e6\u06e7\u0006\u00ce"+ - "\u0016\u0000\u06e7\u01af\u0001\u0000\u0000\u0000\u06e8\u06e9\u0003\u00e4"+ - "i\u0000\u06e9\u06ea\u0001\u0000\u0000\u0000\u06ea\u06eb\u0006\u00cf\u0015"+ - "\u0000\u06eb\u01b1\u0001\u0000\u0000\u0000\u06ec\u06ed\u0003\u00f8s\u0000"+ - "\u06ed\u06ee\u0001\u0000\u0000\u0000\u06ee\u06ef\u0006\u00d0\u0013\u0000"+ - "\u06ef\u06f0\u0006\u00d0,\u0000\u06f0\u01b3\u0001\u0000\u0000\u0000\u06f1"+ - "\u06f2\u0003\u014e\u009e\u0000\u06f2\u06f3\u0001\u0000\u0000\u0000\u06f3"+ - "\u06f4\u0006\u00d1*\u0000\u06f4\u01b5\u0001\u0000\u0000\u0000\u06f5\u06f6"+ - "\u0003\u00cc]\u0000\u06f6\u06f7\u0001\u0000\u0000\u0000\u06f7\u06f8\u0006"+ - "\u00d2\u001e\u0000\u06f8\u01b7\u0001\u0000\u0000\u0000\u06f9\u06fa\u0003"+ - "\u0012\u0000\u0000\u06fa\u06fb\u0001\u0000\u0000\u0000\u06fb\u06fc\u0006"+ - "\u00d3\u0000\u0000\u06fc\u01b9\u0001\u0000\u0000\u0000\u06fd\u06fe\u0003"+ - "\u0014\u0001\u0000\u06fe\u06ff\u0001\u0000\u0000\u0000\u06ff\u0700\u0006"+ - "\u00d4\u0000\u0000\u0700\u01bb\u0001\u0000\u0000\u0000\u0701\u0702\u0003"+ - "\u0016\u0002\u0000\u0702\u0703\u0001\u0000\u0000\u0000\u0703\u0704\u0006"+ - "\u00d5\u0000\u0000\u0704\u01bd\u0001\u0000\u0000\u0000\u0705\u0706\u0003"+ - "\u00b6R\u0000\u0706\u0707\u0001\u0000\u0000\u0000\u0707\u0708\u0006\u00d6"+ - "\u0010\u0000\u0708\u0709\u0006\u00d6\u0011\u0000\u0709\u070a\u0006\u00d6"+ - "\u0011\u0000\u070a\u01bf\u0001\u0000\u0000\u0000\u070b\u070c\u0003\u012e"+ - "\u008e\u0000\u070c\u070d\u0001\u0000\u0000\u0000\u070d\u070e\u0006\u00d7"+ - "\u0012\u0000\u070e\u070f\u0006\u00d7\u0011\u0000\u070f\u0710\u0006\u00d7"+ - "\u0011\u0000\u0710\u0711\u0006\u00d7\u0011\u0000\u0711\u01c1\u0001\u0000"+ - "\u0000\u0000\u0712\u0713\u0003\u00e0g\u0000\u0713\u0714\u0001\u0000\u0000"+ - "\u0000\u0714\u0715\u0006\u00d8\u0016\u0000\u0715\u01c3\u0001\u0000\u0000"+ - "\u0000\u0716\u0717\u0003\u00e4i\u0000\u0717\u0718\u0001\u0000\u0000\u0000"+ - "\u0718\u0719\u0006\u00d9\u0015\u0000\u0719\u01c5\u0001\u0000\u0000\u0000"+ - "\u071a\u071b\u0003\u0202\u00f8\u0000\u071b\u071c\u0001\u0000\u0000\u0000"+ - "\u071c\u071d\u0006\u00da \u0000\u071d\u01c7\u0001\u0000\u0000\u0000\u071e"+ - "\u071f\u0003\u0012\u0000\u0000\u071f\u0720\u0001\u0000\u0000\u0000\u0720"+ - "\u0721\u0006\u00db\u0000\u0000\u0721\u01c9\u0001\u0000\u0000\u0000\u0722"+ - "\u0723\u0003\u0014\u0001\u0000\u0723\u0724\u0001\u0000\u0000\u0000\u0724"+ - "\u0725\u0006\u00dc\u0000\u0000\u0725\u01cb\u0001\u0000\u0000\u0000\u0726"+ - "\u0727\u0003\u0016\u0002\u0000\u0727\u0728\u0001\u0000\u0000\u0000\u0728"+ - "\u0729\u0006\u00dd\u0000\u0000\u0729\u01cd\u0001\u0000\u0000\u0000\u072a"+ - "\u072b\u0003\u00b6R\u0000\u072b\u072c\u0001\u0000\u0000\u0000\u072c\u072d"+ - "\u0006\u00de\u0010\u0000\u072d\u072e\u0006\u00de\u0011\u0000\u072e\u01cf"+ - "\u0001\u0000\u0000\u0000\u072f\u0730\u0003\u012e\u008e\u0000\u0730\u0731"+ - "\u0001\u0000\u0000\u0000\u0731\u0732\u0006\u00df\u0012\u0000\u0732\u0733"+ - "\u0006\u00df\u0011\u0000\u0733\u0734\u0006\u00df\u0011\u0000\u0734\u01d1"+ - "\u0001\u0000\u0000\u0000\u0735\u0736\u0003\u0128\u008b\u0000\u0736\u0737"+ - "\u0001\u0000\u0000\u0000\u0737\u0738\u0006\u00e0\u0017\u0000\u0738\u01d3"+ - "\u0001\u0000\u0000\u0000\u0739\u073a\u0003\u012a\u008c\u0000\u073a\u073b"+ - "\u0001\u0000\u0000\u0000\u073b\u073c\u0006\u00e1\u0018\u0000\u073c\u01d5"+ - "\u0001\u0000\u0000\u0000\u073d\u073e\u0003\u00e4i\u0000\u073e\u073f\u0001"+ - "\u0000\u0000\u0000\u073f\u0740\u0006\u00e2\u0015\u0000\u0740\u01d7\u0001"+ - "\u0000\u0000\u0000\u0741\u0742\u0003\u00fcu\u0000\u0742\u0743\u0001\u0000"+ - "\u0000\u0000\u0743\u0744\u0006\u00e3!\u0000\u0744\u01d9\u0001\u0000\u0000"+ - "\u0000\u0745\u0746\u0003\u0124\u0089\u0000\u0746\u0747\u0001\u0000\u0000"+ - "\u0000\u0747\u0748\u0006\u00e4\"\u0000\u0748\u01db\u0001\u0000\u0000\u0000"+ - "\u0749\u074a\u0003\u0120\u0087\u0000\u074a\u074b\u0001\u0000\u0000\u0000"+ - "\u074b\u074c\u0006\u00e5#\u0000\u074c\u01dd\u0001\u0000\u0000\u0000\u074d"+ - "\u074e\u0003\u0126\u008a\u0000\u074e\u074f\u0001\u0000\u0000\u0000\u074f"+ - "\u0750\u0006\u00e6$\u0000\u0750\u01df\u0001\u0000\u0000\u0000\u0751\u0752"+ - "\u0003\u0134\u0091\u0000\u0752\u0753\u0001\u0000\u0000\u0000\u0753\u0754"+ - "\u0006\u00e7\u0019\u0000\u0754\u01e1\u0001\u0000\u0000\u0000\u0755\u0756"+ - "\u0003\u0130\u008f\u0000\u0756\u0757\u0001\u0000\u0000\u0000\u0757\u0758"+ - "\u0006\u00e8\u001a\u0000\u0758\u01e3\u0001\u0000\u0000\u0000\u0759\u075a"+ - "\u0003\u0012\u0000\u0000\u075a\u075b\u0001\u0000\u0000\u0000\u075b\u075c"+ - "\u0006\u00e9\u0000\u0000\u075c\u01e5\u0001\u0000\u0000\u0000\u075d\u075e"+ - "\u0003\u0014\u0001\u0000\u075e\u075f\u0001\u0000\u0000\u0000\u075f\u0760"+ - "\u0006\u00ea\u0000\u0000\u0760\u01e7\u0001\u0000\u0000\u0000\u0761\u0762"+ - "\u0003\u0016\u0002\u0000\u0762\u0763\u0001\u0000\u0000\u0000\u0763\u0764"+ - "\u0006\u00eb\u0000\u0000\u0764\u01e9\u0001\u0000\u0000\u0000\u0765\u0766"+ - "\u0003\u00b6R\u0000\u0766\u0767\u0001\u0000\u0000\u0000\u0767\u0768\u0006"+ - "\u00ec\u0010\u0000\u0768\u0769\u0006\u00ec\u0011\u0000\u0769\u01eb\u0001"+ - "\u0000\u0000\u0000\u076a\u076b\u0003\u012e\u008e\u0000\u076b\u076c\u0001"+ - "\u0000\u0000\u0000\u076c\u076d\u0006\u00ed\u0012\u0000\u076d\u076e\u0006"+ - "\u00ed\u0011\u0000\u076e\u076f\u0006\u00ed\u0011\u0000\u076f\u01ed\u0001"+ - "\u0000\u0000\u0000\u0770\u0771\u0003\u00e4i\u0000\u0771\u0772\u0001\u0000"+ - "\u0000\u0000\u0772\u0773\u0006\u00ee\u0015\u0000\u0773\u01ef\u0001\u0000"+ - "\u0000\u0000\u0774\u0775\u0003\u0128\u008b\u0000\u0775\u0776\u0001\u0000"+ - "\u0000\u0000\u0776\u0777\u0006\u00ef\u0017\u0000\u0777\u01f1\u0001\u0000"+ - "\u0000\u0000\u0778\u0779\u0003\u012a\u008c\u0000\u0779\u077a\u0001\u0000"+ - "\u0000\u0000\u077a\u077b\u0006\u00f0\u0018\u0000\u077b\u01f3\u0001\u0000"+ - "\u0000\u0000\u077c\u077d\u0003\u00e0g\u0000\u077d\u077e\u0001\u0000\u0000"+ - "\u0000\u077e\u077f\u0006\u00f1\u0016\u0000\u077f\u01f5\u0001\u0000\u0000"+ - "\u0000\u0780\u0781\u0003\u00fcu\u0000\u0781\u0782\u0001\u0000\u0000\u0000"+ - "\u0782\u0783\u0006\u00f2!\u0000\u0783\u01f7\u0001\u0000\u0000\u0000\u0784"+ - "\u0785\u0003\u0124\u0089\u0000\u0785\u0786\u0001\u0000\u0000\u0000\u0786"+ - "\u0787\u0006\u00f3\"\u0000\u0787\u01f9\u0001\u0000\u0000\u0000\u0788\u0789"+ - "\u0003\u0120\u0087\u0000\u0789\u078a\u0001\u0000\u0000\u0000\u078a\u078b"+ - "\u0006\u00f4#\u0000\u078b\u01fb\u0001\u0000\u0000\u0000\u078c\u078d\u0003"+ - "\u0126\u008a\u0000\u078d\u078e\u0001\u0000\u0000\u0000\u078e\u078f\u0006"+ - "\u00f5$\u0000\u078f\u01fd\u0001\u0000\u0000\u0000\u0790\u0795\u0003\u00ba"+ - "T\u0000\u0791\u0795\u0003\u00b8S\u0000\u0792\u0795\u0003\u00c8[\u0000"+ - "\u0793\u0795\u0003\u0116\u0082\u0000\u0794\u0790\u0001\u0000\u0000\u0000"+ - "\u0794\u0791\u0001\u0000\u0000\u0000\u0794\u0792\u0001\u0000\u0000\u0000"+ - "\u0794\u0793\u0001\u0000\u0000\u0000\u0795\u01ff\u0001\u0000\u0000\u0000"+ - "\u0796\u0799\u0003\u00baT\u0000\u0797\u0799\u0003\u0116\u0082\u0000\u0798"+ - "\u0796\u0001\u0000\u0000\u0000\u0798\u0797\u0001\u0000\u0000\u0000\u0799"+ - "\u079d\u0001\u0000\u0000\u0000\u079a\u079c\u0003\u01fe\u00f6\u0000\u079b"+ - "\u079a\u0001\u0000\u0000\u0000\u079c\u079f\u0001\u0000\u0000\u0000\u079d"+ - "\u079b\u0001\u0000\u0000\u0000\u079d\u079e\u0001\u0000\u0000\u0000\u079e"+ - "\u07aa\u0001\u0000\u0000\u0000\u079f\u079d\u0001\u0000\u0000\u0000\u07a0"+ - "\u07a3\u0003\u00c8[\u0000\u07a1\u07a3\u0003\u00c2X\u0000\u07a2\u07a0\u0001"+ - "\u0000\u0000\u0000\u07a2\u07a1\u0001\u0000\u0000\u0000\u07a3\u07a5\u0001"+ - "\u0000\u0000\u0000\u07a4\u07a6\u0003\u01fe\u00f6\u0000\u07a5\u07a4\u0001"+ - "\u0000\u0000\u0000\u07a6\u07a7\u0001\u0000\u0000\u0000\u07a7\u07a5\u0001"+ - "\u0000\u0000\u0000\u07a7\u07a8\u0001\u0000\u0000\u0000\u07a8\u07aa\u0001"+ - "\u0000\u0000\u0000\u07a9\u0798\u0001\u0000\u0000\u0000\u07a9\u07a2\u0001"+ - "\u0000\u0000\u0000\u07aa\u0201\u0001\u0000\u0000\u0000\u07ab\u07ae\u0003"+ - "\u0200\u00f7\u0000\u07ac\u07ae\u0003\u0132\u0090\u0000\u07ad\u07ab\u0001"+ - "\u0000\u0000\u0000\u07ad\u07ac\u0001\u0000\u0000\u0000\u07ae\u07af\u0001"+ - "\u0000\u0000\u0000\u07af\u07ad\u0001\u0000\u0000\u0000\u07af\u07b0\u0001"+ - "\u0000\u0000\u0000\u07b0\u0203\u0001\u0000\u0000\u0000\u07b1\u07b2\u0003"+ - "\u0012\u0000\u0000\u07b2\u07b3\u0001\u0000\u0000\u0000\u07b3\u07b4\u0006"+ - "\u00f9\u0000\u0000\u07b4\u0205\u0001\u0000\u0000\u0000\u07b5\u07b6\u0003"+ - "\u0014\u0001\u0000\u07b6\u07b7\u0001\u0000\u0000\u0000\u07b7\u07b8\u0006"+ - "\u00fa\u0000\u0000\u07b8\u0207\u0001\u0000\u0000\u0000\u07b9\u07ba\u0003"+ - "\u0016\u0002\u0000\u07ba\u07bb\u0001\u0000\u0000\u0000\u07bb\u07bc\u0006"+ - "\u00fb\u0000\u0000\u07bc\u0209\u0001\u0000\u0000\u0000\u07bd\u07be\u0003"+ - "\u00b6R\u0000\u07be\u07bf\u0001\u0000\u0000\u0000\u07bf\u07c0\u0006\u00fc"+ - "\u0010\u0000\u07c0\u07c1\u0006\u00fc\u0011\u0000\u07c1\u020b\u0001\u0000"+ - "\u0000\u0000\u07c2\u07c3\u0003\u012e\u008e\u0000\u07c3\u07c4\u0001\u0000"+ - "\u0000\u0000\u07c4\u07c5\u0006\u00fd\u0012\u0000\u07c5\u07c6\u0006\u00fd"+ - "\u0011\u0000\u07c6\u07c7\u0006\u00fd\u0011\u0000\u07c7\u020d\u0001\u0000"+ - "\u0000\u0000\u07c8\u07c9\u0003\u0128\u008b\u0000\u07c9\u07ca\u0001\u0000"+ - "\u0000\u0000\u07ca\u07cb\u0006\u00fe\u0017\u0000\u07cb\u020f\u0001\u0000"+ - "\u0000\u0000\u07cc\u07cd\u0003\u012a\u008c\u0000\u07cd\u07ce\u0001\u0000"+ - "\u0000\u0000\u07ce\u07cf\u0006\u00ff\u0018\u0000\u07cf\u0211\u0001\u0000"+ - "\u0000\u0000\u07d0\u07d1\u0003\u00d6b\u0000\u07d1\u07d2\u0001\u0000\u0000"+ - "\u0000\u07d2\u07d3\u0006\u0100\u001f\u0000\u07d3\u0213\u0001\u0000\u0000"+ - "\u0000\u07d4\u07d5\u0003\u00e0g\u0000\u07d5\u07d6\u0001\u0000\u0000\u0000"+ - "\u07d6\u07d7\u0006\u0101\u0016\u0000\u07d7\u0215\u0001\u0000\u0000\u0000"+ - "\u07d8\u07d9\u0003\u00e4i\u0000\u07d9\u07da\u0001\u0000\u0000\u0000\u07da"+ - "\u07db\u0006\u0102\u0015\u0000\u07db\u0217\u0001\u0000\u0000\u0000\u07dc"+ - "\u07dd\u0003\u00fcu\u0000\u07dd\u07de\u0001\u0000\u0000\u0000\u07de\u07df"+ - "\u0006\u0103!\u0000\u07df\u0219\u0001\u0000\u0000\u0000\u07e0\u07e1\u0003"+ - "\u0124\u0089\u0000\u07e1\u07e2\u0001\u0000\u0000\u0000\u07e2\u07e3\u0006"+ - "\u0104\"\u0000\u07e3\u021b\u0001\u0000\u0000\u0000\u07e4\u07e5\u0003\u0120"+ - "\u0087\u0000\u07e5\u07e6\u0001\u0000\u0000\u0000\u07e6\u07e7\u0006\u0105"+ - "#\u0000\u07e7\u021d\u0001\u0000\u0000\u0000\u07e8\u07e9\u0003\u0126\u008a"+ - "\u0000\u07e9\u07ea\u0001\u0000\u0000\u0000\u07ea\u07eb\u0006\u0106$\u0000"+ - "\u07eb\u021f\u0001\u0000\u0000\u0000\u07ec\u07ed\u0007\u0004\u0000\u0000"+ - "\u07ed\u07ee\u0007\u0011\u0000\u0000\u07ee\u0221\u0001\u0000\u0000\u0000"+ - "\u07ef\u07f0\u0003\u0202\u00f8\u0000\u07f0\u07f1\u0001\u0000\u0000\u0000"+ - "\u07f1\u07f2\u0006\u0108 \u0000\u07f2\u0223\u0001\u0000\u0000\u0000\u07f3"+ - "\u07f4\u0003\u0012\u0000\u0000\u07f4\u07f5\u0001\u0000\u0000\u0000\u07f5"+ - "\u07f6\u0006\u0109\u0000\u0000\u07f6\u0225\u0001\u0000\u0000\u0000\u07f7"+ - "\u07f8\u0003\u0014\u0001\u0000\u07f8\u07f9\u0001\u0000\u0000\u0000\u07f9"+ - "\u07fa\u0006\u010a\u0000\u0000\u07fa\u0227\u0001\u0000\u0000\u0000\u07fb"+ - "\u07fc\u0003\u0016\u0002\u0000\u07fc\u07fd\u0001\u0000\u0000\u0000\u07fd"+ - "\u07fe\u0006\u010b\u0000\u0000\u07fe\u0229\u0001\u0000\u0000\u0000\u07ff"+ - "\u0800\u0003\u0100w\u0000\u0800\u0801\u0001\u0000\u0000\u0000\u0801\u0802"+ - "\u0006\u010c-\u0000\u0802\u022b\u0001\u0000\u0000\u0000\u0803\u0804\u0003"+ - "\u00e6j\u0000\u0804\u0805\u0001\u0000\u0000\u0000\u0805\u0806\u0006\u010d"+ - ".\u0000\u0806\u022d\u0001\u0000\u0000\u0000\u0807\u0808\u0003\u00f4q\u0000"+ - "\u0808\u0809\u0001\u0000\u0000\u0000\u0809\u080a\u0006\u010e/\u0000\u080a"+ - "\u022f\u0001\u0000\u0000\u0000\u080b\u080c\u0003\u00def\u0000\u080c\u080d"+ - "\u0001\u0000\u0000\u0000\u080d\u080e\u0006\u010f0\u0000\u080e\u080f\u0006"+ - "\u010f\u0011\u0000\u080f\u0231\u0001\u0000\u0000\u0000\u0810\u0811\u0003"+ - "\u00d6b\u0000\u0811\u0812\u0001\u0000\u0000\u0000\u0812\u0813\u0006\u0110"+ - "\u001f\u0000\u0813\u0233\u0001\u0000\u0000\u0000\u0814\u0815\u0003\u00cc"+ - "]\u0000\u0815\u0816\u0001\u0000\u0000\u0000\u0816\u0817\u0006\u0111\u001e"+ - "\u0000\u0817\u0235\u0001\u0000\u0000\u0000\u0818\u0819\u0003\u0130\u008f"+ - "\u0000\u0819\u081a\u0001\u0000\u0000\u0000\u081a\u081b\u0006\u0112\u001a"+ - "\u0000\u081b\u0237\u0001\u0000\u0000\u0000\u081c\u081d\u0003\u0134\u0091"+ - "\u0000\u081d\u081e\u0001\u0000\u0000\u0000\u081e\u081f\u0006\u0113\u0019"+ - "\u0000\u081f\u0239\u0001\u0000\u0000\u0000\u0820\u0821\u0003\u00d0_\u0000"+ - "\u0821\u0822\u0001\u0000\u0000\u0000\u0822\u0823\u0006\u01141\u0000\u0823"+ - "\u023b\u0001\u0000\u0000\u0000\u0824\u0825\u0003\u00ce^\u0000\u0825\u0826"+ - "\u0001\u0000\u0000\u0000\u0826\u0827\u0006\u01152\u0000\u0827\u023d\u0001"+ - "\u0000\u0000\u0000\u0828\u0829\u0003\u00e0g\u0000\u0829\u082a\u0001\u0000"+ - "\u0000\u0000\u082a\u082b\u0006\u0116\u0016\u0000\u082b\u023f\u0001\u0000"+ - "\u0000\u0000\u082c\u082d\u0003\u00e4i\u0000\u082d\u082e\u0001\u0000\u0000"+ - "\u0000\u082e\u082f\u0006\u0117\u0015\u0000\u082f\u0241\u0001\u0000\u0000"+ - "\u0000\u0830\u0831\u0003\u00fcu\u0000\u0831\u0832\u0001\u0000\u0000\u0000"+ - "\u0832\u0833\u0006\u0118!\u0000\u0833\u0243\u0001\u0000\u0000\u0000\u0834"+ - "\u0835\u0003\u0124\u0089\u0000\u0835\u0836\u0001\u0000\u0000\u0000\u0836"+ - "\u0837\u0006\u0119\"\u0000\u0837\u0245\u0001\u0000\u0000\u0000\u0838\u0839"+ - "\u0003\u0120\u0087\u0000\u0839\u083a\u0001\u0000\u0000\u0000\u083a\u083b"+ - "\u0006\u011a#\u0000\u083b\u0247\u0001\u0000\u0000\u0000\u083c\u083d\u0003"+ - "\u0126\u008a\u0000\u083d\u083e\u0001\u0000\u0000\u0000\u083e\u083f\u0006"+ - "\u011b$\u0000\u083f\u0249\u0001\u0000\u0000\u0000\u0840\u0841\u0003\u0128"+ - "\u008b\u0000\u0841\u0842\u0001\u0000\u0000\u0000\u0842\u0843\u0006\u011c"+ - "\u0017\u0000\u0843\u024b\u0001\u0000\u0000\u0000\u0844\u0845\u0003\u012a"+ - "\u008c\u0000\u0845\u0846\u0001\u0000\u0000\u0000\u0846\u0847\u0006\u011d"+ - "\u0018\u0000\u0847\u024d\u0001\u0000\u0000\u0000\u0848\u0849\u0003\u0202"+ - "\u00f8\u0000\u0849\u084a\u0001\u0000\u0000\u0000\u084a\u084b\u0006\u011e"+ - " \u0000\u084b\u024f\u0001\u0000\u0000\u0000\u084c\u084d\u0003\u0012\u0000"+ - "\u0000\u084d\u084e\u0001\u0000\u0000\u0000\u084e\u084f\u0006\u011f\u0000"+ - "\u0000\u084f\u0251\u0001\u0000\u0000\u0000\u0850\u0851\u0003\u0014\u0001"+ - "\u0000\u0851\u0852\u0001\u0000\u0000\u0000\u0852\u0853\u0006\u0120\u0000"+ - "\u0000\u0853\u0253\u0001\u0000\u0000\u0000\u0854\u0855\u0003\u0016\u0002"+ - "\u0000\u0855\u0856\u0001\u0000\u0000\u0000\u0856\u0857\u0006\u0121\u0000"+ - "\u0000\u0857\u0255\u0001\u0000\u0000\u0000\u0858\u0859\u0003\u00b6R\u0000"+ - "\u0859\u085a\u0001\u0000\u0000\u0000\u085a\u085b\u0006\u0122\u0010\u0000"+ - "\u085b\u085c\u0006\u0122\u0011\u0000\u085c\u0257\u0001\u0000\u0000\u0000"+ - "\u085d\u085e\u0007\n\u0000\u0000\u085e\u085f\u0007\u0005\u0000\u0000\u085f"+ - "\u0860\u0007\u0015\u0000\u0000\u0860\u0861\u0007\t\u0000\u0000\u0861\u0259"+ - "\u0001\u0000\u0000\u0000\u0862\u0863\u0003\u0012\u0000\u0000\u0863\u0864"+ - "\u0001\u0000\u0000\u0000\u0864\u0865\u0006\u0124\u0000\u0000\u0865\u025b"+ - "\u0001\u0000\u0000\u0000\u0866\u0867\u0003\u0014\u0001\u0000\u0867\u0868"+ - "\u0001\u0000\u0000\u0000\u0868\u0869\u0006\u0125\u0000\u0000\u0869\u025d"+ - "\u0001\u0000\u0000\u0000\u086a\u086b\u0003\u0016\u0002\u0000\u086b\u086c"+ - "\u0001\u0000\u0000\u0000\u086c\u086d\u0006\u0126\u0000\u0000\u086d\u025f"+ - "\u0001\u0000\u0000\u0000F\u0000\u0001\u0002\u0003\u0004\u0005\u0006\u0007"+ - "\b\t\n\u000b\f\r\u000e\u000f\u0010\u0011\u0266\u026a\u026d\u0276\u0278"+ - "\u0283\u03a4\u03f9\u03fd\u0402\u0486\u048b\u0494\u049b\u04a0\u04a2\u04ad"+ - "\u04b5\u04b8\u04ba\u04bf\u04c4\u04ca\u04d1\u04d6\u04dc\u04df\u04e7\u04eb"+ - "\u0578\u057d\u0584\u0586\u058b\u0590\u0597\u0599\u05b3\u05b8\u05bd\u05bf"+ - "\u05c5\u0603\u0608\u0794\u0798\u079d\u07a2\u07a7\u07a9\u07ad\u07af3\u0000"+ - "\u0001\u0000\u0005\u0001\u0000\u0005\u0002\u0000\u0005\u0004\u0000\u0005"+ - "\u0005\u0000\u0005\u0006\u0000\u0005\u0007\u0000\u0005\b\u0000\u0005\t"+ - "\u0000\u0005\n\u0000\u0005\u000b\u0000\u0005\r\u0000\u0005\u000e\u0000"+ - "\u0005\u000f\u0000\u0005\u0010\u0000\u0005\u0011\u0000\u00072\u0000\u0004"+ - "\u0000\u0000\u0007c\u0000\u0007I\u0000\u0007\u008d\u0000\u0007?\u0000"+ - "\u0007=\u0000\u0007`\u0000\u0007a\u0000\u0007e\u0000\u0007d\u0000\u0005"+ - "\u0003\u0000\u0007N\u0000\u0007(\u0000\u00073\u0000\u00078\u0000\u0007"+ - "\u0089\u0000\u0007K\u0000\u0007^\u0000\u0007]\u0000\u0007_\u0000\u0007"+ - "b\u0000\u0005\u0000\u0000\u0007\u0011\u0000\u0007;\u0000\u0007:\u0000"+ - "\u0007j\u0000\u00079\u0000\u0005\f\u0000\u0007M\u0000\u0007@\u0000\u0007"+ - "G\u0000\u0007<\u0000\u00075\u0000\u00074\u0000"; + "\u00f5\u0001\u00f6\u0001\u00f6\u0001\u00f6\u0001\u00f6\u0001\u00f7\u0001"+ + "\u00f7\u0001\u00f7\u0001\u00f7\u0003\u00f7\u07c9\b\u00f7\u0001\u00f8\u0001"+ + "\u00f8\u0003\u00f8\u07cd\b\u00f8\u0001\u00f8\u0005\u00f8\u07d0\b\u00f8"+ + "\n\u00f8\f\u00f8\u07d3\t\u00f8\u0001\u00f8\u0001\u00f8\u0003\u00f8\u07d7"+ + "\b\u00f8\u0001\u00f8\u0004\u00f8\u07da\b\u00f8\u000b\u00f8\f\u00f8\u07db"+ + "\u0003\u00f8\u07de\b\u00f8\u0001\u00f9\u0001\u00f9\u0004\u00f9\u07e2\b"+ + "\u00f9\u000b\u00f9\f\u00f9\u07e3\u0001\u00fa\u0001\u00fa\u0001\u00fa\u0001"+ + "\u00fa\u0001\u00fb\u0001\u00fb\u0001\u00fb\u0001\u00fb\u0001\u00fc\u0001"+ + "\u00fc\u0001\u00fc\u0001\u00fc\u0001\u00fd\u0001\u00fd\u0005\u00fd\u07f4"+ + "\b\u00fd\n\u00fd\f\u00fd\u07f7\t\u00fd\u0001\u00fd\u0001\u00fd\u0004\u00fd"+ + "\u07fb\b\u00fd\u000b\u00fd\f\u00fd\u07fc\u0003\u00fd\u07ff\b\u00fd\u0001"+ + "\u00fe\u0001\u00fe\u0001\u00fe\u0001\u00fe\u0001\u00ff\u0001\u00ff\u0001"+ + "\u00ff\u0001\u00ff\u0001\u0100\u0001\u0100\u0001\u0100\u0001\u0100\u0001"+ + "\u0101\u0001\u0101\u0001\u0101\u0001\u0101\u0001\u0101\u0001\u0102\u0001"+ + "\u0102\u0001\u0102\u0001\u0102\u0001\u0102\u0001\u0102\u0001\u0103\u0001"+ + "\u0103\u0001\u0103\u0001\u0103\u0001\u0104\u0001\u0104\u0001\u0104\u0001"+ + "\u0104\u0001\u0105\u0001\u0105\u0001\u0105\u0001\u0105\u0001\u0106\u0001"+ + "\u0106\u0001\u0106\u0001\u0106\u0001\u0106\u0001\u0107\u0001\u0107\u0001"+ + "\u0107\u0004\u0107\u082c\b\u0107\u000b\u0107\f\u0107\u082d\u0001\u0108"+ + "\u0001\u0108\u0001\u0108\u0001\u0108\u0005\u0108\u0834\b\u0108\n\u0108"+ + "\f\u0108\u0837\t\u0108\u0001\u0108\u0001\u0108\u0001\u0108\u0001\u0108"+ + "\u0001\u0108\u0005\u0108\u083e\b\u0108\n\u0108\f\u0108\u0841\t\u0108\u0001"+ + "\u0108\u0001\u0108\u0001\u0108\u0005\u0108\u0846\b\u0108\n\u0108\f\u0108"+ + "\u0849\t\u0108\u0001\u0108\u0003\u0108\u084c\b\u0108\u0001\u0109\u0001"+ + "\u0109\u0005\u0109\u0850\b\u0109\n\u0109\f\u0109\u0853\t\u0109\u0001\u0109"+ + "\u0003\u0109\u0856\b\u0109\u0001\u0109\u0003\u0109\u0859\b\u0109\u0001"+ + "\u010a\u0001\u010a\u0001\u010a\u0001\u010a\u0001\u010a\u0001\u010a\u0001"+ + "\u010b\u0001\u010b\u0001\u010b\u0001\u010b\u0001\u010b\u0001\u010b\u0001"+ + "\u010b\u0001\u010b\u0001\u010c\u0001\u010c\u0001\u010c\u0001\u010c\u0001"+ + "\u010c\u0001\u010c\u0001\u010d\u0001\u010d\u0001\u010d\u0001\u010d\u0001"+ + "\u010e\u0001\u010e\u0001\u010e\u0001\u010e\u0001\u010f\u0001\u010f\u0001"+ + "\u010f\u0001\u010f\u0001\u0110\u0001\u0110\u0001\u0110\u0001\u0110\u0001"+ + "\u0110\u0001\u0111\u0001\u0111\u0001\u0111\u0001\u0111\u0001\u0111\u0001"+ + "\u0111\u0001\u0112\u0001\u0112\u0001\u0112\u0001\u0112\u0001\u0113\u0001"+ + "\u0113\u0001\u0113\u0001\u0113\u0001\u0114\u0001\u0114\u0001\u0114\u0001"+ + "\u0114\u0001\u0115\u0001\u0115\u0001\u0115\u0001\u0115\u0001\u0116\u0001"+ + "\u0116\u0001\u0116\u0001\u0116\u0001\u0117\u0001\u0117\u0001\u0117\u0001"+ + "\u0117\u0001\u0118\u0001\u0118\u0001\u0118\u0001\u0118\u0001\u0119\u0001"+ + "\u0119\u0001\u0119\u0001\u0119\u0001\u011a\u0001\u011a\u0001\u011a\u0001"+ + "\u011a\u0001\u011b\u0001\u011b\u0001\u011b\u0001\u011c\u0001\u011c\u0001"+ + "\u011c\u0001\u011c\u0001\u011d\u0001\u011d\u0001\u011d\u0001\u011d\u0001"+ + "\u011e\u0001\u011e\u0001\u011e\u0001\u011e\u0001\u011f\u0001\u011f\u0001"+ + "\u011f\u0001\u011f\u0001\u0120\u0001\u0120\u0001\u0120\u0001\u0120\u0001"+ + "\u0121\u0001\u0121\u0001\u0121\u0001\u0121\u0001\u0122\u0001\u0122\u0001"+ + "\u0122\u0001\u0122\u0001\u0123\u0001\u0123\u0001\u0123\u0001\u0123\u0001"+ + "\u0123\u0001\u0124\u0001\u0124\u0001\u0124\u0001\u0124\u0001\u0125\u0001"+ + "\u0125\u0001\u0125\u0001\u0125\u0001\u0126\u0001\u0126\u0001\u0126\u0001"+ + "\u0126\u0001\u0127\u0001\u0127\u0001\u0127\u0001\u0127\u0001\u0128\u0001"+ + "\u0128\u0001\u0128\u0001\u0128\u0001\u0129\u0001\u0129\u0001\u0129\u0001"+ + "\u0129\u0001\u012a\u0001\u012a\u0001\u012a\u0001\u012a\u0001\u012b\u0001"+ + "\u012b\u0001\u012b\u0001\u012b\u0001\u012c\u0001\u012c\u0001\u012c\u0001"+ + "\u012c\u0001\u012d\u0001\u012d\u0001\u012d\u0001\u012d\u0001\u012e\u0001"+ + "\u012e\u0001\u012e\u0001\u012e\u0001\u012f\u0001\u012f\u0001\u012f\u0001"+ + "\u012f\u0001\u0130\u0001\u0130\u0001\u0130\u0001\u0130\u0001\u0131\u0001"+ + "\u0131\u0001\u0131\u0001\u0131\u0001\u0132\u0001\u0132\u0001\u0132\u0001"+ + "\u0132\u0001\u0133\u0001\u0133\u0001\u0133\u0001\u0133\u0001\u0134\u0001"+ + "\u0134\u0001\u0134\u0001\u0134\u0001\u0135\u0001\u0135\u0001\u0135\u0001"+ + "\u0135\u0001\u0136\u0001\u0136\u0001\u0136\u0001\u0136\u0001\u0136\u0001"+ + "\u0137\u0001\u0137\u0001\u0137\u0001\u0137\u0001\u0137\u0001\u0138\u0001"+ + "\u0138\u0001\u0138\u0001\u0138\u0001\u0139\u0001\u0139\u0001\u0139\u0001"+ + "\u0139\u0001\u013a\u0001\u013a\u0001\u013a\u0001\u013a\u0002\u02a2\u04e1"+ + "\u0000\u013b\u0014\u0001\u0016\u0002\u0018\u0003\u001a\u0004\u001c\u0005"+ + "\u001e\u0006 \u0007\"\b$\t&\n(\u000b*\f,\r.\u000e0\u000f2\u00104\u0011"+ + "6\u00128\u0013:\u0014<\u0015>\u0016@\u0017B\u0018D\u0019F\u001aH\u001b"+ + "J\u001cL\u001dN\u001eP\u001fR T!V\"X#Z$\\%^\u0000`\u0000b\u0000d\u0000"+ + "f\u0000h\u0000j\u0000l\u0000n\u0000p\u0000r&t\'v(x\u0000z\u0000|\u0000"+ + "~\u0000\u0080\u0000\u0082)\u0084\u0000\u0086\u0000\u0088*\u008a+\u008c"+ + ",\u008e\u0000\u0090\u0000\u0092\u0000\u0094\u0000\u0096\u0000\u0098\u0000"+ + "\u009a\u0000\u009c\u0000\u009e\u0000\u00a0\u0000\u00a2\u0000\u00a4\u0000"+ + "\u00a6\u0000\u00a8\u0000\u00aa-\u00ac.\u00ae/\u00b0\u0000\u00b2\u0000"+ + "\u00b40\u00b61\u00b82\u00ba3\u00bc\u0000\u00be\u0000\u00c0\u0000\u00c2"+ + "\u0000\u00c4\u0000\u00c6\u0000\u00c8\u0000\u00ca\u0000\u00cc\u0000\u00ce"+ + "\u0000\u00d04\u00d25\u00d46\u00d67\u00d88\u00da9\u00dc:\u00de;\u00e0<"+ + "\u00e2=\u00e4>\u00e6?\u00e8@\u00eaA\u00ecB\u00eeC\u00f0D\u00f2E\u00f4"+ + "F\u00f6G\u00f8H\u00faI\u00fcJ\u00feK\u0100L\u0102M\u0104N\u0106O\u0108"+ + "P\u010aQ\u010cR\u010eS\u0110T\u0112U\u0114V\u0116W\u0118X\u011aY\u011c"+ + "Z\u011e[\u0120\\\u0122]\u0124^\u0126\u0000\u0128_\u012a`\u012ca\u012e"+ + "b\u0130c\u0132d\u0134e\u0136\u0000\u0138f\u013ag\u013ch\u013ei\u0140\u0000"+ + "\u0142\u0000\u0144\u0000\u0146\u0000\u0148\u0000\u014aj\u014c\u0000\u014e"+ + "\u0000\u0150\u0000\u0152k\u0154\u0000\u0156\u0000\u0158l\u015am\u015c"+ + "n\u015e\u0000\u0160\u0000\u0162\u0000\u0164o\u0166p\u0168q\u016a\u0000"+ + "\u016c\u0000\u016er\u0170s\u0172t\u0174\u0000\u0176\u0000\u0178\u0000"+ + "\u017a\u0000\u017c\u0000\u017e\u0000\u0180\u0000\u0182\u0000\u0184\u0000"+ + "\u0186\u0000\u0188u\u018av\u018cw\u018ex\u0190y\u0192z\u0194{\u0196\u0000"+ + "\u0198|\u019a\u0000\u019c\u0000\u019e}\u01a0\u0000\u01a2\u0000\u01a4\u0000"+ + "\u01a6~\u01a8\u007f\u01aa\u0080\u01ac\u0000\u01ae\u0000\u01b0\u0000\u01b2"+ + "\u0000\u01b4\u0000\u01b6\u0000\u01b8\u0000\u01ba\u0000\u01bc\u0081\u01be"+ + "\u0082\u01c0\u0083\u01c2\u0000\u01c4\u0000\u01c6\u0000\u01c8\u0000\u01ca"+ + "\u0000\u01cc\u0084\u01ce\u0085\u01d0\u0086\u01d2\u0000\u01d4\u0000\u01d6"+ + "\u0000\u01d8\u0000\u01da\u0000\u01dc\u0000\u01de\u0000\u01e0\u0000\u01e2"+ + "\u0000\u01e4\u0000\u01e6\u0000\u01e8\u0087\u01ea\u0088\u01ec\u0089\u01ee"+ + "\u0000\u01f0\u0000\u01f2\u0000\u01f4\u0000\u01f6\u0000\u01f8\u0000\u01fa"+ + "\u0000\u01fc\u0000\u01fe\u0000\u0200\u0000\u0202\u0000\u0204\u0000\u0206"+ + "\u008a\u0208\u008b\u020a\u008c\u020c\u008d\u020e\u008e\u0210\u0000\u0212"+ + "\u0000\u0214\u0000\u0216\u0000\u0218\u0000\u021a\u008f\u021c\u0090\u021e"+ + "\u0091\u0220\u0000\u0222\u0092\u0224\u0000\u0226\u0000\u0228\u0000\u022a"+ + "\u0000\u022c\u0000\u022e\u0093\u0230\u0094\u0232\u0095\u0234\u0000\u0236"+ + "\u0000\u0238\u0000\u023a\u0000\u023c\u0000\u023e\u0000\u0240\u0000\u0242"+ + "\u0000\u0244\u0000\u0246\u0000\u0248\u0000\u024a\u0096\u024c\u0000\u024e"+ + "\u0097\u0250\u0098\u0252\u0099\u0254\u0000\u0256\u0000\u0258\u0000\u025a"+ + "\u0000\u025c\u0000\u025e\u0000\u0260\u0000\u0262\u0000\u0264\u0000\u0266"+ + "\u0000\u0268\u0000\u026a\u0000\u026c\u0000\u026e\u0000\u0270\u0000\u0272"+ + "\u0000\u0274\u0000\u0276\u0000\u0278\u0000\u027a\u009a\u027c\u009b\u027e"+ + "\u009c\u0280\u0000\u0282\u009d\u0284\u009e\u0286\u009f\u0288\u00a0\u0014"+ + "\u0000\u0001\u0002\u0003\u0004\u0005\u0006\u0007\b\t\n\u000b\f\r\u000e"+ + "\u000f\u0010\u0011\u0012\u0013+\u0002\u0000\n\n\r\r\u0003\u0000\t\n\r"+ + "\r \u0002\u0000CCcc\u0002\u0000HHhh\u0002\u0000AAaa\u0002\u0000NNnn\u0002"+ + "\u0000GGgg\u0002\u0000EEee\u0002\u0000PPpp\u0002\u0000OOoo\u0002\u0000"+ + "IIii\u0002\u0000TTtt\u0002\u0000RRrr\u0002\u0000XXxx\u0002\u0000LLll\u0002"+ + "\u0000MMmm\u0002\u0000DDdd\u0002\u0000SSss\u0002\u0000VVvv\u0002\u0000"+ + "KKkk\u0002\u0000WWww\u0002\u0000FFff\u0002\u0000UUuu\u0002\u0000QQqq\u0006"+ + "\u0000\t\n\r\r //[[]]\f\u0000\t\n\r\r \"#(),,//::<<>?\\\\||\u0001\u0000"+ + "09\u0002\u0000AZaz\b\u0000\"\"NNRRTT\\\\nnrrtt\u0004\u0000\n\n\r\r\"\""+ + "\\\\\u0002\u0000++--\u0001\u0000``\u0002\u0000BBbb\u0002\u0000YYyy\f\u0000"+ + "\t\n\r\r \"\"(),,//::==[[]]||\u0002\u0000**//\u0002\u0000JJjj\u0003\u0000"+ + "09AZaz\u0004\u000009AZ__az\u0002\u0000@@__\u0006\u0000\n\n\r\r\"#\')`"+ + "`||\u0002\u0000\"\"\\\\\u0002\u0000\'\'\\\\\u094f\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\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^\u0001\u0000\u0000\u0000\u0001`\u0001\u0000\u0000\u0000\u0001"+ + "b\u0001\u0000\u0000\u0000\u0001d\u0001\u0000\u0000\u0000\u0001f\u0001"+ + "\u0000\u0000\u0000\u0001h\u0001\u0000\u0000\u0000\u0001j\u0001\u0000\u0000"+ + "\u0000\u0001l\u0001\u0000\u0000\u0000\u0001n\u0001\u0000\u0000\u0000\u0001"+ + "p\u0001\u0000\u0000\u0000\u0001r\u0001\u0000\u0000\u0000\u0001t\u0001"+ + "\u0000\u0000\u0000\u0001v\u0001\u0000\u0000\u0000\u0002x\u0001\u0000\u0000"+ + "\u0000\u0002z\u0001\u0000\u0000\u0000\u0002|\u0001\u0000\u0000\u0000\u0002"+ + "~\u0001\u0000\u0000\u0000\u0002\u0082\u0001\u0000\u0000\u0000\u0002\u0084"+ + "\u0001\u0000\u0000\u0000\u0002\u0086\u0001\u0000\u0000\u0000\u0002\u0088"+ + "\u0001\u0000\u0000\u0000\u0002\u008a\u0001\u0000\u0000\u0000\u0002\u008c"+ + "\u0001\u0000\u0000\u0000\u0003\u008e\u0001\u0000\u0000\u0000\u0003\u0090"+ + "\u0001\u0000\u0000\u0000\u0003\u0092\u0001\u0000\u0000\u0000\u0003\u0094"+ + "\u0001\u0000\u0000\u0000\u0003\u0096\u0001\u0000\u0000\u0000\u0003\u0098"+ + "\u0001\u0000\u0000\u0000\u0003\u009a\u0001\u0000\u0000\u0000\u0003\u009c"+ + "\u0001\u0000\u0000\u0000\u0003\u009e\u0001\u0000\u0000\u0000\u0003\u00a0"+ + "\u0001\u0000\u0000\u0000\u0003\u00a2\u0001\u0000\u0000\u0000\u0003\u00a4"+ + "\u0001\u0000\u0000\u0000\u0003\u00a6\u0001\u0000\u0000\u0000\u0003\u00a8"+ + "\u0001\u0000\u0000\u0000\u0003\u00aa\u0001\u0000\u0000\u0000\u0003\u00ac"+ + "\u0001\u0000\u0000\u0000\u0003\u00ae\u0001\u0000\u0000\u0000\u0004\u00b0"+ + "\u0001\u0000\u0000\u0000\u0004\u00b2\u0001\u0000\u0000\u0000\u0004\u00b4"+ + "\u0001\u0000\u0000\u0000\u0004\u00b6\u0001\u0000\u0000\u0000\u0004\u00b8"+ + "\u0001\u0000\u0000\u0000\u0005\u00ba\u0001\u0000\u0000\u0000\u0005\u00d0"+ + "\u0001\u0000\u0000\u0000\u0005\u00d2\u0001\u0000\u0000\u0000\u0005\u00d4"+ + "\u0001\u0000\u0000\u0000\u0005\u00d6\u0001\u0000\u0000\u0000\u0005\u00d8"+ + "\u0001\u0000\u0000\u0000\u0005\u00da\u0001\u0000\u0000\u0000\u0005\u00dc"+ + "\u0001\u0000\u0000\u0000\u0005\u00de\u0001\u0000\u0000\u0000\u0005\u00e0"+ + "\u0001\u0000\u0000\u0000\u0005\u00e2\u0001\u0000\u0000\u0000\u0005\u00e4"+ + "\u0001\u0000\u0000\u0000\u0005\u00e6\u0001\u0000\u0000\u0000\u0005\u00e8"+ + "\u0001\u0000\u0000\u0000\u0005\u00ea\u0001\u0000\u0000\u0000\u0005\u00ec"+ + "\u0001\u0000\u0000\u0000\u0005\u00ee\u0001\u0000\u0000\u0000\u0005\u00f0"+ + "\u0001\u0000\u0000\u0000\u0005\u00f2\u0001\u0000\u0000\u0000\u0005\u00f4"+ + "\u0001\u0000\u0000\u0000\u0005\u00f6\u0001\u0000\u0000\u0000\u0005\u00f8"+ + "\u0001\u0000\u0000\u0000\u0005\u00fa\u0001\u0000\u0000\u0000\u0005\u00fc"+ + "\u0001\u0000\u0000\u0000\u0005\u00fe\u0001\u0000\u0000\u0000\u0005\u0100"+ + "\u0001\u0000\u0000\u0000\u0005\u0102\u0001\u0000\u0000\u0000\u0005\u0104"+ + "\u0001\u0000\u0000\u0000\u0005\u0106\u0001\u0000\u0000\u0000\u0005\u0108"+ + "\u0001\u0000\u0000\u0000\u0005\u010a\u0001\u0000\u0000\u0000\u0005\u010c"+ + "\u0001\u0000\u0000\u0000\u0005\u010e\u0001\u0000\u0000\u0000\u0005\u0110"+ + "\u0001\u0000\u0000\u0000\u0005\u0112\u0001\u0000\u0000\u0000\u0005\u0114"+ + "\u0001\u0000\u0000\u0000\u0005\u0116\u0001\u0000\u0000\u0000\u0005\u0118"+ + "\u0001\u0000\u0000\u0000\u0005\u011a\u0001\u0000\u0000\u0000\u0005\u011c"+ + "\u0001\u0000\u0000\u0000\u0005\u011e\u0001\u0000\u0000\u0000\u0005\u0120"+ + "\u0001\u0000\u0000\u0000\u0005\u0122\u0001\u0000\u0000\u0000\u0005\u0124"+ + "\u0001\u0000\u0000\u0000\u0005\u0126\u0001\u0000\u0000\u0000\u0005\u0128"+ + "\u0001\u0000\u0000\u0000\u0005\u012a\u0001\u0000\u0000\u0000\u0005\u012c"+ + "\u0001\u0000\u0000\u0000\u0005\u012e\u0001\u0000\u0000\u0000\u0005\u0130"+ + "\u0001\u0000\u0000\u0000\u0005\u0132\u0001\u0000\u0000\u0000\u0005\u0134"+ + "\u0001\u0000\u0000\u0000\u0005\u0138\u0001\u0000\u0000\u0000\u0005\u013a"+ + "\u0001\u0000\u0000\u0000\u0005\u013c\u0001\u0000\u0000\u0000\u0005\u013e"+ + "\u0001\u0000\u0000\u0000\u0006\u0140\u0001\u0000\u0000\u0000\u0006\u0142"+ + "\u0001\u0000\u0000\u0000\u0006\u0144\u0001\u0000\u0000\u0000\u0006\u0146"+ + "\u0001\u0000\u0000\u0000\u0006\u0148\u0001\u0000\u0000\u0000\u0006\u014a"+ + "\u0001\u0000\u0000\u0000\u0006\u014c\u0001\u0000\u0000\u0000\u0006\u014e"+ + "\u0001\u0000\u0000\u0000\u0006\u0152\u0001\u0000\u0000\u0000\u0006\u0154"+ + "\u0001\u0000\u0000\u0000\u0006\u0156\u0001\u0000\u0000\u0000\u0006\u0158"+ + "\u0001\u0000\u0000\u0000\u0006\u015a\u0001\u0000\u0000\u0000\u0006\u015c"+ + "\u0001\u0000\u0000\u0000\u0007\u015e\u0001\u0000\u0000\u0000\u0007\u0160"+ + "\u0001\u0000\u0000\u0000\u0007\u0162\u0001\u0000\u0000\u0000\u0007\u0164"+ + "\u0001\u0000\u0000\u0000\u0007\u0166\u0001\u0000\u0000\u0000\u0007\u0168"+ + "\u0001\u0000\u0000\u0000\b\u016a\u0001\u0000\u0000\u0000\b\u016c\u0001"+ + "\u0000\u0000\u0000\b\u016e\u0001\u0000\u0000\u0000\b\u0170\u0001\u0000"+ + "\u0000\u0000\b\u0172\u0001\u0000\u0000\u0000\b\u0174\u0001\u0000\u0000"+ + "\u0000\b\u0176\u0001\u0000\u0000\u0000\b\u0178\u0001\u0000\u0000\u0000"+ + "\b\u017a\u0001\u0000\u0000\u0000\b\u017c\u0001\u0000\u0000\u0000\b\u017e"+ + "\u0001\u0000\u0000\u0000\b\u0180\u0001\u0000\u0000\u0000\b\u0182\u0001"+ + "\u0000\u0000\u0000\b\u0184\u0001\u0000\u0000\u0000\b\u0186\u0001\u0000"+ + "\u0000\u0000\b\u0188\u0001\u0000\u0000\u0000\b\u018a\u0001\u0000\u0000"+ + "\u0000\b\u018c\u0001\u0000\u0000\u0000\t\u018e\u0001\u0000\u0000\u0000"+ + "\t\u0190\u0001\u0000\u0000\u0000\t\u0192\u0001\u0000\u0000\u0000\t\u0194"+ + "\u0001\u0000\u0000\u0000\n\u0196\u0001\u0000\u0000\u0000\n\u0198\u0001"+ + "\u0000\u0000\u0000\n\u019a\u0001\u0000\u0000\u0000\n\u019c\u0001\u0000"+ + "\u0000\u0000\n\u019e\u0001\u0000\u0000\u0000\n\u01a0\u0001\u0000\u0000"+ + "\u0000\n\u01a2\u0001\u0000\u0000\u0000\n\u01a4\u0001\u0000\u0000\u0000"+ + "\n\u01a6\u0001\u0000\u0000\u0000\n\u01a8\u0001\u0000\u0000\u0000\n\u01aa"+ + "\u0001\u0000\u0000\u0000\u000b\u01ac\u0001\u0000\u0000\u0000\u000b\u01ae"+ + "\u0001\u0000\u0000\u0000\u000b\u01b0\u0001\u0000\u0000\u0000\u000b\u01b2"+ + "\u0001\u0000\u0000\u0000\u000b\u01b4\u0001\u0000\u0000\u0000\u000b\u01b6"+ + "\u0001\u0000\u0000\u0000\u000b\u01b8\u0001\u0000\u0000\u0000\u000b\u01ba"+ + "\u0001\u0000\u0000\u0000\u000b\u01bc\u0001\u0000\u0000\u0000\u000b\u01be"+ + "\u0001\u0000\u0000\u0000\u000b\u01c0\u0001\u0000\u0000\u0000\f\u01c2\u0001"+ + "\u0000\u0000\u0000\f\u01c4\u0001\u0000\u0000\u0000\f\u01c6\u0001\u0000"+ + "\u0000\u0000\f\u01c8\u0001\u0000\u0000\u0000\f\u01ca\u0001\u0000\u0000"+ + "\u0000\f\u01cc\u0001\u0000\u0000\u0000\f\u01ce\u0001\u0000\u0000\u0000"+ + "\f\u01d0\u0001\u0000\u0000\u0000\r\u01d2\u0001\u0000\u0000\u0000\r\u01d4"+ + "\u0001\u0000\u0000\u0000\r\u01d6\u0001\u0000\u0000\u0000\r\u01d8\u0001"+ + "\u0000\u0000\u0000\r\u01da\u0001\u0000\u0000\u0000\r\u01dc\u0001\u0000"+ + "\u0000\u0000\r\u01de\u0001\u0000\u0000\u0000\r\u01e0\u0001\u0000\u0000"+ + "\u0000\r\u01e2\u0001\u0000\u0000\u0000\r\u01e4\u0001\u0000\u0000\u0000"+ + "\r\u01e6\u0001\u0000\u0000\u0000\r\u01e8\u0001\u0000\u0000\u0000\r\u01ea"+ + "\u0001\u0000\u0000\u0000\r\u01ec\u0001\u0000\u0000\u0000\u000e\u01ee\u0001"+ + "\u0000\u0000\u0000\u000e\u01f0\u0001\u0000\u0000\u0000\u000e\u01f2\u0001"+ + "\u0000\u0000\u0000\u000e\u01f4\u0001\u0000\u0000\u0000\u000e\u01f6\u0001"+ + "\u0000\u0000\u0000\u000e\u01f8\u0001\u0000\u0000\u0000\u000e\u01fa\u0001"+ + "\u0000\u0000\u0000\u000e\u01fc\u0001\u0000\u0000\u0000\u000e\u01fe\u0001"+ + "\u0000\u0000\u0000\u000e\u0200\u0001\u0000\u0000\u0000\u000e\u0206\u0001"+ + "\u0000\u0000\u0000\u000e\u0208\u0001\u0000\u0000\u0000\u000e\u020a\u0001"+ + "\u0000\u0000\u0000\u000e\u020c\u0001\u0000\u0000\u0000\u000f\u020e\u0001"+ + "\u0000\u0000\u0000\u000f\u0210\u0001\u0000\u0000\u0000\u000f\u0212\u0001"+ + "\u0000\u0000\u0000\u000f\u0214\u0001\u0000\u0000\u0000\u000f\u0216\u0001"+ + "\u0000\u0000\u0000\u000f\u0218\u0001\u0000\u0000\u0000\u000f\u021a\u0001"+ + "\u0000\u0000\u0000\u000f\u021c\u0001\u0000\u0000\u0000\u000f\u021e\u0001"+ + "\u0000\u0000\u0000\u0010\u0220\u0001\u0000\u0000\u0000\u0010\u0222\u0001"+ + "\u0000\u0000\u0000\u0010\u0228\u0001\u0000\u0000\u0000\u0010\u022a\u0001"+ + "\u0000\u0000\u0000\u0010\u022c\u0001\u0000\u0000\u0000\u0010\u022e\u0001"+ + "\u0000\u0000\u0000\u0010\u0230\u0001\u0000\u0000\u0000\u0010\u0232\u0001"+ + "\u0000\u0000\u0000\u0011\u0234\u0001\u0000\u0000\u0000\u0011\u0236\u0001"+ + "\u0000\u0000\u0000\u0011\u0238\u0001\u0000\u0000\u0000\u0011\u023a\u0001"+ + "\u0000\u0000\u0000\u0011\u023c\u0001\u0000\u0000\u0000\u0011\u023e\u0001"+ + "\u0000\u0000\u0000\u0011\u0240\u0001\u0000\u0000\u0000\u0011\u0242\u0001"+ + "\u0000\u0000\u0000\u0011\u0244\u0001\u0000\u0000\u0000\u0011\u0246\u0001"+ + "\u0000\u0000\u0000\u0011\u0248\u0001\u0000\u0000\u0000\u0011\u024a\u0001"+ + "\u0000\u0000\u0000\u0011\u024c\u0001\u0000\u0000\u0000\u0011\u024e\u0001"+ + "\u0000\u0000\u0000\u0011\u0250\u0001\u0000\u0000\u0000\u0011\u0252\u0001"+ + "\u0000\u0000\u0000\u0012\u0254\u0001\u0000\u0000\u0000\u0012\u0256\u0001"+ + "\u0000\u0000\u0000\u0012\u0258\u0001\u0000\u0000\u0000\u0012\u025a\u0001"+ + "\u0000\u0000\u0000\u0012\u025c\u0001\u0000\u0000\u0000\u0012\u025e\u0001"+ + "\u0000\u0000\u0000\u0012\u0260\u0001\u0000\u0000\u0000\u0012\u0262\u0001"+ + "\u0000\u0000\u0000\u0012\u0264\u0001\u0000\u0000\u0000\u0012\u0266\u0001"+ + "\u0000\u0000\u0000\u0012\u0268\u0001\u0000\u0000\u0000\u0012\u026a\u0001"+ + "\u0000\u0000\u0000\u0012\u026c\u0001\u0000\u0000\u0000\u0012\u026e\u0001"+ + "\u0000\u0000\u0000\u0012\u0270\u0001\u0000\u0000\u0000\u0012\u0272\u0001"+ + "\u0000\u0000\u0000\u0012\u0274\u0001\u0000\u0000\u0000\u0012\u0276\u0001"+ + "\u0000\u0000\u0000\u0012\u0278\u0001\u0000\u0000\u0000\u0012\u027a\u0001"+ + "\u0000\u0000\u0000\u0012\u027c\u0001\u0000\u0000\u0000\u0012\u027e\u0001"+ + "\u0000\u0000\u0000\u0013\u0280\u0001\u0000\u0000\u0000\u0013\u0282\u0001"+ + "\u0000\u0000\u0000\u0013\u0284\u0001\u0000\u0000\u0000\u0013\u0286\u0001"+ + "\u0000\u0000\u0000\u0013\u0288\u0001\u0000\u0000\u0000\u0014\u028a\u0001"+ + "\u0000\u0000\u0000\u0016\u029b\u0001\u0000\u0000\u0000\u0018\u02ab\u0001"+ + "\u0000\u0000\u0000\u001a\u02b1\u0001\u0000\u0000\u0000\u001c\u02c0\u0001"+ + "\u0000\u0000\u0000\u001e\u02c9\u0001\u0000\u0000\u0000 \u02d4\u0001\u0000"+ + "\u0000\u0000\"\u02e1\u0001\u0000\u0000\u0000$\u02eb\u0001\u0000\u0000"+ + "\u0000&\u02f2\u0001\u0000\u0000\u0000(\u02f9\u0001\u0000\u0000\u0000*"+ + "\u0301\u0001\u0000\u0000\u0000,\u030a\u0001\u0000\u0000\u0000.\u0310\u0001"+ + "\u0000\u0000\u00000\u0319\u0001\u0000\u0000\u00002\u0320\u0001\u0000\u0000"+ + "\u00004\u0328\u0001\u0000\u0000\u00006\u0330\u0001\u0000\u0000\u00008"+ + "\u0337\u0001\u0000\u0000\u0000:\u033c\u0001\u0000\u0000\u0000<\u0343\u0001"+ + "\u0000\u0000\u0000>\u034a\u0001\u0000\u0000\u0000@\u0353\u0001\u0000\u0000"+ + "\u0000B\u0361\u0001\u0000\u0000\u0000D\u036a\u0001\u0000\u0000\u0000F"+ + "\u0372\u0001\u0000\u0000\u0000H\u037a\u0001\u0000\u0000\u0000J\u0383\u0001"+ + "\u0000\u0000\u0000L\u038f\u0001\u0000\u0000\u0000N\u039b\u0001\u0000\u0000"+ + "\u0000P\u03a2\u0001\u0000\u0000\u0000R\u03a9\u0001\u0000\u0000\u0000T"+ + "\u03b5\u0001\u0000\u0000\u0000V\u03bf\u0001\u0000\u0000\u0000X\u03c8\u0001"+ + "\u0000\u0000\u0000Z\u03ce\u0001\u0000\u0000\u0000\\\u03d6\u0001\u0000"+ + "\u0000\u0000^\u03dc\u0001\u0000\u0000\u0000`\u03e1\u0001\u0000\u0000\u0000"+ + "b\u03e7\u0001\u0000\u0000\u0000d\u03eb\u0001\u0000\u0000\u0000f\u03ef"+ + "\u0001\u0000\u0000\u0000h\u03f3\u0001\u0000\u0000\u0000j\u03f7\u0001\u0000"+ + "\u0000\u0000l\u03fb\u0001\u0000\u0000\u0000n\u03ff\u0001\u0000\u0000\u0000"+ + "p\u0403\u0001\u0000\u0000\u0000r\u0407\u0001\u0000\u0000\u0000t\u040b"+ + "\u0001\u0000\u0000\u0000v\u040f\u0001\u0000\u0000\u0000x\u0413\u0001\u0000"+ + "\u0000\u0000z\u0418\u0001\u0000\u0000\u0000|\u041e\u0001\u0000\u0000\u0000"+ + "~\u0423\u0001\u0000\u0000\u0000\u0080\u0428\u0001\u0000\u0000\u0000\u0082"+ + "\u0431\u0001\u0000\u0000\u0000\u0084\u0438\u0001\u0000\u0000\u0000\u0086"+ + "\u043c\u0001\u0000\u0000\u0000\u0088\u0440\u0001\u0000\u0000\u0000\u008a"+ + "\u0444\u0001\u0000\u0000\u0000\u008c\u0448\u0001\u0000\u0000\u0000\u008e"+ + "\u044c\u0001\u0000\u0000\u0000\u0090\u0452\u0001\u0000\u0000\u0000\u0092"+ + "\u0459\u0001\u0000\u0000\u0000\u0094\u045d\u0001\u0000\u0000\u0000\u0096"+ + "\u0461\u0001\u0000\u0000\u0000\u0098\u0465\u0001\u0000\u0000\u0000\u009a"+ + "\u0469\u0001\u0000\u0000\u0000\u009c\u046d\u0001\u0000\u0000\u0000\u009e"+ + "\u0471\u0001\u0000\u0000\u0000\u00a0\u0475\u0001\u0000\u0000\u0000\u00a2"+ + "\u0479\u0001\u0000\u0000\u0000\u00a4\u047d\u0001\u0000\u0000\u0000\u00a6"+ + "\u0481\u0001\u0000\u0000\u0000\u00a8\u0485\u0001\u0000\u0000\u0000\u00aa"+ + "\u0489\u0001\u0000\u0000\u0000\u00ac\u048d\u0001\u0000\u0000\u0000\u00ae"+ + "\u0491\u0001\u0000\u0000\u0000\u00b0\u0495\u0001\u0000\u0000\u0000\u00b2"+ + "\u049a\u0001\u0000\u0000\u0000\u00b4\u049f\u0001\u0000\u0000\u0000\u00b6"+ + "\u04a3\u0001\u0000\u0000\u0000\u00b8\u04a7\u0001\u0000\u0000\u0000\u00ba"+ + "\u04ab\u0001\u0000\u0000\u0000\u00bc\u04af\u0001\u0000\u0000\u0000\u00be"+ + "\u04b1\u0001\u0000\u0000\u0000\u00c0\u04b3\u0001\u0000\u0000\u0000\u00c2"+ + "\u04b6\u0001\u0000\u0000\u0000\u00c4\u04b8\u0001\u0000\u0000\u0000\u00c6"+ + "\u04c1\u0001\u0000\u0000\u0000\u00c8\u04c3\u0001\u0000\u0000\u0000\u00ca"+ + "\u04c8\u0001\u0000\u0000\u0000\u00cc\u04ca\u0001\u0000\u0000\u0000\u00ce"+ + "\u04cf\u0001\u0000\u0000\u0000\u00d0\u04ee\u0001\u0000\u0000\u0000\u00d2"+ + "\u04f1\u0001\u0000\u0000\u0000\u00d4\u051f\u0001\u0000\u0000\u0000\u00d6"+ + "\u0521\u0001\u0000\u0000\u0000\u00d8\u0525\u0001\u0000\u0000\u0000\u00da"+ + "\u0529\u0001\u0000\u0000\u0000\u00dc\u052b\u0001\u0000\u0000\u0000\u00de"+ + "\u052e\u0001\u0000\u0000\u0000\u00e0\u0531\u0001\u0000\u0000\u0000\u00e2"+ + "\u0533\u0001\u0000\u0000\u0000\u00e4\u0535\u0001\u0000\u0000\u0000\u00e6"+ + "\u0537\u0001\u0000\u0000\u0000\u00e8\u053c\u0001\u0000\u0000\u0000\u00ea"+ + "\u053e\u0001\u0000\u0000\u0000\u00ec\u0544\u0001\u0000\u0000\u0000\u00ee"+ + "\u054a\u0001\u0000\u0000\u0000\u00f0\u054d\u0001\u0000\u0000\u0000\u00f2"+ + "\u0550\u0001\u0000\u0000\u0000\u00f4\u0555\u0001\u0000\u0000\u0000\u00f6"+ + "\u055a\u0001\u0000\u0000\u0000\u00f8\u055e\u0001\u0000\u0000\u0000\u00fa"+ + "\u0563\u0001\u0000\u0000\u0000\u00fc\u0569\u0001\u0000\u0000\u0000\u00fe"+ + "\u056c\u0001\u0000\u0000\u0000\u0100\u056f\u0001\u0000\u0000\u0000\u0102"+ + "\u0571\u0001\u0000\u0000\u0000\u0104\u0577\u0001\u0000\u0000\u0000\u0106"+ + "\u057c\u0001\u0000\u0000\u0000\u0108\u0581\u0001\u0000\u0000\u0000\u010a"+ + "\u0584\u0001\u0000\u0000\u0000\u010c\u0587\u0001\u0000\u0000\u0000\u010e"+ + "\u058a\u0001\u0000\u0000\u0000\u0110\u058c\u0001\u0000\u0000\u0000\u0112"+ + "\u058f\u0001\u0000\u0000\u0000\u0114\u0591\u0001\u0000\u0000\u0000\u0116"+ + "\u0594\u0001\u0000\u0000\u0000\u0118\u0596\u0001\u0000\u0000\u0000\u011a"+ + "\u0598\u0001\u0000\u0000\u0000\u011c\u059a\u0001\u0000\u0000\u0000\u011e"+ + "\u059c\u0001\u0000\u0000\u0000\u0120\u059e\u0001\u0000\u0000\u0000\u0122"+ + "\u05a0\u0001\u0000\u0000\u0000\u0124\u05a2\u0001\u0000\u0000\u0000\u0126"+ + "\u05a5\u0001\u0000\u0000\u0000\u0128\u05ba\u0001\u0000\u0000\u0000\u012a"+ + "\u05cd\u0001\u0000\u0000\u0000\u012c\u05cf\u0001\u0000\u0000\u0000\u012e"+ + "\u05d4\u0001\u0000\u0000\u0000\u0130\u05d9\u0001\u0000\u0000\u0000\u0132"+ + "\u05de\u0001\u0000\u0000\u0000\u0134\u05f3\u0001\u0000\u0000\u0000\u0136"+ + "\u05f5\u0001\u0000\u0000\u0000\u0138\u05fd\u0001\u0000\u0000\u0000\u013a"+ + "\u05ff\u0001\u0000\u0000\u0000\u013c\u0603\u0001\u0000\u0000\u0000\u013e"+ + "\u0607\u0001\u0000\u0000\u0000\u0140\u060b\u0001\u0000\u0000\u0000\u0142"+ + "\u0610\u0001\u0000\u0000\u0000\u0144\u0614\u0001\u0000\u0000\u0000\u0146"+ + "\u0618\u0001\u0000\u0000\u0000\u0148\u061c\u0001\u0000\u0000\u0000\u014a"+ + "\u0620\u0001\u0000\u0000\u0000\u014c\u0629\u0001\u0000\u0000\u0000\u014e"+ + "\u062f\u0001\u0000\u0000\u0000\u0150\u0637\u0001\u0000\u0000\u0000\u0152"+ + "\u063a\u0001\u0000\u0000\u0000\u0154\u063e\u0001\u0000\u0000\u0000\u0156"+ + "\u0642\u0001\u0000\u0000\u0000\u0158\u0646\u0001\u0000\u0000\u0000\u015a"+ + "\u064a\u0001\u0000\u0000\u0000\u015c\u064e\u0001\u0000\u0000\u0000\u015e"+ + "\u0652\u0001\u0000\u0000\u0000\u0160\u0657\u0001\u0000\u0000\u0000\u0162"+ + "\u065d\u0001\u0000\u0000\u0000\u0164\u0662\u0001\u0000\u0000\u0000\u0166"+ + "\u0666\u0001\u0000\u0000\u0000\u0168\u066a\u0001\u0000\u0000\u0000\u016a"+ + "\u066e\u0001\u0000\u0000\u0000\u016c\u0673\u0001\u0000\u0000\u0000\u016e"+ + "\u0679\u0001\u0000\u0000\u0000\u0170\u067f\u0001\u0000\u0000\u0000\u0172"+ + "\u0685\u0001\u0000\u0000\u0000\u0174\u0689\u0001\u0000\u0000\u0000\u0176"+ + "\u068f\u0001\u0000\u0000\u0000\u0178\u0693\u0001\u0000\u0000\u0000\u017a"+ + "\u0697\u0001\u0000\u0000\u0000\u017c\u069b\u0001\u0000\u0000\u0000\u017e"+ + "\u069f\u0001\u0000\u0000\u0000\u0180\u06a3\u0001\u0000\u0000\u0000\u0182"+ + "\u06a7\u0001\u0000\u0000\u0000\u0184\u06ab\u0001\u0000\u0000\u0000\u0186"+ + "\u06af\u0001\u0000\u0000\u0000\u0188\u06b3\u0001\u0000\u0000\u0000\u018a"+ + "\u06b7\u0001\u0000\u0000\u0000\u018c\u06bb\u0001\u0000\u0000\u0000\u018e"+ + "\u06bf\u0001\u0000\u0000\u0000\u0190\u06c8\u0001\u0000\u0000\u0000\u0192"+ + "\u06cc\u0001\u0000\u0000\u0000\u0194\u06d0\u0001\u0000\u0000\u0000\u0196"+ + "\u06d4\u0001\u0000\u0000\u0000\u0198\u06d9\u0001\u0000\u0000\u0000\u019a"+ + "\u06de\u0001\u0000\u0000\u0000\u019c\u06e2\u0001\u0000\u0000\u0000\u019e"+ + "\u06e8\u0001\u0000\u0000\u0000\u01a0\u06f1\u0001\u0000\u0000\u0000\u01a2"+ + "\u06f5\u0001\u0000\u0000\u0000\u01a4\u06f9\u0001\u0000\u0000\u0000\u01a6"+ + "\u06fd\u0001\u0000\u0000\u0000\u01a8\u0701\u0001\u0000\u0000\u0000\u01aa"+ + "\u0705\u0001\u0000\u0000\u0000\u01ac\u0709\u0001\u0000\u0000\u0000\u01ae"+ + "\u070e\u0001\u0000\u0000\u0000\u01b0\u0714\u0001\u0000\u0000\u0000\u01b2"+ + "\u0718\u0001\u0000\u0000\u0000\u01b4\u071c\u0001\u0000\u0000\u0000\u01b6"+ + "\u0720\u0001\u0000\u0000\u0000\u01b8\u0725\u0001\u0000\u0000\u0000\u01ba"+ + "\u0729\u0001\u0000\u0000\u0000\u01bc\u072d\u0001\u0000\u0000\u0000\u01be"+ + "\u0731\u0001\u0000\u0000\u0000\u01c0\u0735\u0001\u0000\u0000\u0000\u01c2"+ + "\u0739\u0001\u0000\u0000\u0000\u01c4\u073f\u0001\u0000\u0000\u0000\u01c6"+ + "\u0746\u0001\u0000\u0000\u0000\u01c8\u074a\u0001\u0000\u0000\u0000\u01ca"+ + "\u074e\u0001\u0000\u0000\u0000\u01cc\u0752\u0001\u0000\u0000\u0000\u01ce"+ + "\u0756\u0001\u0000\u0000\u0000\u01d0\u075a\u0001\u0000\u0000\u0000\u01d2"+ + "\u075e\u0001\u0000\u0000\u0000\u01d4\u0763\u0001\u0000\u0000\u0000\u01d6"+ + "\u0769\u0001\u0000\u0000\u0000\u01d8\u076d\u0001\u0000\u0000\u0000\u01da"+ + "\u0771\u0001\u0000\u0000\u0000\u01dc\u0775\u0001\u0000\u0000\u0000\u01de"+ + "\u0779\u0001\u0000\u0000\u0000\u01e0\u077d\u0001\u0000\u0000\u0000\u01e2"+ + "\u0781\u0001\u0000\u0000\u0000\u01e4\u0785\u0001\u0000\u0000\u0000\u01e6"+ + "\u0789\u0001\u0000\u0000\u0000\u01e8\u078d\u0001\u0000\u0000\u0000\u01ea"+ + "\u0791\u0001\u0000\u0000\u0000\u01ec\u0795\u0001\u0000\u0000\u0000\u01ee"+ + "\u0799\u0001\u0000\u0000\u0000\u01f0\u079e\u0001\u0000\u0000\u0000\u01f2"+ + "\u07a4\u0001\u0000\u0000\u0000\u01f4\u07a8\u0001\u0000\u0000\u0000\u01f6"+ + "\u07ac\u0001\u0000\u0000\u0000\u01f8\u07b0\u0001\u0000\u0000\u0000\u01fa"+ + "\u07b4\u0001\u0000\u0000\u0000\u01fc\u07b8\u0001\u0000\u0000\u0000\u01fe"+ + "\u07bc\u0001\u0000\u0000\u0000\u0200\u07c0\u0001\u0000\u0000\u0000\u0202"+ + "\u07c8\u0001\u0000\u0000\u0000\u0204\u07dd\u0001\u0000\u0000\u0000\u0206"+ + "\u07e1\u0001\u0000\u0000\u0000\u0208\u07e5\u0001\u0000\u0000\u0000\u020a"+ + "\u07e9\u0001\u0000\u0000\u0000\u020c\u07ed\u0001\u0000\u0000\u0000\u020e"+ + "\u07fe\u0001\u0000\u0000\u0000\u0210\u0800\u0001\u0000\u0000\u0000\u0212"+ + "\u0804\u0001\u0000\u0000\u0000\u0214\u0808\u0001\u0000\u0000\u0000\u0216"+ + "\u080c\u0001\u0000\u0000\u0000\u0218\u0811\u0001\u0000\u0000\u0000\u021a"+ + "\u0817\u0001\u0000\u0000\u0000\u021c\u081b\u0001\u0000\u0000\u0000\u021e"+ + "\u081f\u0001\u0000\u0000\u0000\u0220\u0823\u0001\u0000\u0000\u0000\u0222"+ + "\u082b\u0001\u0000\u0000\u0000\u0224\u084b\u0001\u0000\u0000\u0000\u0226"+ + "\u084d\u0001\u0000\u0000\u0000\u0228\u085a\u0001\u0000\u0000\u0000\u022a"+ + "\u0860\u0001\u0000\u0000\u0000\u022c\u0868\u0001\u0000\u0000\u0000\u022e"+ + "\u086e\u0001\u0000\u0000\u0000\u0230\u0872\u0001\u0000\u0000\u0000\u0232"+ + "\u0876\u0001\u0000\u0000\u0000\u0234\u087a\u0001\u0000\u0000\u0000\u0236"+ + "\u087f\u0001\u0000\u0000\u0000\u0238\u0885\u0001\u0000\u0000\u0000\u023a"+ + "\u0889\u0001\u0000\u0000\u0000\u023c\u088d\u0001\u0000\u0000\u0000\u023e"+ + "\u0891\u0001\u0000\u0000\u0000\u0240\u0895\u0001\u0000\u0000\u0000\u0242"+ + "\u0899\u0001\u0000\u0000\u0000\u0244\u089d\u0001\u0000\u0000\u0000\u0246"+ + "\u08a1\u0001\u0000\u0000\u0000\u0248\u08a5\u0001\u0000\u0000\u0000\u024a"+ + "\u08a9\u0001\u0000\u0000\u0000\u024c\u08ac\u0001\u0000\u0000\u0000\u024e"+ + "\u08b0\u0001\u0000\u0000\u0000\u0250\u08b4\u0001\u0000\u0000\u0000\u0252"+ + "\u08b8\u0001\u0000\u0000\u0000\u0254\u08bc\u0001\u0000\u0000\u0000\u0256"+ + "\u08c0\u0001\u0000\u0000\u0000\u0258\u08c4\u0001\u0000\u0000\u0000\u025a"+ + "\u08c8\u0001\u0000\u0000\u0000\u025c\u08cd\u0001\u0000\u0000\u0000\u025e"+ + "\u08d1\u0001\u0000\u0000\u0000\u0260\u08d5\u0001\u0000\u0000\u0000\u0262"+ + "\u08d9\u0001\u0000\u0000\u0000\u0264\u08dd\u0001\u0000\u0000\u0000\u0266"+ + "\u08e1\u0001\u0000\u0000\u0000\u0268\u08e5\u0001\u0000\u0000\u0000\u026a"+ + "\u08e9\u0001\u0000\u0000\u0000\u026c\u08ed\u0001\u0000\u0000\u0000\u026e"+ + "\u08f1\u0001\u0000\u0000\u0000\u0270\u08f5\u0001\u0000\u0000\u0000\u0272"+ + "\u08f9\u0001\u0000\u0000\u0000\u0274\u08fd\u0001\u0000\u0000\u0000\u0276"+ + "\u0901\u0001\u0000\u0000\u0000\u0278\u0905\u0001\u0000\u0000\u0000\u027a"+ + "\u0909\u0001\u0000\u0000\u0000\u027c\u090d\u0001\u0000\u0000\u0000\u027e"+ + "\u0911\u0001\u0000\u0000\u0000\u0280\u0915\u0001\u0000\u0000\u0000\u0282"+ + "\u091a\u0001\u0000\u0000\u0000\u0284\u091f\u0001\u0000\u0000\u0000\u0286"+ + "\u0923\u0001\u0000\u0000\u0000\u0288\u0927\u0001\u0000\u0000\u0000\u028a"+ + "\u028b\u0005/\u0000\u0000\u028b\u028c\u0005/\u0000\u0000\u028c\u0290\u0001"+ + "\u0000\u0000\u0000\u028d\u028f\b\u0000\u0000\u0000\u028e\u028d\u0001\u0000"+ + "\u0000\u0000\u028f\u0292\u0001\u0000\u0000\u0000\u0290\u028e\u0001\u0000"+ + "\u0000\u0000\u0290\u0291\u0001\u0000\u0000\u0000\u0291\u0294\u0001\u0000"+ + "\u0000\u0000\u0292\u0290\u0001\u0000\u0000\u0000\u0293\u0295\u0005\r\u0000"+ + "\u0000\u0294\u0293\u0001\u0000\u0000\u0000\u0294\u0295\u0001\u0000\u0000"+ + "\u0000\u0295\u0297\u0001\u0000\u0000\u0000\u0296\u0298\u0005\n\u0000\u0000"+ + "\u0297\u0296\u0001\u0000\u0000\u0000\u0297\u0298\u0001\u0000\u0000\u0000"+ + "\u0298\u0299\u0001\u0000\u0000\u0000\u0299\u029a\u0006\u0000\u0000\u0000"+ + "\u029a\u0015\u0001\u0000\u0000\u0000\u029b\u029c\u0005/\u0000\u0000\u029c"+ + "\u029d\u0005*\u0000\u0000\u029d\u02a2\u0001\u0000\u0000\u0000\u029e\u02a1"+ + "\u0003\u0016\u0001\u0000\u029f\u02a1\t\u0000\u0000\u0000\u02a0\u029e\u0001"+ + "\u0000\u0000\u0000\u02a0\u029f\u0001\u0000\u0000\u0000\u02a1\u02a4\u0001"+ + "\u0000\u0000\u0000\u02a2\u02a3\u0001\u0000\u0000\u0000\u02a2\u02a0\u0001"+ + "\u0000\u0000\u0000\u02a3\u02a5\u0001\u0000\u0000\u0000\u02a4\u02a2\u0001"+ + "\u0000\u0000\u0000\u02a5\u02a6\u0005*\u0000\u0000\u02a6\u02a7\u0005/\u0000"+ + "\u0000\u02a7\u02a8\u0001\u0000\u0000\u0000\u02a8\u02a9\u0006\u0001\u0000"+ + "\u0000\u02a9\u0017\u0001\u0000\u0000\u0000\u02aa\u02ac\u0007\u0001\u0000"+ + "\u0000\u02ab\u02aa\u0001\u0000\u0000\u0000\u02ac\u02ad\u0001\u0000\u0000"+ + "\u0000\u02ad\u02ab\u0001\u0000\u0000\u0000\u02ad\u02ae\u0001\u0000\u0000"+ + "\u0000\u02ae\u02af\u0001\u0000\u0000\u0000\u02af\u02b0\u0006\u0002\u0000"+ + "\u0000\u02b0\u0019\u0001\u0000\u0000\u0000\u02b1\u02b2\u0007\u0002\u0000"+ + "\u0000\u02b2\u02b3\u0007\u0003\u0000\u0000\u02b3\u02b4\u0007\u0004\u0000"+ + "\u0000\u02b4\u02b5\u0007\u0005\u0000\u0000\u02b5\u02b6\u0007\u0006\u0000"+ + "\u0000\u02b6\u02b7\u0007\u0007\u0000\u0000\u02b7\u02b8\u0005_\u0000\u0000"+ + "\u02b8\u02b9\u0007\b\u0000\u0000\u02b9\u02ba\u0007\t\u0000\u0000\u02ba"+ + "\u02bb\u0007\n\u0000\u0000\u02bb\u02bc\u0007\u0005\u0000\u0000\u02bc\u02bd"+ + "\u0007\u000b\u0000\u0000\u02bd\u02be\u0001\u0000\u0000\u0000\u02be\u02bf"+ + "\u0006\u0003\u0001\u0000\u02bf\u001b\u0001\u0000\u0000\u0000\u02c0\u02c1"+ + "\u0007\u0007\u0000\u0000\u02c1\u02c2\u0007\u0005\u0000\u0000\u02c2\u02c3"+ + "\u0007\f\u0000\u0000\u02c3\u02c4\u0007\n\u0000\u0000\u02c4\u02c5\u0007"+ + "\u0002\u0000\u0000\u02c5\u02c6\u0007\u0003\u0000\u0000\u02c6\u02c7\u0001"+ + "\u0000\u0000\u0000\u02c7\u02c8\u0006\u0004\u0002\u0000\u02c8\u001d\u0001"+ + "\u0000\u0000\u0000\u02c9\u02ca\u0004\u0005\u0000\u0000\u02ca\u02cb\u0007"+ + "\u0007\u0000\u0000\u02cb\u02cc\u0007\r\u0000\u0000\u02cc\u02cd\u0007\b"+ + "\u0000\u0000\u02cd\u02ce\u0007\u000e\u0000\u0000\u02ce\u02cf\u0007\u0004"+ + "\u0000\u0000\u02cf\u02d0\u0007\n\u0000\u0000\u02d0\u02d1\u0007\u0005\u0000"+ + "\u0000\u02d1\u02d2\u0001\u0000\u0000\u0000\u02d2\u02d3\u0006\u0005\u0003"+ + "\u0000\u02d3\u001f\u0001\u0000\u0000\u0000\u02d4\u02d5\u0007\u0002\u0000"+ + "\u0000\u02d5\u02d6\u0007\t\u0000\u0000\u02d6\u02d7\u0007\u000f\u0000\u0000"+ + "\u02d7\u02d8\u0007\b\u0000\u0000\u02d8\u02d9\u0007\u000e\u0000\u0000\u02d9"+ + "\u02da\u0007\u0007\u0000\u0000\u02da\u02db\u0007\u000b\u0000\u0000\u02db"+ + "\u02dc\u0007\n\u0000\u0000\u02dc\u02dd\u0007\t\u0000\u0000\u02dd\u02de"+ + "\u0007\u0005\u0000\u0000\u02de\u02df\u0001\u0000\u0000\u0000\u02df\u02e0"+ + "\u0006\u0006\u0004\u0000\u02e0!\u0001\u0000\u0000\u0000\u02e1\u02e2\u0007"+ + "\u0010\u0000\u0000\u02e2\u02e3\u0007\n\u0000\u0000\u02e3\u02e4\u0007\u0011"+ + "\u0000\u0000\u02e4\u02e5\u0007\u0011\u0000\u0000\u02e5\u02e6\u0007\u0007"+ + "\u0000\u0000\u02e6\u02e7\u0007\u0002\u0000\u0000\u02e7\u02e8\u0007\u000b"+ + "\u0000\u0000\u02e8\u02e9\u0001\u0000\u0000\u0000\u02e9\u02ea\u0006\u0007"+ + "\u0004\u0000\u02ea#\u0001\u0000\u0000\u0000\u02eb\u02ec\u0007\u0007\u0000"+ + "\u0000\u02ec\u02ed\u0007\u0012\u0000\u0000\u02ed\u02ee\u0007\u0004\u0000"+ + "\u0000\u02ee\u02ef\u0007\u000e\u0000\u0000\u02ef\u02f0\u0001\u0000\u0000"+ + "\u0000\u02f0\u02f1\u0006\b\u0004\u0000\u02f1%\u0001\u0000\u0000\u0000"+ + "\u02f2\u02f3\u0007\u0006\u0000\u0000\u02f3\u02f4\u0007\f\u0000\u0000\u02f4"+ + "\u02f5\u0007\t\u0000\u0000\u02f5\u02f6\u0007\u0013\u0000\u0000\u02f6\u02f7"+ + "\u0001\u0000\u0000\u0000\u02f7\u02f8\u0006\t\u0004\u0000\u02f8\'\u0001"+ + "\u0000\u0000\u0000\u02f9\u02fa\u0007\u000e\u0000\u0000\u02fa\u02fb\u0007"+ + "\n\u0000\u0000\u02fb\u02fc\u0007\u000f\u0000\u0000\u02fc\u02fd\u0007\n"+ + "\u0000\u0000\u02fd\u02fe\u0007\u000b\u0000\u0000\u02fe\u02ff\u0001\u0000"+ + "\u0000\u0000\u02ff\u0300\u0006\n\u0004\u0000\u0300)\u0001\u0000\u0000"+ + "\u0000\u0301\u0302\u0007\f\u0000\u0000\u0302\u0303\u0007\u0007\u0000\u0000"+ + "\u0303\u0304\u0007\f\u0000\u0000\u0304\u0305\u0007\u0004\u0000\u0000\u0305"+ + "\u0306\u0007\u0005\u0000\u0000\u0306\u0307\u0007\u0013\u0000\u0000\u0307"+ + "\u0308\u0001\u0000\u0000\u0000\u0308\u0309\u0006\u000b\u0004\u0000\u0309"+ + "+\u0001\u0000\u0000\u0000\u030a\u030b\u0007\f\u0000\u0000\u030b\u030c"+ + "\u0007\t\u0000\u0000\u030c\u030d\u0007\u0014\u0000\u0000\u030d\u030e\u0001"+ + "\u0000\u0000\u0000\u030e\u030f\u0006\f\u0004\u0000\u030f-\u0001\u0000"+ + "\u0000\u0000\u0310\u0311\u0007\u0011\u0000\u0000\u0311\u0312\u0007\u0004"+ + "\u0000\u0000\u0312\u0313\u0007\u000f\u0000\u0000\u0313\u0314\u0007\b\u0000"+ + "\u0000\u0314\u0315\u0007\u000e\u0000\u0000\u0315\u0316\u0007\u0007\u0000"+ + "\u0000\u0316\u0317\u0001\u0000\u0000\u0000\u0317\u0318\u0006\r\u0004\u0000"+ + "\u0318/\u0001\u0000\u0000\u0000\u0319\u031a\u0007\u0011\u0000\u0000\u031a"+ + "\u031b\u0007\t\u0000\u0000\u031b\u031c\u0007\f\u0000\u0000\u031c\u031d"+ + "\u0007\u000b\u0000\u0000\u031d\u031e\u0001\u0000\u0000\u0000\u031e\u031f"+ + "\u0006\u000e\u0004\u0000\u031f1\u0001\u0000\u0000\u0000\u0320\u0321\u0007"+ + "\u0011\u0000\u0000\u0321\u0322\u0007\u000b\u0000\u0000\u0322\u0323\u0007"+ + "\u0004\u0000\u0000\u0323\u0324\u0007\u000b\u0000\u0000\u0324\u0325\u0007"+ + "\u0011\u0000\u0000\u0325\u0326\u0001\u0000\u0000\u0000\u0326\u0327\u0006"+ + "\u000f\u0004\u0000\u03273\u0001\u0000\u0000\u0000\u0328\u0329\u0007\u0014"+ + "\u0000\u0000\u0329\u032a\u0007\u0003\u0000\u0000\u032a\u032b\u0007\u0007"+ + "\u0000\u0000\u032b\u032c\u0007\f\u0000\u0000\u032c\u032d\u0007\u0007\u0000"+ + "\u0000\u032d\u032e\u0001\u0000\u0000\u0000\u032e\u032f\u0006\u0010\u0004"+ + "\u0000\u032f5\u0001\u0000\u0000\u0000\u0330\u0331\u0007\u0015\u0000\u0000"+ + "\u0331\u0332\u0007\f\u0000\u0000\u0332\u0333\u0007\t\u0000\u0000\u0333"+ + "\u0334\u0007\u000f\u0000\u0000\u0334\u0335\u0001\u0000\u0000\u0000\u0335"+ + "\u0336\u0006\u0011\u0005\u0000\u03367\u0001\u0000\u0000\u0000\u0337\u0338"+ + "\u0007\u000b\u0000\u0000\u0338\u0339\u0007\u0011\u0000\u0000\u0339\u033a"+ + "\u0001\u0000\u0000\u0000\u033a\u033b\u0006\u0012\u0005\u0000\u033b9\u0001"+ + "\u0000\u0000\u0000\u033c\u033d\u0007\u0015\u0000\u0000\u033d\u033e\u0007"+ + "\t\u0000\u0000\u033e\u033f\u0007\f\u0000\u0000\u033f\u0340\u0007\u0013"+ + "\u0000\u0000\u0340\u0341\u0001\u0000\u0000\u0000\u0341\u0342\u0006\u0013"+ + "\u0006\u0000\u0342;\u0001\u0000\u0000\u0000\u0343\u0344\u0007\u0015\u0000"+ + "\u0000\u0344\u0345\u0007\u0016\u0000\u0000\u0345\u0346\u0007\u0011\u0000"+ + "\u0000\u0346\u0347\u0007\u0007\u0000\u0000\u0347\u0348\u0001\u0000\u0000"+ + "\u0000\u0348\u0349\u0006\u0014\u0007\u0000\u0349=\u0001\u0000\u0000\u0000"+ + "\u034a\u034b\u0007\n\u0000\u0000\u034b\u034c\u0007\u0005\u0000\u0000\u034c"+ + "\u034d\u0007\u000e\u0000\u0000\u034d\u034e\u0007\n\u0000\u0000\u034e\u034f"+ + "\u0007\u0005\u0000\u0000\u034f\u0350\u0007\u0007\u0000\u0000\u0350\u0351"+ + "\u0001\u0000\u0000\u0000\u0351\u0352\u0006\u0015\b\u0000\u0352?\u0001"+ + "\u0000\u0000\u0000\u0353\u0354\u0007\n\u0000\u0000\u0354\u0355\u0007\u0005"+ + "\u0000\u0000\u0355\u0356\u0007\u000e\u0000\u0000\u0356\u0357\u0007\n\u0000"+ + "\u0000\u0357\u0358\u0007\u0005\u0000\u0000\u0358\u0359\u0007\u0007\u0000"+ + "\u0000\u0359\u035a\u0007\u0011\u0000\u0000\u035a\u035b\u0007\u000b\u0000"+ + "\u0000\u035b\u035c\u0007\u0004\u0000\u0000\u035c\u035d\u0007\u000b\u0000"+ + "\u0000\u035d\u035e\u0007\u0011\u0000\u0000\u035e\u035f\u0001\u0000\u0000"+ + "\u0000\u035f\u0360\u0006\u0016\u0004\u0000\u0360A\u0001\u0000\u0000\u0000"+ + "\u0361\u0362\u0007\u000e\u0000\u0000\u0362\u0363\u0007\t\u0000\u0000\u0363"+ + "\u0364\u0007\t\u0000\u0000\u0364\u0365\u0007\u0013\u0000\u0000\u0365\u0366"+ + "\u0007\u0016\u0000\u0000\u0366\u0367\u0007\b\u0000\u0000\u0367\u0368\u0001"+ + "\u0000\u0000\u0000\u0368\u0369\u0006\u0017\t\u0000\u0369C\u0001\u0000"+ + "\u0000\u0000\u036a\u036b\u0004\u0018\u0001\u0000\u036b\u036c\u0007\u0015"+ + "\u0000\u0000\u036c\u036d\u0007\u0016\u0000\u0000\u036d\u036e\u0007\u000e"+ + "\u0000\u0000\u036e\u036f\u0007\u000e\u0000\u0000\u036f\u0370\u0001\u0000"+ + "\u0000\u0000\u0370\u0371\u0006\u0018\t\u0000\u0371E\u0001\u0000\u0000"+ + "\u0000\u0372\u0373\u0004\u0019\u0002\u0000\u0373\u0374\u0007\u000e\u0000"+ + "\u0000\u0374\u0375\u0007\u0007\u0000\u0000\u0375\u0376\u0007\u0015\u0000"+ + "\u0000\u0376\u0377\u0007\u000b\u0000\u0000\u0377\u0378\u0001\u0000\u0000"+ + "\u0000\u0378\u0379\u0006\u0019\t\u0000\u0379G\u0001\u0000\u0000\u0000"+ + "\u037a\u037b\u0004\u001a\u0003\u0000\u037b\u037c\u0007\f\u0000\u0000\u037c"+ + "\u037d\u0007\n\u0000\u0000\u037d\u037e\u0007\u0006\u0000\u0000\u037e\u037f"+ + "\u0007\u0003\u0000\u0000\u037f\u0380\u0007\u000b\u0000\u0000\u0380\u0381"+ + "\u0001\u0000\u0000\u0000\u0381\u0382\u0006\u001a\t\u0000\u0382I\u0001"+ + "\u0000\u0000\u0000\u0383\u0384\u0004\u001b\u0004\u0000\u0384\u0385\u0007"+ + "\u000e\u0000\u0000\u0385\u0386\u0007\t\u0000\u0000\u0386\u0387\u0007\t"+ + "\u0000\u0000\u0387\u0388\u0007\u0013\u0000\u0000\u0388\u0389\u0007\u0016"+ + "\u0000\u0000\u0389\u038a\u0007\b\u0000\u0000\u038a\u038b\u0005_\u0000"+ + "\u0000\u038b\u038c\u0005\u8001\uf414\u0000\u0000\u038c\u038d\u0001\u0000"+ + "\u0000\u0000\u038d\u038e\u0006\u001b\n\u0000\u038eK\u0001\u0000\u0000"+ + "\u0000\u038f\u0390\u0007\u000f\u0000\u0000\u0390\u0391\u0007\u0012\u0000"+ + "\u0000\u0391\u0392\u0005_\u0000\u0000\u0392\u0393\u0007\u0007\u0000\u0000"+ + "\u0393\u0394\u0007\r\u0000\u0000\u0394\u0395\u0007\b\u0000\u0000\u0395"+ + "\u0396\u0007\u0004\u0000\u0000\u0396\u0397\u0007\u0005\u0000\u0000\u0397"+ + "\u0398\u0007\u0010\u0000\u0000\u0398\u0399\u0001\u0000\u0000\u0000\u0399"+ + "\u039a\u0006\u001c\u000b\u0000\u039aM\u0001\u0000\u0000\u0000\u039b\u039c"+ + "\u0007\u0010\u0000\u0000\u039c\u039d\u0007\f\u0000\u0000\u039d\u039e\u0007"+ + "\t\u0000\u0000\u039e\u039f\u0007\b\u0000\u0000\u039f\u03a0\u0001\u0000"+ + "\u0000\u0000\u03a0\u03a1\u0006\u001d\f\u0000\u03a1O\u0001\u0000\u0000"+ + "\u0000\u03a2\u03a3\u0007\u0013\u0000\u0000\u03a3\u03a4\u0007\u0007\u0000"+ + "\u0000\u03a4\u03a5\u0007\u0007\u0000\u0000\u03a5\u03a6\u0007\b\u0000\u0000"+ + "\u03a6\u03a7\u0001\u0000\u0000\u0000\u03a7\u03a8\u0006\u001e\f\u0000\u03a8"+ + "Q\u0001\u0000\u0000\u0000\u03a9\u03aa\u0004\u001f\u0005\u0000\u03aa\u03ab"+ + "\u0007\n\u0000\u0000\u03ab\u03ac\u0007\u0005\u0000\u0000\u03ac\u03ad\u0007"+ + "\u0011\u0000\u0000\u03ad\u03ae\u0007\n\u0000\u0000\u03ae\u03af\u0007\u0011"+ + "\u0000\u0000\u03af\u03b0\u0007\u000b\u0000\u0000\u03b0\u03b1\u0005_\u0000"+ + "\u0000\u03b1\u03b2\u0005\u8001\uf414\u0000\u0000\u03b2\u03b3\u0001\u0000"+ + "\u0000\u0000\u03b3\u03b4\u0006\u001f\f\u0000\u03b4S\u0001\u0000\u0000"+ + "\u0000\u03b5\u03b6\u0004 \u0006\u0000\u03b6\u03b7\u0007\b\u0000\u0000"+ + "\u03b7\u03b8\u0007\f\u0000\u0000\u03b8\u03b9\u0007\t\u0000\u0000\u03b9"+ + "\u03ba\u0007\u000f\u0000\u0000\u03ba\u03bb\u0007\u0017\u0000\u0000\u03bb"+ + "\u03bc\u0007\u000e\u0000\u0000\u03bc\u03bd\u0001\u0000\u0000\u0000\u03bd"+ + "\u03be\u0006 \r\u0000\u03beU\u0001\u0000\u0000\u0000\u03bf\u03c0\u0007"+ + "\f\u0000\u0000\u03c0\u03c1\u0007\u0007\u0000\u0000\u03c1\u03c2\u0007\u0005"+ + "\u0000\u0000\u03c2\u03c3\u0007\u0004\u0000\u0000\u03c3\u03c4\u0007\u000f"+ + "\u0000\u0000\u03c4\u03c5\u0007\u0007\u0000\u0000\u03c5\u03c6\u0001\u0000"+ + "\u0000\u0000\u03c6\u03c7\u0006!\u000e\u0000\u03c7W\u0001\u0000\u0000\u0000"+ + "\u03c8\u03c9\u0007\u0011\u0000\u0000\u03c9\u03ca\u0007\u0007\u0000\u0000"+ + "\u03ca\u03cb\u0007\u000b\u0000\u0000\u03cb\u03cc\u0001\u0000\u0000\u0000"+ + "\u03cc\u03cd\u0006\"\u000f\u0000\u03cdY\u0001\u0000\u0000\u0000\u03ce"+ + "\u03cf\u0007\u0011\u0000\u0000\u03cf\u03d0\u0007\u0003\u0000\u0000\u03d0"+ + "\u03d1\u0007\t\u0000\u0000\u03d1\u03d2\u0007\u0014\u0000\u0000\u03d2\u03d3"+ + "\u0001\u0000\u0000\u0000\u03d3\u03d4\u0006#\u0010\u0000\u03d4[\u0001\u0000"+ + "\u0000\u0000\u03d5\u03d7\b\u0018\u0000\u0000\u03d6\u03d5\u0001\u0000\u0000"+ + "\u0000\u03d7\u03d8\u0001\u0000\u0000\u0000\u03d8\u03d6\u0001\u0000\u0000"+ + "\u0000\u03d8\u03d9\u0001\u0000\u0000\u0000\u03d9\u03da\u0001\u0000\u0000"+ + "\u0000\u03da\u03db\u0006$\u0004\u0000\u03db]\u0001\u0000\u0000\u0000\u03dc"+ + "\u03dd\u0003\u00baS\u0000\u03dd\u03de\u0001\u0000\u0000\u0000\u03de\u03df"+ + "\u0006%\u0011\u0000\u03df\u03e0\u0006%\u0012\u0000\u03e0_\u0001\u0000"+ + "\u0000\u0000\u03e1\u03e2\u0003\u0132\u008f\u0000\u03e2\u03e3\u0001\u0000"+ + "\u0000\u0000\u03e3\u03e4\u0006&\u0013\u0000\u03e4\u03e5\u0006&\u0012\u0000"+ + "\u03e5\u03e6\u0006&\u0012\u0000\u03e6a\u0001\u0000\u0000\u0000\u03e7\u03e8"+ + "\u0003\u00fct\u0000\u03e8\u03e9\u0001\u0000\u0000\u0000\u03e9\u03ea\u0006"+ + "\'\u0014\u0000\u03eac\u0001\u0000\u0000\u0000\u03eb\u03ec\u0003\u024a"+ + "\u011b\u0000\u03ec\u03ed\u0001\u0000\u0000\u0000\u03ed\u03ee\u0006(\u0015"+ + "\u0000\u03eee\u0001\u0000\u0000\u0000\u03ef\u03f0\u0003\u00e8j\u0000\u03f0"+ + "\u03f1\u0001\u0000\u0000\u0000\u03f1\u03f2\u0006)\u0016\u0000\u03f2g\u0001"+ + "\u0000\u0000\u0000\u03f3\u03f4\u0003\u00e4h\u0000\u03f4\u03f5\u0001\u0000"+ + "\u0000\u0000\u03f5\u03f6\u0006*\u0017\u0000\u03f6i\u0001\u0000\u0000\u0000"+ + "\u03f7\u03f8\u0003\u012c\u008c\u0000\u03f8\u03f9\u0001\u0000\u0000\u0000"+ + "\u03f9\u03fa\u0006+\u0018\u0000\u03fak\u0001\u0000\u0000\u0000\u03fb\u03fc"+ + "\u0003\u012e\u008d\u0000\u03fc\u03fd\u0001\u0000\u0000\u0000\u03fd\u03fe"+ + "\u0006,\u0019\u0000\u03fem\u0001\u0000\u0000\u0000\u03ff\u0400\u0003\u0138"+ + "\u0092\u0000\u0400\u0401\u0001\u0000\u0000\u0000\u0401\u0402\u0006-\u001a"+ + "\u0000\u0402o\u0001\u0000\u0000\u0000\u0403\u0404\u0003\u0134\u0090\u0000"+ + "\u0404\u0405\u0001\u0000\u0000\u0000\u0405\u0406\u0006.\u001b\u0000\u0406"+ + "q\u0001\u0000\u0000\u0000\u0407\u0408\u0003\u0014\u0000\u0000\u0408\u0409"+ + "\u0001\u0000\u0000\u0000\u0409\u040a\u0006/\u0000\u0000\u040as\u0001\u0000"+ + "\u0000\u0000\u040b\u040c\u0003\u0016\u0001\u0000\u040c\u040d\u0001\u0000"+ + "\u0000\u0000\u040d\u040e\u00060\u0000\u0000\u040eu\u0001\u0000\u0000\u0000"+ + "\u040f\u0410\u0003\u0018\u0002\u0000\u0410\u0411\u0001\u0000\u0000\u0000"+ + "\u0411\u0412\u00061\u0000\u0000\u0412w\u0001\u0000\u0000\u0000\u0413\u0414"+ + "\u0003\u00baS\u0000\u0414\u0415\u0001\u0000\u0000\u0000\u0415\u0416\u0006"+ + "2\u0011\u0000\u0416\u0417\u00062\u0012\u0000\u0417y\u0001\u0000\u0000"+ + "\u0000\u0418\u0419\u0003\u0132\u008f\u0000\u0419\u041a\u0001\u0000\u0000"+ + "\u0000\u041a\u041b\u00063\u0013\u0000\u041b\u041c\u00063\u0012\u0000\u041c"+ + "\u041d\u00063\u0012\u0000\u041d{\u0001\u0000\u0000\u0000\u041e\u041f\u0003"+ + "\u00fct\u0000\u041f\u0420\u0001\u0000\u0000\u0000\u0420\u0421\u00064\u0014"+ + "\u0000\u0421\u0422\u00064\u001c\u0000\u0422}\u0001\u0000\u0000\u0000\u0423"+ + "\u0424\u0003\u0106y\u0000\u0424\u0425\u0001\u0000\u0000\u0000\u0425\u0426"+ + "\u00065\u001d\u0000\u0426\u0427\u00065\u001c\u0000\u0427\u007f\u0001\u0000"+ + "\u0000\u0000\u0428\u0429\b\u0019\u0000\u0000\u0429\u0081\u0001\u0000\u0000"+ + "\u0000\u042a\u042c\u0003\u00806\u0000\u042b\u042a\u0001\u0000\u0000\u0000"+ + "\u042c\u042d\u0001\u0000\u0000\u0000\u042d\u042b\u0001\u0000\u0000\u0000"+ + "\u042d\u042e\u0001\u0000\u0000\u0000\u042e\u042f\u0001\u0000\u0000\u0000"+ + "\u042f\u0430\u0003\u00e0f\u0000\u0430\u0432\u0001\u0000\u0000\u0000\u0431"+ + "\u042b\u0001\u0000\u0000\u0000\u0431\u0432\u0001\u0000\u0000\u0000\u0432"+ + "\u0434\u0001\u0000\u0000\u0000\u0433\u0435\u0003\u00806\u0000\u0434\u0433"+ + "\u0001\u0000\u0000\u0000\u0435\u0436\u0001\u0000\u0000\u0000\u0436\u0434"+ + "\u0001\u0000\u0000\u0000\u0436\u0437\u0001\u0000\u0000\u0000\u0437\u0083"+ + "\u0001\u0000\u0000\u0000\u0438\u0439\u0003\u00827\u0000\u0439\u043a\u0001"+ + "\u0000\u0000\u0000\u043a\u043b\u00068\u001e\u0000\u043b\u0085\u0001\u0000"+ + "\u0000\u0000\u043c\u043d\u0003\u00d0^\u0000\u043d\u043e\u0001\u0000\u0000"+ + "\u0000\u043e\u043f\u00069\u001f\u0000\u043f\u0087\u0001\u0000\u0000\u0000"+ + "\u0440\u0441\u0003\u0014\u0000\u0000\u0441\u0442\u0001\u0000\u0000\u0000"+ + "\u0442\u0443\u0006:\u0000\u0000\u0443\u0089\u0001\u0000\u0000\u0000\u0444"+ + "\u0445\u0003\u0016\u0001\u0000\u0445\u0446\u0001\u0000\u0000\u0000\u0446"+ + "\u0447\u0006;\u0000\u0000\u0447\u008b\u0001\u0000\u0000\u0000\u0448\u0449"+ + "\u0003\u0018\u0002\u0000\u0449\u044a\u0001\u0000\u0000\u0000\u044a\u044b"+ + "\u0006<\u0000\u0000\u044b\u008d\u0001\u0000\u0000\u0000\u044c\u044d\u0003"+ + "\u00baS\u0000\u044d\u044e\u0001\u0000\u0000\u0000\u044e\u044f\u0006=\u0011"+ + "\u0000\u044f\u0450\u0006=\u0012\u0000\u0450\u0451\u0006=\u0012\u0000\u0451"+ + "\u008f\u0001\u0000\u0000\u0000\u0452\u0453\u0003\u0132\u008f\u0000\u0453"+ + "\u0454\u0001\u0000\u0000\u0000\u0454\u0455\u0006>\u0013\u0000\u0455\u0456"+ + "\u0006>\u0012\u0000\u0456\u0457\u0006>\u0012\u0000\u0457\u0458\u0006>"+ + "\u0012\u0000\u0458\u0091\u0001\u0000\u0000\u0000\u0459\u045a\u0003\u012c"+ + "\u008c\u0000\u045a\u045b\u0001\u0000\u0000\u0000\u045b\u045c\u0006?\u0018"+ + "\u0000\u045c\u0093\u0001\u0000\u0000\u0000\u045d\u045e\u0003\u012e\u008d"+ + "\u0000\u045e\u045f\u0001\u0000\u0000\u0000\u045f\u0460\u0006@\u0019\u0000"+ + "\u0460\u0095\u0001\u0000\u0000\u0000\u0461\u0462\u0003\u00dac\u0000\u0462"+ + "\u0463\u0001\u0000\u0000\u0000\u0463\u0464\u0006A \u0000\u0464\u0097\u0001"+ + "\u0000\u0000\u0000\u0465\u0466\u0003\u00e4h\u0000\u0466\u0467\u0001\u0000"+ + "\u0000\u0000\u0467\u0468\u0006B\u0017\u0000\u0468\u0099\u0001\u0000\u0000"+ + "\u0000\u0469\u046a\u0003\u00e8j\u0000\u046a\u046b\u0001\u0000\u0000\u0000"+ + "\u046b\u046c\u0006C\u0016\u0000\u046c\u009b\u0001\u0000\u0000\u0000\u046d"+ + "\u046e\u0003\u0106y\u0000\u046e\u046f\u0001\u0000\u0000\u0000\u046f\u0470"+ + "\u0006D\u001d\u0000\u0470\u009d\u0001\u0000\u0000\u0000\u0471\u0472\u0003"+ + "\u0206\u00f9\u0000\u0472\u0473\u0001\u0000\u0000\u0000\u0473\u0474\u0006"+ + "E!\u0000\u0474\u009f\u0001\u0000\u0000\u0000\u0475\u0476\u0003\u0138\u0092"+ + "\u0000\u0476\u0477\u0001\u0000\u0000\u0000\u0477\u0478\u0006F\u001a\u0000"+ + "\u0478\u00a1\u0001\u0000\u0000\u0000\u0479\u047a\u0003\u0100v\u0000\u047a"+ + "\u047b\u0001\u0000\u0000\u0000\u047b\u047c\u0006G\"\u0000\u047c\u00a3"+ + "\u0001\u0000\u0000\u0000\u047d\u047e\u0003\u0128\u008a\u0000\u047e\u047f"+ + "\u0001\u0000\u0000\u0000\u047f\u0480\u0006H#\u0000\u0480\u00a5\u0001\u0000"+ + "\u0000\u0000\u0481\u0482\u0003\u0124\u0088\u0000\u0482\u0483\u0001\u0000"+ + "\u0000\u0000\u0483\u0484\u0006I$\u0000\u0484\u00a7\u0001\u0000\u0000\u0000"+ + "\u0485\u0486\u0003\u012a\u008b\u0000\u0486\u0487\u0001\u0000\u0000\u0000"+ + "\u0487\u0488\u0006J%\u0000\u0488\u00a9\u0001\u0000\u0000\u0000\u0489\u048a"+ + "\u0003\u0014\u0000\u0000\u048a\u048b\u0001\u0000\u0000\u0000\u048b\u048c"+ + "\u0006K\u0000\u0000\u048c\u00ab\u0001\u0000\u0000\u0000\u048d\u048e\u0003"+ + "\u0016\u0001\u0000\u048e\u048f\u0001\u0000\u0000\u0000\u048f\u0490\u0006"+ + "L\u0000\u0000\u0490\u00ad\u0001\u0000\u0000\u0000\u0491\u0492\u0003\u0018"+ + "\u0002\u0000\u0492\u0493\u0001\u0000\u0000\u0000\u0493\u0494\u0006M\u0000"+ + "\u0000\u0494\u00af\u0001\u0000\u0000\u0000\u0495\u0496\u0003\u0130\u008e"+ + "\u0000\u0496\u0497\u0001\u0000\u0000\u0000\u0497\u0498\u0006N&\u0000\u0498"+ + "\u0499\u0006N\'\u0000\u0499\u00b1\u0001\u0000\u0000\u0000\u049a\u049b"+ + "\u0003\u00baS\u0000\u049b\u049c\u0001\u0000\u0000\u0000\u049c\u049d\u0006"+ + "O\u0011\u0000\u049d\u049e\u0006O\u0012\u0000\u049e\u00b3\u0001\u0000\u0000"+ + "\u0000\u049f\u04a0\u0003\u0018\u0002\u0000\u04a0\u04a1\u0001\u0000\u0000"+ + "\u0000\u04a1\u04a2\u0006P\u0000\u0000\u04a2\u00b5\u0001\u0000\u0000\u0000"+ + "\u04a3\u04a4\u0003\u0014\u0000\u0000\u04a4\u04a5\u0001\u0000\u0000\u0000"+ + "\u04a5\u04a6\u0006Q\u0000\u0000\u04a6\u00b7\u0001\u0000\u0000\u0000\u04a7"+ + "\u04a8\u0003\u0016\u0001\u0000\u04a8\u04a9\u0001\u0000\u0000\u0000\u04a9"+ + "\u04aa\u0006R\u0000\u0000\u04aa\u00b9\u0001\u0000\u0000\u0000\u04ab\u04ac"+ + "\u0005|\u0000\u0000\u04ac\u04ad\u0001\u0000\u0000\u0000\u04ad\u04ae\u0006"+ + "S\u0012\u0000\u04ae\u00bb\u0001\u0000\u0000\u0000\u04af\u04b0\u0007\u001a"+ + "\u0000\u0000\u04b0\u00bd\u0001\u0000\u0000\u0000\u04b1\u04b2\u0007\u001b"+ + "\u0000\u0000\u04b2\u00bf\u0001\u0000\u0000\u0000\u04b3\u04b4\u0005\\\u0000"+ + "\u0000\u04b4\u04b5\u0007\u001c\u0000\u0000\u04b5\u00c1\u0001\u0000\u0000"+ + "\u0000\u04b6\u04b7\b\u001d\u0000\u0000\u04b7\u00c3\u0001\u0000\u0000\u0000"+ + "\u04b8\u04ba\u0007\u0007\u0000\u0000\u04b9\u04bb\u0007\u001e\u0000\u0000"+ + "\u04ba\u04b9\u0001\u0000\u0000\u0000\u04ba\u04bb\u0001\u0000\u0000\u0000"+ + "\u04bb\u04bd\u0001\u0000\u0000\u0000\u04bc\u04be\u0003\u00bcT\u0000\u04bd"+ + "\u04bc\u0001\u0000\u0000\u0000\u04be\u04bf\u0001\u0000\u0000\u0000\u04bf"+ + "\u04bd\u0001\u0000\u0000\u0000\u04bf\u04c0\u0001\u0000\u0000\u0000\u04c0"+ + "\u00c5\u0001\u0000\u0000\u0000\u04c1\u04c2\u0005@\u0000\u0000\u04c2\u00c7"+ + "\u0001\u0000\u0000\u0000\u04c3\u04c4\u0005`\u0000\u0000\u04c4\u00c9\u0001"+ + "\u0000\u0000\u0000\u04c5\u04c9\b\u001f\u0000\u0000\u04c6\u04c7\u0005`"+ + "\u0000\u0000\u04c7\u04c9\u0005`\u0000\u0000\u04c8\u04c5\u0001\u0000\u0000"+ + "\u0000\u04c8\u04c6\u0001\u0000\u0000\u0000\u04c9\u00cb\u0001\u0000\u0000"+ + "\u0000\u04ca\u04cb\u0005_\u0000\u0000\u04cb\u00cd\u0001\u0000\u0000\u0000"+ + "\u04cc\u04d0\u0003\u00beU\u0000\u04cd\u04d0\u0003\u00bcT\u0000\u04ce\u04d0"+ + "\u0003\u00cc\\\u0000\u04cf\u04cc\u0001\u0000\u0000\u0000\u04cf\u04cd\u0001"+ + "\u0000\u0000\u0000\u04cf\u04ce\u0001\u0000\u0000\u0000\u04d0\u00cf\u0001"+ + "\u0000\u0000\u0000\u04d1\u04d6\u0005\"\u0000\u0000\u04d2\u04d5\u0003\u00c0"+ + "V\u0000\u04d3\u04d5\u0003\u00c2W\u0000\u04d4\u04d2\u0001\u0000\u0000\u0000"+ + "\u04d4\u04d3\u0001\u0000\u0000\u0000\u04d5\u04d8\u0001\u0000\u0000\u0000"+ + "\u04d6\u04d4\u0001\u0000\u0000\u0000\u04d6\u04d7\u0001\u0000\u0000\u0000"+ + "\u04d7\u04d9\u0001\u0000\u0000\u0000\u04d8\u04d6\u0001\u0000\u0000\u0000"+ + "\u04d9\u04ef\u0005\"\u0000\u0000\u04da\u04db\u0005\"\u0000\u0000\u04db"+ + "\u04dc\u0005\"\u0000\u0000\u04dc\u04dd\u0005\"\u0000\u0000\u04dd\u04e1"+ + "\u0001\u0000\u0000\u0000\u04de\u04e0\b\u0000\u0000\u0000\u04df\u04de\u0001"+ + "\u0000\u0000\u0000\u04e0\u04e3\u0001\u0000\u0000\u0000\u04e1\u04e2\u0001"+ + "\u0000\u0000\u0000\u04e1\u04df\u0001\u0000\u0000\u0000\u04e2\u04e4\u0001"+ + "\u0000\u0000\u0000\u04e3\u04e1\u0001\u0000\u0000\u0000\u04e4\u04e5\u0005"+ + "\"\u0000\u0000\u04e5\u04e6\u0005\"\u0000\u0000\u04e6\u04e7\u0005\"\u0000"+ + "\u0000\u04e7\u04e9\u0001\u0000\u0000\u0000\u04e8\u04ea\u0005\"\u0000\u0000"+ + "\u04e9\u04e8\u0001\u0000\u0000\u0000\u04e9\u04ea\u0001\u0000\u0000\u0000"+ + "\u04ea\u04ec\u0001\u0000\u0000\u0000\u04eb\u04ed\u0005\"\u0000\u0000\u04ec"+ + "\u04eb\u0001\u0000\u0000\u0000\u04ec\u04ed\u0001\u0000\u0000\u0000\u04ed"+ + "\u04ef\u0001\u0000\u0000\u0000\u04ee\u04d1\u0001\u0000\u0000\u0000\u04ee"+ + "\u04da\u0001\u0000\u0000\u0000\u04ef\u00d1\u0001\u0000\u0000\u0000\u04f0"+ + "\u04f2\u0003\u00bcT\u0000\u04f1\u04f0\u0001\u0000\u0000\u0000\u04f2\u04f3"+ + "\u0001\u0000\u0000\u0000\u04f3\u04f1\u0001\u0000\u0000\u0000\u04f3\u04f4"+ + "\u0001\u0000\u0000\u0000\u04f4\u00d3\u0001\u0000\u0000\u0000\u04f5\u04f7"+ + "\u0003\u00bcT\u0000\u04f6\u04f5\u0001\u0000\u0000\u0000\u04f7\u04f8\u0001"+ + "\u0000\u0000\u0000\u04f8\u04f6\u0001\u0000\u0000\u0000\u04f8\u04f9\u0001"+ + "\u0000\u0000\u0000\u04f9\u04fa\u0001\u0000\u0000\u0000\u04fa\u04fe\u0003"+ + "\u00e8j\u0000\u04fb\u04fd\u0003\u00bcT\u0000\u04fc\u04fb\u0001\u0000\u0000"+ + "\u0000\u04fd\u0500\u0001\u0000\u0000\u0000\u04fe\u04fc\u0001\u0000\u0000"+ + "\u0000\u04fe\u04ff\u0001\u0000\u0000\u0000\u04ff\u0520\u0001\u0000\u0000"+ + "\u0000\u0500\u04fe\u0001\u0000\u0000\u0000\u0501\u0503\u0003\u00e8j\u0000"+ + "\u0502\u0504\u0003\u00bcT\u0000\u0503\u0502\u0001\u0000\u0000\u0000\u0504"+ + "\u0505\u0001\u0000\u0000\u0000\u0505\u0503\u0001\u0000\u0000\u0000\u0505"+ + "\u0506\u0001\u0000\u0000\u0000\u0506\u0520\u0001\u0000\u0000\u0000\u0507"+ + "\u0509\u0003\u00bcT\u0000\u0508\u0507\u0001\u0000\u0000\u0000\u0509\u050a"+ + "\u0001\u0000\u0000\u0000\u050a\u0508\u0001\u0000\u0000\u0000\u050a\u050b"+ + "\u0001\u0000\u0000\u0000\u050b\u0513\u0001\u0000\u0000\u0000\u050c\u0510"+ + "\u0003\u00e8j\u0000\u050d\u050f\u0003\u00bcT\u0000\u050e\u050d\u0001\u0000"+ + "\u0000\u0000\u050f\u0512\u0001\u0000\u0000\u0000\u0510\u050e\u0001\u0000"+ + "\u0000\u0000\u0510\u0511\u0001\u0000\u0000\u0000\u0511\u0514\u0001\u0000"+ + "\u0000\u0000\u0512\u0510\u0001\u0000\u0000\u0000\u0513\u050c\u0001\u0000"+ + "\u0000\u0000\u0513\u0514\u0001\u0000\u0000\u0000\u0514\u0515\u0001\u0000"+ + "\u0000\u0000\u0515\u0516\u0003\u00c4X\u0000\u0516\u0520\u0001\u0000\u0000"+ + "\u0000\u0517\u0519\u0003\u00e8j\u0000\u0518\u051a\u0003\u00bcT\u0000\u0519"+ + "\u0518\u0001\u0000\u0000\u0000\u051a\u051b\u0001\u0000\u0000\u0000\u051b"+ + "\u0519\u0001\u0000\u0000\u0000\u051b\u051c\u0001\u0000\u0000\u0000\u051c"+ + "\u051d\u0001\u0000\u0000\u0000\u051d\u051e\u0003\u00c4X\u0000\u051e\u0520"+ + "\u0001\u0000\u0000\u0000\u051f\u04f6\u0001\u0000\u0000\u0000\u051f\u0501"+ + "\u0001\u0000\u0000\u0000\u051f\u0508\u0001\u0000\u0000\u0000\u051f\u0517"+ + "\u0001\u0000\u0000\u0000\u0520\u00d5\u0001\u0000\u0000\u0000\u0521\u0522"+ + "\u0007\u0004\u0000\u0000\u0522\u0523\u0007\u0005\u0000\u0000\u0523\u0524"+ + "\u0007\u0010\u0000\u0000\u0524\u00d7\u0001\u0000\u0000\u0000\u0525\u0526"+ + "\u0007\u0004\u0000\u0000\u0526\u0527\u0007\u0011\u0000\u0000\u0527\u0528"+ + "\u0007\u0002\u0000\u0000\u0528\u00d9\u0001\u0000\u0000\u0000\u0529\u052a"+ + "\u0005=\u0000\u0000\u052a\u00db\u0001\u0000\u0000\u0000\u052b\u052c\u0007"+ + " \u0000\u0000\u052c\u052d\u0007!\u0000\u0000\u052d\u00dd\u0001\u0000\u0000"+ + "\u0000\u052e\u052f\u0005:\u0000\u0000\u052f\u0530\u0005:\u0000\u0000\u0530"+ + "\u00df\u0001\u0000\u0000\u0000\u0531\u0532\u0005:\u0000\u0000\u0532\u00e1"+ + "\u0001\u0000\u0000\u0000\u0533\u0534\u0005;\u0000\u0000\u0534\u00e3\u0001"+ + "\u0000\u0000\u0000\u0535\u0536\u0005,\u0000\u0000\u0536\u00e5\u0001\u0000"+ + "\u0000\u0000\u0537\u0538\u0007\u0010\u0000\u0000\u0538\u0539\u0007\u0007"+ + "\u0000\u0000\u0539\u053a\u0007\u0011\u0000\u0000\u053a\u053b\u0007\u0002"+ + "\u0000\u0000\u053b\u00e7\u0001\u0000\u0000\u0000\u053c\u053d\u0005.\u0000"+ + "\u0000\u053d\u00e9\u0001\u0000\u0000\u0000\u053e\u053f\u0007\u0015\u0000"+ + "\u0000\u053f\u0540\u0007\u0004\u0000\u0000\u0540\u0541\u0007\u000e\u0000"+ + "\u0000\u0541\u0542\u0007\u0011\u0000\u0000\u0542\u0543\u0007\u0007\u0000"+ + "\u0000\u0543\u00eb\u0001\u0000\u0000\u0000\u0544\u0545\u0007\u0015\u0000"+ + "\u0000\u0545\u0546\u0007\n\u0000\u0000\u0546\u0547\u0007\f\u0000\u0000"+ + "\u0547\u0548\u0007\u0011\u0000\u0000\u0548\u0549\u0007\u000b\u0000\u0000"+ + "\u0549\u00ed\u0001\u0000\u0000\u0000\u054a\u054b\u0007\n\u0000\u0000\u054b"+ + "\u054c\u0007\u0005\u0000\u0000\u054c\u00ef\u0001\u0000\u0000\u0000\u054d"+ + "\u054e\u0007\n\u0000\u0000\u054e\u054f\u0007\u0011\u0000\u0000\u054f\u00f1"+ + "\u0001\u0000\u0000\u0000\u0550\u0551\u0007\u000e\u0000\u0000\u0551\u0552"+ + "\u0007\u0004\u0000\u0000\u0552\u0553\u0007\u0011\u0000\u0000\u0553\u0554"+ + "\u0007\u000b\u0000\u0000\u0554\u00f3\u0001\u0000\u0000\u0000\u0555\u0556"+ + "\u0007\u000e\u0000\u0000\u0556\u0557\u0007\n\u0000\u0000\u0557\u0558\u0007"+ + "\u0013\u0000\u0000\u0558\u0559\u0007\u0007\u0000\u0000\u0559\u00f5\u0001"+ + "\u0000\u0000\u0000\u055a\u055b\u0007\u0005\u0000\u0000\u055b\u055c\u0007"+ + "\t\u0000\u0000\u055c\u055d\u0007\u000b\u0000\u0000\u055d\u00f7\u0001\u0000"+ + "\u0000\u0000\u055e\u055f\u0007\u0005\u0000\u0000\u055f\u0560\u0007\u0016"+ + "\u0000\u0000\u0560\u0561\u0007\u000e\u0000\u0000\u0561\u0562\u0007\u000e"+ + "\u0000\u0000\u0562\u00f9\u0001\u0000\u0000\u0000\u0563\u0564\u0007\u0005"+ + "\u0000\u0000\u0564\u0565\u0007\u0016\u0000\u0000\u0565\u0566\u0007\u000e"+ + "\u0000\u0000\u0566\u0567\u0007\u000e\u0000\u0000\u0567\u0568\u0007\u0011"+ + "\u0000\u0000\u0568\u00fb\u0001\u0000\u0000\u0000\u0569\u056a\u0007\t\u0000"+ + "\u0000\u056a\u056b\u0007\u0005\u0000\u0000\u056b\u00fd\u0001\u0000\u0000"+ + "\u0000\u056c\u056d\u0007\t\u0000\u0000\u056d\u056e\u0007\f\u0000\u0000"+ + "\u056e\u00ff\u0001\u0000\u0000\u0000\u056f\u0570\u0005?\u0000\u0000\u0570"+ + "\u0101\u0001\u0000\u0000\u0000\u0571\u0572\u0007\f\u0000\u0000\u0572\u0573"+ + "\u0007\u000e\u0000\u0000\u0573\u0574\u0007\n\u0000\u0000\u0574\u0575\u0007"+ + "\u0013\u0000\u0000\u0575\u0576\u0007\u0007\u0000\u0000\u0576\u0103\u0001"+ + "\u0000\u0000\u0000\u0577\u0578\u0007\u000b\u0000\u0000\u0578\u0579\u0007"+ + "\f\u0000\u0000\u0579\u057a\u0007\u0016\u0000\u0000\u057a\u057b\u0007\u0007"+ + "\u0000\u0000\u057b\u0105\u0001\u0000\u0000\u0000\u057c\u057d\u0007\u0014"+ + "\u0000\u0000\u057d\u057e\u0007\n\u0000\u0000\u057e\u057f\u0007\u000b\u0000"+ + "\u0000\u057f\u0580\u0007\u0003\u0000\u0000\u0580\u0107\u0001\u0000\u0000"+ + "\u0000\u0581\u0582\u0005=\u0000\u0000\u0582\u0583\u0005=\u0000\u0000\u0583"+ + "\u0109\u0001\u0000\u0000\u0000\u0584\u0585\u0005=\u0000\u0000\u0585\u0586"+ + "\u0005~\u0000\u0000\u0586\u010b\u0001\u0000\u0000\u0000\u0587\u0588\u0005"+ + "!\u0000\u0000\u0588\u0589\u0005=\u0000\u0000\u0589\u010d\u0001\u0000\u0000"+ + "\u0000\u058a\u058b\u0005<\u0000\u0000\u058b\u010f\u0001\u0000\u0000\u0000"+ + "\u058c\u058d\u0005<\u0000\u0000\u058d\u058e\u0005=\u0000\u0000\u058e\u0111"+ + "\u0001\u0000\u0000\u0000\u058f\u0590\u0005>\u0000\u0000\u0590\u0113\u0001"+ + "\u0000\u0000\u0000\u0591\u0592\u0005>\u0000\u0000\u0592\u0593\u0005=\u0000"+ + "\u0000\u0593\u0115\u0001\u0000\u0000\u0000\u0594\u0595\u0005+\u0000\u0000"+ + "\u0595\u0117\u0001\u0000\u0000\u0000\u0596\u0597\u0005-\u0000\u0000\u0597"+ + "\u0119\u0001\u0000\u0000\u0000\u0598\u0599\u0005*\u0000\u0000\u0599\u011b"+ + "\u0001\u0000\u0000\u0000\u059a\u059b\u0005/\u0000\u0000\u059b\u011d\u0001"+ + "\u0000\u0000\u0000\u059c\u059d\u0005%\u0000\u0000\u059d\u011f\u0001\u0000"+ + "\u0000\u0000\u059e\u059f\u0005{\u0000\u0000\u059f\u0121\u0001\u0000\u0000"+ + "\u0000\u05a0\u05a1\u0005}\u0000\u0000\u05a1\u0123\u0001\u0000\u0000\u0000"+ + "\u05a2\u05a3\u0005?\u0000\u0000\u05a3\u05a4\u0005?\u0000\u0000\u05a4\u0125"+ + "\u0001\u0000\u0000\u0000\u05a5\u05a6\u00034\u0010\u0000\u05a6\u05a7\u0001"+ + "\u0000\u0000\u0000\u05a7\u05a8\u0006\u0089(\u0000\u05a8\u0127\u0001\u0000"+ + "\u0000\u0000\u05a9\u05ac\u0003\u0100v\u0000\u05aa\u05ad\u0003\u00beU\u0000"+ + "\u05ab\u05ad\u0003\u00cc\\\u0000\u05ac\u05aa\u0001\u0000\u0000\u0000\u05ac"+ + "\u05ab\u0001\u0000\u0000\u0000\u05ad\u05b1\u0001\u0000\u0000\u0000\u05ae"+ + "\u05b0\u0003\u00ce]\u0000\u05af\u05ae\u0001\u0000\u0000\u0000\u05b0\u05b3"+ + "\u0001\u0000\u0000\u0000\u05b1\u05af\u0001\u0000\u0000\u0000\u05b1\u05b2"+ + "\u0001\u0000\u0000\u0000\u05b2\u05bb\u0001\u0000\u0000\u0000\u05b3\u05b1"+ + "\u0001\u0000\u0000\u0000\u05b4\u05b6\u0003\u0100v\u0000\u05b5\u05b7\u0003"+ + "\u00bcT\u0000\u05b6\u05b5\u0001\u0000\u0000\u0000\u05b7\u05b8\u0001\u0000"+ + "\u0000\u0000\u05b8\u05b6\u0001\u0000\u0000\u0000\u05b8\u05b9\u0001\u0000"+ + "\u0000\u0000\u05b9\u05bb\u0001\u0000\u0000\u0000\u05ba\u05a9\u0001\u0000"+ + "\u0000\u0000\u05ba\u05b4\u0001\u0000\u0000\u0000\u05bb\u0129\u0001\u0000"+ + "\u0000\u0000\u05bc\u05bf\u0003\u0124\u0088\u0000\u05bd\u05c0\u0003\u00be"+ + "U\u0000\u05be\u05c0\u0003\u00cc\\\u0000\u05bf\u05bd\u0001\u0000\u0000"+ + "\u0000\u05bf\u05be\u0001\u0000\u0000\u0000\u05c0\u05c4\u0001\u0000\u0000"+ + "\u0000\u05c1\u05c3\u0003\u00ce]\u0000\u05c2\u05c1\u0001\u0000\u0000\u0000"+ + "\u05c3\u05c6\u0001\u0000\u0000\u0000\u05c4\u05c2\u0001\u0000\u0000\u0000"+ + "\u05c4\u05c5\u0001\u0000\u0000\u0000\u05c5\u05ce\u0001\u0000\u0000\u0000"+ + "\u05c6\u05c4\u0001\u0000\u0000\u0000\u05c7\u05c9\u0003\u0124\u0088\u0000"+ + "\u05c8\u05ca\u0003\u00bcT\u0000\u05c9\u05c8\u0001\u0000\u0000\u0000\u05ca"+ + "\u05cb\u0001\u0000\u0000\u0000\u05cb\u05c9\u0001\u0000\u0000\u0000\u05cb"+ + "\u05cc\u0001\u0000\u0000\u0000\u05cc\u05ce\u0001\u0000\u0000\u0000\u05cd"+ + "\u05bc\u0001\u0000\u0000\u0000\u05cd\u05c7\u0001\u0000\u0000\u0000\u05ce"+ + "\u012b\u0001\u0000\u0000\u0000\u05cf\u05d0\u0005[\u0000\u0000\u05d0\u05d1"+ + "\u0001\u0000\u0000\u0000\u05d1\u05d2\u0006\u008c\u0004\u0000\u05d2\u05d3"+ + "\u0006\u008c\u0004\u0000\u05d3\u012d\u0001\u0000\u0000\u0000\u05d4\u05d5"+ + "\u0005]\u0000\u0000\u05d5\u05d6\u0001\u0000\u0000\u0000\u05d6\u05d7\u0006"+ + "\u008d\u0012\u0000\u05d7\u05d8\u0006\u008d\u0012\u0000\u05d8\u012f\u0001"+ + "\u0000\u0000\u0000\u05d9\u05da\u0005(\u0000\u0000\u05da\u05db\u0001\u0000"+ + "\u0000\u0000\u05db\u05dc\u0006\u008e\u0004\u0000\u05dc\u05dd\u0006\u008e"+ + "\u0004\u0000\u05dd\u0131\u0001\u0000\u0000\u0000\u05de\u05df\u0005)\u0000"+ + "\u0000\u05df\u05e0\u0001\u0000\u0000\u0000\u05e0\u05e1\u0006\u008f\u0012"+ + "\u0000\u05e1\u05e2\u0006\u008f\u0012\u0000\u05e2\u0133\u0001\u0000\u0000"+ + "\u0000\u05e3\u05e7\u0003\u00beU\u0000\u05e4\u05e6\u0003\u00ce]\u0000\u05e5"+ + "\u05e4\u0001\u0000\u0000\u0000\u05e6\u05e9\u0001\u0000\u0000\u0000\u05e7"+ + "\u05e5\u0001\u0000\u0000\u0000\u05e7\u05e8\u0001\u0000\u0000\u0000\u05e8"+ + "\u05f4\u0001\u0000\u0000\u0000\u05e9\u05e7\u0001\u0000\u0000\u0000\u05ea"+ + "\u05ed\u0003\u00cc\\\u0000\u05eb\u05ed\u0003\u00c6Y\u0000\u05ec\u05ea"+ + "\u0001\u0000\u0000\u0000\u05ec\u05eb\u0001\u0000\u0000\u0000\u05ed\u05ef"+ + "\u0001\u0000\u0000\u0000\u05ee\u05f0\u0003\u00ce]\u0000\u05ef\u05ee\u0001"+ + "\u0000\u0000\u0000\u05f0\u05f1\u0001\u0000\u0000\u0000\u05f1\u05ef\u0001"+ + "\u0000\u0000\u0000\u05f1\u05f2\u0001\u0000\u0000\u0000\u05f2\u05f4\u0001"+ + "\u0000\u0000\u0000\u05f3\u05e3\u0001\u0000\u0000\u0000\u05f3\u05ec\u0001"+ + "\u0000\u0000\u0000\u05f4\u0135\u0001\u0000\u0000\u0000\u05f5\u05f7\u0003"+ + "\u00c8Z\u0000\u05f6\u05f8\u0003\u00ca[\u0000\u05f7\u05f6\u0001\u0000\u0000"+ + "\u0000\u05f8\u05f9\u0001\u0000\u0000\u0000\u05f9\u05f7\u0001\u0000\u0000"+ + "\u0000\u05f9\u05fa\u0001\u0000\u0000\u0000\u05fa\u05fb\u0001\u0000\u0000"+ + "\u0000\u05fb\u05fc\u0003\u00c8Z\u0000\u05fc\u0137\u0001\u0000\u0000\u0000"+ + "\u05fd\u05fe\u0003\u0136\u0091\u0000\u05fe\u0139\u0001\u0000\u0000\u0000"+ + "\u05ff\u0600\u0003\u0014\u0000\u0000\u0600\u0601\u0001\u0000\u0000\u0000"+ + "\u0601\u0602\u0006\u0093\u0000\u0000\u0602\u013b\u0001\u0000\u0000\u0000"+ + "\u0603\u0604\u0003\u0016\u0001\u0000\u0604\u0605\u0001\u0000\u0000\u0000"+ + "\u0605\u0606\u0006\u0094\u0000\u0000\u0606\u013d\u0001\u0000\u0000\u0000"+ + "\u0607\u0608\u0003\u0018\u0002\u0000\u0608\u0609\u0001\u0000\u0000\u0000"+ + "\u0609\u060a\u0006\u0095\u0000\u0000\u060a\u013f\u0001\u0000\u0000\u0000"+ + "\u060b\u060c\u0003\u00baS\u0000\u060c\u060d\u0001\u0000\u0000\u0000\u060d"+ + "\u060e\u0006\u0096\u0011\u0000\u060e\u060f\u0006\u0096\u0012\u0000\u060f"+ + "\u0141\u0001\u0000\u0000\u0000\u0610\u0611\u0003\u00e0f\u0000\u0611\u0612"+ + "\u0001\u0000\u0000\u0000\u0612\u0613\u0006\u0097)\u0000\u0613\u0143\u0001"+ + "\u0000\u0000\u0000\u0614\u0615\u0003\u00dee\u0000\u0615\u0616\u0001\u0000"+ + "\u0000\u0000\u0616\u0617\u0006\u0098*\u0000\u0617\u0145\u0001\u0000\u0000"+ + "\u0000\u0618\u0619\u0003\u00e4h\u0000\u0619\u061a\u0001\u0000\u0000\u0000"+ + "\u061a\u061b\u0006\u0099\u0017\u0000\u061b\u0147\u0001\u0000\u0000\u0000"+ + "\u061c\u061d\u0003\u00dac\u0000\u061d\u061e\u0001\u0000\u0000\u0000\u061e"+ + "\u061f\u0006\u009a \u0000\u061f\u0149\u0001\u0000\u0000\u0000\u0620\u0621"+ + "\u0007\u000f\u0000\u0000\u0621\u0622\u0007\u0007\u0000\u0000\u0622\u0623"+ + "\u0007\u000b\u0000\u0000\u0623\u0624\u0007\u0004\u0000\u0000\u0624\u0625"+ + "\u0007\u0010\u0000\u0000\u0625\u0626\u0007\u0004\u0000\u0000\u0626\u0627"+ + "\u0007\u000b\u0000\u0000\u0627\u0628\u0007\u0004\u0000\u0000\u0628\u014b"+ + "\u0001\u0000\u0000\u0000\u0629\u062a\u0003\u0132\u008f\u0000\u062a\u062b"+ + "\u0001\u0000\u0000\u0000\u062b\u062c\u0006\u009c\u0013\u0000\u062c\u062d"+ + "\u0006\u009c\u0012\u0000\u062d\u062e\u0006\u009c\u0012\u0000\u062e\u014d"+ + "\u0001\u0000\u0000\u0000\u062f\u0630\u0003\u0130\u008e\u0000\u0630\u0631"+ + "\u0001\u0000\u0000\u0000\u0631\u0632\u0006\u009d&\u0000\u0632\u0633\u0006"+ + "\u009d\'\u0000\u0633\u014f\u0001\u0000\u0000\u0000\u0634\u0638\b\"\u0000"+ + "\u0000\u0635\u0636\u0005/\u0000\u0000\u0636\u0638\b#\u0000\u0000\u0637"+ + "\u0634\u0001\u0000\u0000\u0000\u0637\u0635\u0001\u0000\u0000\u0000\u0638"+ + "\u0151\u0001\u0000\u0000\u0000\u0639\u063b\u0003\u0150\u009e\u0000\u063a"+ + "\u0639\u0001\u0000\u0000\u0000\u063b\u063c\u0001\u0000\u0000\u0000\u063c"+ + "\u063a\u0001\u0000\u0000\u0000\u063c\u063d\u0001\u0000\u0000\u0000\u063d"+ + "\u0153\u0001\u0000\u0000\u0000\u063e\u063f\u0003\u0152\u009f\u0000\u063f"+ + "\u0640\u0001\u0000\u0000\u0000\u0640\u0641\u0006\u00a0+\u0000\u0641\u0155"+ + "\u0001\u0000\u0000\u0000\u0642\u0643\u0003\u00d0^\u0000\u0643\u0644\u0001"+ + "\u0000\u0000\u0000\u0644\u0645\u0006\u00a1\u001f\u0000\u0645\u0157\u0001"+ + "\u0000\u0000\u0000\u0646\u0647\u0003\u0014\u0000\u0000\u0647\u0648\u0001"+ + "\u0000\u0000\u0000\u0648\u0649\u0006\u00a2\u0000\u0000\u0649\u0159\u0001"+ + "\u0000\u0000\u0000\u064a\u064b\u0003\u0016\u0001\u0000\u064b\u064c\u0001"+ + "\u0000\u0000\u0000\u064c\u064d\u0006\u00a3\u0000\u0000\u064d\u015b\u0001"+ + "\u0000\u0000\u0000\u064e\u064f\u0003\u0018\u0002\u0000\u064f\u0650\u0001"+ + "\u0000\u0000\u0000\u0650\u0651\u0006\u00a4\u0000\u0000\u0651\u015d\u0001"+ + "\u0000\u0000\u0000\u0652\u0653\u0003\u0130\u008e\u0000\u0653\u0654\u0001"+ + "\u0000\u0000\u0000\u0654\u0655\u0006\u00a5&\u0000\u0655\u0656\u0006\u00a5"+ + "\'\u0000\u0656\u015f\u0001\u0000\u0000\u0000\u0657\u0658\u0003\u0132\u008f"+ + "\u0000\u0658\u0659\u0001\u0000\u0000\u0000\u0659\u065a\u0006\u00a6\u0013"+ + "\u0000\u065a\u065b\u0006\u00a6\u0012\u0000\u065b\u065c\u0006\u00a6\u0012"+ + "\u0000\u065c\u0161\u0001\u0000\u0000\u0000\u065d\u065e\u0003\u00baS\u0000"+ + "\u065e\u065f\u0001\u0000\u0000\u0000\u065f\u0660\u0006\u00a7\u0011\u0000"+ + "\u0660\u0661\u0006\u00a7\u0012\u0000\u0661\u0163\u0001\u0000\u0000\u0000"+ + "\u0662\u0663\u0003\u0018\u0002\u0000\u0663\u0664\u0001\u0000\u0000\u0000"+ + "\u0664\u0665\u0006\u00a8\u0000\u0000\u0665\u0165\u0001\u0000\u0000\u0000"+ + "\u0666\u0667\u0003\u0014\u0000\u0000\u0667\u0668\u0001\u0000\u0000\u0000"+ + "\u0668\u0669\u0006\u00a9\u0000\u0000\u0669\u0167\u0001\u0000\u0000\u0000"+ + "\u066a\u066b\u0003\u0016\u0001\u0000\u066b\u066c\u0001\u0000\u0000\u0000"+ + "\u066c\u066d\u0006\u00aa\u0000\u0000\u066d\u0169\u0001\u0000\u0000\u0000"+ + "\u066e\u066f\u0003\u00baS\u0000\u066f\u0670\u0001\u0000\u0000\u0000\u0670"+ + "\u0671\u0006\u00ab\u0011\u0000\u0671\u0672\u0006\u00ab\u0012\u0000\u0672"+ + "\u016b\u0001\u0000\u0000\u0000\u0673\u0674\u0003\u0132\u008f\u0000\u0674"+ + "\u0675\u0001\u0000\u0000\u0000\u0675\u0676\u0006\u00ac\u0013\u0000\u0676"+ + "\u0677\u0006\u00ac\u0012\u0000\u0677\u0678\u0006\u00ac\u0012\u0000\u0678"+ + "\u016d\u0001\u0000\u0000\u0000\u0679\u067a\u0007\u0006\u0000\u0000\u067a"+ + "\u067b\u0007\f\u0000\u0000\u067b\u067c\u0007\t\u0000\u0000\u067c\u067d"+ + "\u0007\u0016\u0000\u0000\u067d\u067e\u0007\b\u0000\u0000\u067e\u016f\u0001"+ + "\u0000\u0000\u0000\u067f\u0680\u0007\u0011\u0000\u0000\u0680\u0681\u0007"+ + "\u0002\u0000\u0000\u0681\u0682\u0007\t\u0000\u0000\u0682\u0683\u0007\f"+ + "\u0000\u0000\u0683\u0684\u0007\u0007\u0000\u0000\u0684\u0171\u0001\u0000"+ + "\u0000\u0000\u0685\u0686\u0007\u0013\u0000\u0000\u0686\u0687\u0007\u0007"+ + "\u0000\u0000\u0687\u0688\u0007!\u0000\u0000\u0688\u0173\u0001\u0000\u0000"+ + "\u0000\u0689\u068a\u0003\u0106y\u0000\u068a\u068b\u0001\u0000\u0000\u0000"+ + "\u068b\u068c\u0006\u00b0\u001d\u0000\u068c\u068d\u0006\u00b0\u0012\u0000"+ + "\u068d\u068e\u0006\u00b0\u0004\u0000\u068e\u0175\u0001\u0000\u0000\u0000"+ + "\u068f\u0690\u0003\u00e4h\u0000\u0690\u0691\u0001\u0000\u0000\u0000\u0691"+ + "\u0692\u0006\u00b1\u0017\u0000\u0692\u0177\u0001\u0000\u0000\u0000\u0693"+ + "\u0694\u0003\u00e8j\u0000\u0694\u0695\u0001\u0000\u0000\u0000\u0695\u0696"+ + "\u0006\u00b2\u0016\u0000\u0696\u0179\u0001\u0000\u0000\u0000\u0697\u0698"+ + "\u0003\u0100v\u0000\u0698\u0699\u0001\u0000\u0000\u0000\u0699\u069a\u0006"+ + "\u00b3\"\u0000\u069a\u017b\u0001\u0000\u0000\u0000\u069b\u069c\u0003\u0128"+ + "\u008a\u0000\u069c\u069d\u0001\u0000\u0000\u0000\u069d\u069e\u0006\u00b4"+ + "#\u0000\u069e\u017d\u0001\u0000\u0000\u0000\u069f\u06a0\u0003\u0124\u0088"+ + "\u0000\u06a0\u06a1\u0001\u0000\u0000\u0000\u06a1\u06a2\u0006\u00b5$\u0000"+ + "\u06a2\u017f\u0001\u0000\u0000\u0000\u06a3\u06a4\u0003\u012a\u008b\u0000"+ + "\u06a4\u06a5\u0001\u0000\u0000\u0000\u06a5\u06a6\u0006\u00b6%\u0000\u06a6"+ + "\u0181\u0001\u0000\u0000\u0000\u06a7\u06a8\u0003\u00dcd\u0000\u06a8\u06a9"+ + "\u0001\u0000\u0000\u0000\u06a9\u06aa\u0006\u00b7,\u0000\u06aa\u0183\u0001"+ + "\u0000\u0000\u0000\u06ab\u06ac\u0003\u0138\u0092\u0000\u06ac\u06ad\u0001"+ + "\u0000\u0000\u0000\u06ad\u06ae\u0006\u00b8\u001a\u0000\u06ae\u0185\u0001"+ + "\u0000\u0000\u0000\u06af\u06b0\u0003\u0134\u0090\u0000\u06b0\u06b1\u0001"+ + "\u0000\u0000\u0000\u06b1\u06b2\u0006\u00b9\u001b\u0000\u06b2\u0187\u0001"+ + "\u0000\u0000\u0000\u06b3\u06b4\u0003\u0014\u0000\u0000\u06b4\u06b5\u0001"+ + "\u0000\u0000\u0000\u06b5\u06b6\u0006\u00ba\u0000\u0000\u06b6\u0189\u0001"+ + "\u0000\u0000\u0000\u06b7\u06b8\u0003\u0016\u0001\u0000\u06b8\u06b9\u0001"+ + "\u0000\u0000\u0000\u06b9\u06ba\u0006\u00bb\u0000\u0000\u06ba\u018b\u0001"+ + "\u0000\u0000\u0000\u06bb\u06bc\u0003\u0018\u0002\u0000\u06bc\u06bd\u0001"+ + "\u0000\u0000\u0000\u06bd\u06be\u0006\u00bc\u0000\u0000\u06be\u018d\u0001"+ + "\u0000\u0000\u0000\u06bf\u06c0\u0007\u0011\u0000\u0000\u06c0\u06c1\u0007"+ + "\u000b\u0000\u0000\u06c1\u06c2\u0007\u0004\u0000\u0000\u06c2\u06c3\u0007"+ + "\u000b\u0000\u0000\u06c3\u06c4\u0007\u0011\u0000\u0000\u06c4\u06c5\u0001"+ + "\u0000\u0000\u0000\u06c5\u06c6\u0006\u00bd\u0012\u0000\u06c6\u06c7\u0006"+ + "\u00bd\u0004\u0000\u06c7\u018f\u0001\u0000\u0000\u0000\u06c8\u06c9\u0003"+ + "\u0014\u0000\u0000\u06c9\u06ca\u0001\u0000\u0000\u0000\u06ca\u06cb\u0006"+ + "\u00be\u0000\u0000\u06cb\u0191\u0001\u0000\u0000\u0000\u06cc\u06cd\u0003"+ + "\u0016\u0001\u0000\u06cd\u06ce\u0001\u0000\u0000\u0000\u06ce\u06cf\u0006"+ + "\u00bf\u0000\u0000\u06cf\u0193\u0001\u0000\u0000\u0000\u06d0\u06d1\u0003"+ + "\u0018\u0002\u0000\u06d1\u06d2\u0001\u0000\u0000\u0000\u06d2\u06d3\u0006"+ + "\u00c0\u0000\u0000\u06d3\u0195\u0001\u0000\u0000\u0000\u06d4\u06d5\u0003"+ + "\u00baS\u0000\u06d5\u06d6\u0001\u0000\u0000\u0000\u06d6\u06d7\u0006\u00c1"+ + "\u0011\u0000\u06d7\u06d8\u0006\u00c1\u0012\u0000\u06d8\u0197\u0001\u0000"+ + "\u0000\u0000\u06d9\u06da\u0007$\u0000\u0000\u06da\u06db\u0007\t\u0000"+ + "\u0000\u06db\u06dc\u0007\n\u0000\u0000\u06dc\u06dd\u0007\u0005\u0000\u0000"+ + "\u06dd\u0199\u0001\u0000\u0000\u0000\u06de\u06df\u0003\u024a\u011b\u0000"+ + "\u06df\u06e0\u0001\u0000\u0000\u0000\u06e0\u06e1\u0006\u00c3\u0015\u0000"+ + "\u06e1\u019b\u0001\u0000\u0000\u0000\u06e2\u06e3\u0003\u00fct\u0000\u06e3"+ + "\u06e4\u0001\u0000\u0000\u0000\u06e4\u06e5\u0006\u00c4\u0014\u0000\u06e5"+ + "\u06e6\u0006\u00c4\u0012\u0000\u06e6\u06e7\u0006\u00c4\u0004\u0000\u06e7"+ + "\u019d\u0001\u0000\u0000\u0000\u06e8\u06e9\u0007\u0016\u0000\u0000\u06e9"+ + "\u06ea\u0007\u0011\u0000\u0000\u06ea\u06eb\u0007\n\u0000\u0000\u06eb\u06ec"+ + "\u0007\u0005\u0000\u0000\u06ec\u06ed\u0007\u0006\u0000\u0000\u06ed\u06ee"+ + "\u0001\u0000\u0000\u0000\u06ee\u06ef\u0006\u00c5\u0012\u0000\u06ef\u06f0"+ + "\u0006\u00c5\u0004\u0000\u06f0\u019f\u0001\u0000\u0000\u0000\u06f1\u06f2"+ + "\u0003\u0152\u009f\u0000\u06f2\u06f3\u0001\u0000\u0000\u0000\u06f3\u06f4"+ + "\u0006\u00c6+\u0000\u06f4\u01a1\u0001\u0000\u0000\u0000\u06f5\u06f6\u0003"+ + "\u00d0^\u0000\u06f6\u06f7\u0001\u0000\u0000\u0000\u06f7\u06f8\u0006\u00c7"+ + "\u001f\u0000\u06f8\u01a3\u0001\u0000\u0000\u0000\u06f9\u06fa\u0003\u00e0"+ + "f\u0000\u06fa\u06fb\u0001\u0000\u0000\u0000\u06fb\u06fc\u0006\u00c8)\u0000"+ + "\u06fc\u01a5\u0001\u0000\u0000\u0000\u06fd\u06fe\u0003\u0014\u0000\u0000"+ + "\u06fe\u06ff\u0001\u0000\u0000\u0000\u06ff\u0700\u0006\u00c9\u0000\u0000"+ + "\u0700\u01a7\u0001\u0000\u0000\u0000\u0701\u0702\u0003\u0016\u0001\u0000"+ + "\u0702\u0703\u0001\u0000\u0000\u0000\u0703\u0704\u0006\u00ca\u0000\u0000"+ + "\u0704\u01a9\u0001\u0000\u0000\u0000\u0705\u0706\u0003\u0018\u0002\u0000"+ + "\u0706\u0707\u0001\u0000\u0000\u0000\u0707\u0708\u0006\u00cb\u0000\u0000"+ + "\u0708\u01ab\u0001\u0000\u0000\u0000\u0709\u070a\u0003\u00baS\u0000\u070a"+ + "\u070b\u0001\u0000\u0000\u0000\u070b\u070c\u0006\u00cc\u0011\u0000\u070c"+ + "\u070d\u0006\u00cc\u0012\u0000\u070d\u01ad\u0001\u0000\u0000\u0000\u070e"+ + "\u070f\u0003\u0132\u008f\u0000\u070f\u0710\u0001\u0000\u0000\u0000\u0710"+ + "\u0711\u0006\u00cd\u0013\u0000\u0711\u0712\u0006\u00cd\u0012\u0000\u0712"+ + "\u0713\u0006\u00cd\u0012\u0000\u0713\u01af\u0001\u0000\u0000\u0000\u0714"+ + "\u0715\u0003\u00e0f\u0000\u0715\u0716\u0001\u0000\u0000\u0000\u0716\u0717"+ + "\u0006\u00ce)\u0000\u0717\u01b1\u0001\u0000\u0000\u0000\u0718\u0719\u0003"+ + "\u00e4h\u0000\u0719\u071a\u0001\u0000\u0000\u0000\u071a\u071b\u0006\u00cf"+ + "\u0017\u0000\u071b\u01b3\u0001\u0000\u0000\u0000\u071c\u071d\u0003\u00e8"+ + "j\u0000\u071d\u071e\u0001\u0000\u0000\u0000\u071e\u071f\u0006\u00d0\u0016"+ + "\u0000\u071f\u01b5\u0001\u0000\u0000\u0000\u0720\u0721\u0003\u00fct\u0000"+ + "\u0721\u0722\u0001\u0000\u0000\u0000\u0722\u0723\u0006\u00d1\u0014\u0000"+ + "\u0723\u0724\u0006\u00d1-\u0000\u0724\u01b7\u0001\u0000\u0000\u0000\u0725"+ + "\u0726\u0003\u0152\u009f\u0000\u0726\u0727\u0001\u0000\u0000\u0000\u0727"+ + "\u0728\u0006\u00d2+\u0000\u0728\u01b9\u0001\u0000\u0000\u0000\u0729\u072a"+ + "\u0003\u00d0^\u0000\u072a\u072b\u0001\u0000\u0000\u0000\u072b\u072c\u0006"+ + "\u00d3\u001f\u0000\u072c\u01bb\u0001\u0000\u0000\u0000\u072d\u072e\u0003"+ + "\u0014\u0000\u0000\u072e\u072f\u0001\u0000\u0000\u0000\u072f\u0730\u0006"+ + "\u00d4\u0000\u0000\u0730\u01bd\u0001\u0000\u0000\u0000\u0731\u0732\u0003"+ + "\u0016\u0001\u0000\u0732\u0733\u0001\u0000\u0000\u0000\u0733\u0734\u0006"+ + "\u00d5\u0000\u0000\u0734\u01bf\u0001\u0000\u0000\u0000\u0735\u0736\u0003"+ + "\u0018\u0002\u0000\u0736\u0737\u0001\u0000\u0000\u0000\u0737\u0738\u0006"+ + "\u00d6\u0000\u0000\u0738\u01c1\u0001\u0000\u0000\u0000\u0739\u073a\u0003"+ + "\u00baS\u0000\u073a\u073b\u0001\u0000\u0000\u0000\u073b\u073c\u0006\u00d7"+ + "\u0011\u0000\u073c\u073d\u0006\u00d7\u0012\u0000\u073d\u073e\u0006\u00d7"+ + "\u0012\u0000\u073e\u01c3\u0001\u0000\u0000\u0000\u073f\u0740\u0003\u0132"+ + "\u008f\u0000\u0740\u0741\u0001\u0000\u0000\u0000\u0741\u0742\u0006\u00d8"+ + "\u0013\u0000\u0742\u0743\u0006\u00d8\u0012\u0000\u0743\u0744\u0006\u00d8"+ + "\u0012\u0000\u0744\u0745\u0006\u00d8\u0012\u0000\u0745\u01c5\u0001\u0000"+ + "\u0000\u0000\u0746\u0747\u0003\u00e4h\u0000\u0747\u0748\u0001\u0000\u0000"+ + "\u0000\u0748\u0749\u0006\u00d9\u0017\u0000\u0749\u01c7\u0001\u0000\u0000"+ + "\u0000\u074a\u074b\u0003\u00e8j\u0000\u074b\u074c\u0001\u0000\u0000\u0000"+ + "\u074c\u074d\u0006\u00da\u0016\u0000\u074d\u01c9\u0001\u0000\u0000\u0000"+ + "\u074e\u074f\u0003\u0206\u00f9\u0000\u074f\u0750\u0001\u0000\u0000\u0000"+ + "\u0750\u0751\u0006\u00db!\u0000\u0751\u01cb\u0001\u0000\u0000\u0000\u0752"+ + "\u0753\u0003\u0014\u0000\u0000\u0753\u0754\u0001\u0000\u0000\u0000\u0754"+ + "\u0755\u0006\u00dc\u0000\u0000\u0755\u01cd\u0001\u0000\u0000\u0000\u0756"+ + "\u0757\u0003\u0016\u0001\u0000\u0757\u0758\u0001\u0000\u0000\u0000\u0758"+ + "\u0759\u0006\u00dd\u0000\u0000\u0759\u01cf\u0001\u0000\u0000\u0000\u075a"+ + "\u075b\u0003\u0018\u0002\u0000\u075b\u075c\u0001\u0000\u0000\u0000\u075c"+ + "\u075d\u0006\u00de\u0000\u0000\u075d\u01d1\u0001\u0000\u0000\u0000\u075e"+ + "\u075f\u0003\u00baS\u0000\u075f\u0760\u0001\u0000\u0000\u0000\u0760\u0761"+ + "\u0006\u00df\u0011\u0000\u0761\u0762\u0006\u00df\u0012\u0000\u0762\u01d3"+ + "\u0001\u0000\u0000\u0000\u0763\u0764\u0003\u0132\u008f\u0000\u0764\u0765"+ + "\u0001\u0000\u0000\u0000\u0765\u0766\u0006\u00e0\u0013\u0000\u0766\u0767"+ + "\u0006\u00e0\u0012\u0000\u0767\u0768\u0006\u00e0\u0012\u0000\u0768\u01d5"+ + "\u0001\u0000\u0000\u0000\u0769\u076a\u0003\u012c\u008c\u0000\u076a\u076b"+ + "\u0001\u0000\u0000\u0000\u076b\u076c\u0006\u00e1\u0018\u0000\u076c\u01d7"+ + "\u0001\u0000\u0000\u0000\u076d\u076e\u0003\u012e\u008d\u0000\u076e\u076f"+ + "\u0001\u0000\u0000\u0000\u076f\u0770\u0006\u00e2\u0019\u0000\u0770\u01d9"+ + "\u0001\u0000\u0000\u0000\u0771\u0772\u0003\u00e8j\u0000\u0772\u0773\u0001"+ + "\u0000\u0000\u0000\u0773\u0774\u0006\u00e3\u0016\u0000\u0774\u01db\u0001"+ + "\u0000\u0000\u0000\u0775\u0776\u0003\u0100v\u0000\u0776\u0777\u0001\u0000"+ + "\u0000\u0000\u0777\u0778\u0006\u00e4\"\u0000\u0778\u01dd\u0001\u0000\u0000"+ + "\u0000\u0779\u077a\u0003\u0128\u008a\u0000\u077a\u077b\u0001\u0000\u0000"+ + "\u0000\u077b\u077c\u0006\u00e5#\u0000\u077c\u01df\u0001\u0000\u0000\u0000"+ + "\u077d\u077e\u0003\u0124\u0088\u0000\u077e\u077f\u0001\u0000\u0000\u0000"+ + "\u077f\u0780\u0006\u00e6$\u0000\u0780\u01e1\u0001\u0000\u0000\u0000\u0781"+ + "\u0782\u0003\u012a\u008b\u0000\u0782\u0783\u0001\u0000\u0000\u0000\u0783"+ + "\u0784\u0006\u00e7%\u0000\u0784\u01e3\u0001\u0000\u0000\u0000\u0785\u0786"+ + "\u0003\u0138\u0092\u0000\u0786\u0787\u0001\u0000\u0000\u0000\u0787\u0788"+ + "\u0006\u00e8\u001a\u0000\u0788\u01e5\u0001\u0000\u0000\u0000\u0789\u078a"+ + "\u0003\u0134\u0090\u0000\u078a\u078b\u0001\u0000\u0000\u0000\u078b\u078c"+ + "\u0006\u00e9\u001b\u0000\u078c\u01e7\u0001\u0000\u0000\u0000\u078d\u078e"+ + "\u0003\u0014\u0000\u0000\u078e\u078f\u0001\u0000\u0000\u0000\u078f\u0790"+ + "\u0006\u00ea\u0000\u0000\u0790\u01e9\u0001\u0000\u0000\u0000\u0791\u0792"+ + "\u0003\u0016\u0001\u0000\u0792\u0793\u0001\u0000\u0000\u0000\u0793\u0794"+ + "\u0006\u00eb\u0000\u0000\u0794\u01eb\u0001\u0000\u0000\u0000\u0795\u0796"+ + "\u0003\u0018\u0002\u0000\u0796\u0797\u0001\u0000\u0000\u0000\u0797\u0798"+ + "\u0006\u00ec\u0000\u0000\u0798\u01ed\u0001\u0000\u0000\u0000\u0799\u079a"+ + "\u0003\u00baS\u0000\u079a\u079b\u0001\u0000\u0000\u0000\u079b\u079c\u0006"+ + "\u00ed\u0011\u0000\u079c\u079d\u0006\u00ed\u0012\u0000\u079d\u01ef\u0001"+ + "\u0000\u0000\u0000\u079e\u079f\u0003\u0132\u008f\u0000\u079f\u07a0\u0001"+ + "\u0000\u0000\u0000\u07a0\u07a1\u0006\u00ee\u0013\u0000\u07a1\u07a2\u0006"+ + "\u00ee\u0012\u0000\u07a2\u07a3\u0006\u00ee\u0012\u0000\u07a3\u01f1\u0001"+ + "\u0000\u0000\u0000\u07a4\u07a5\u0003\u00e8j\u0000\u07a5\u07a6\u0001\u0000"+ + "\u0000\u0000\u07a6\u07a7\u0006\u00ef\u0016\u0000\u07a7\u01f3\u0001\u0000"+ + "\u0000\u0000\u07a8\u07a9\u0003\u012c\u008c\u0000\u07a9\u07aa\u0001\u0000"+ + "\u0000\u0000\u07aa\u07ab\u0006\u00f0\u0018\u0000\u07ab\u01f5\u0001\u0000"+ + "\u0000\u0000\u07ac\u07ad\u0003\u012e\u008d\u0000\u07ad\u07ae\u0001\u0000"+ + "\u0000\u0000\u07ae\u07af\u0006\u00f1\u0019\u0000\u07af\u01f7\u0001\u0000"+ + "\u0000\u0000\u07b0\u07b1\u0003\u00e4h\u0000\u07b1\u07b2\u0001\u0000\u0000"+ + "\u0000\u07b2\u07b3\u0006\u00f2\u0017\u0000\u07b3\u01f9\u0001\u0000\u0000"+ + "\u0000\u07b4\u07b5\u0003\u0100v\u0000\u07b5\u07b6\u0001\u0000\u0000\u0000"+ + "\u07b6\u07b7\u0006\u00f3\"\u0000\u07b7\u01fb\u0001\u0000\u0000\u0000\u07b8"+ + "\u07b9\u0003\u0128\u008a\u0000\u07b9\u07ba\u0001\u0000\u0000\u0000\u07ba"+ + "\u07bb\u0006\u00f4#\u0000\u07bb\u01fd\u0001\u0000\u0000\u0000\u07bc\u07bd"+ + "\u0003\u0124\u0088\u0000\u07bd\u07be\u0001\u0000\u0000\u0000\u07be\u07bf"+ + "\u0006\u00f5$\u0000\u07bf\u01ff\u0001\u0000\u0000\u0000\u07c0\u07c1\u0003"+ + "\u012a\u008b\u0000\u07c1\u07c2\u0001\u0000\u0000\u0000\u07c2\u07c3\u0006"+ + "\u00f6%\u0000\u07c3\u0201\u0001\u0000\u0000\u0000\u07c4\u07c9\u0003\u00be"+ + "U\u0000\u07c5\u07c9\u0003\u00bcT\u0000\u07c6\u07c9\u0003\u00cc\\\u0000"+ + "\u07c7\u07c9\u0003\u011a\u0083\u0000\u07c8\u07c4\u0001\u0000\u0000\u0000"+ + "\u07c8\u07c5\u0001\u0000\u0000\u0000\u07c8\u07c6\u0001\u0000\u0000\u0000"+ + "\u07c8\u07c7\u0001\u0000\u0000\u0000\u07c9\u0203\u0001\u0000\u0000\u0000"+ + "\u07ca\u07cd\u0003\u00beU\u0000\u07cb\u07cd\u0003\u011a\u0083\u0000\u07cc"+ + "\u07ca\u0001\u0000\u0000\u0000\u07cc\u07cb\u0001\u0000\u0000\u0000\u07cd"+ + "\u07d1\u0001\u0000\u0000\u0000\u07ce\u07d0\u0003\u0202\u00f7\u0000\u07cf"+ + "\u07ce\u0001\u0000\u0000\u0000\u07d0\u07d3\u0001\u0000\u0000\u0000\u07d1"+ + "\u07cf\u0001\u0000\u0000\u0000\u07d1\u07d2\u0001\u0000\u0000\u0000\u07d2"+ + "\u07de\u0001\u0000\u0000\u0000\u07d3\u07d1\u0001\u0000\u0000\u0000\u07d4"+ + "\u07d7\u0003\u00cc\\\u0000\u07d5\u07d7\u0003\u00c6Y\u0000\u07d6\u07d4"+ + "\u0001\u0000\u0000\u0000\u07d6\u07d5\u0001\u0000\u0000\u0000\u07d7\u07d9"+ + "\u0001\u0000\u0000\u0000\u07d8\u07da\u0003\u0202\u00f7\u0000\u07d9\u07d8"+ + "\u0001\u0000\u0000\u0000\u07da\u07db\u0001\u0000\u0000\u0000\u07db\u07d9"+ + "\u0001\u0000\u0000\u0000\u07db\u07dc\u0001\u0000\u0000\u0000\u07dc\u07de"+ + "\u0001\u0000\u0000\u0000\u07dd\u07cc\u0001\u0000\u0000\u0000\u07dd\u07d6"+ + "\u0001\u0000\u0000\u0000\u07de\u0205\u0001\u0000\u0000\u0000\u07df\u07e2"+ + "\u0003\u0204\u00f8\u0000\u07e0\u07e2\u0003\u0136\u0091\u0000\u07e1\u07df"+ + "\u0001\u0000\u0000\u0000\u07e1\u07e0\u0001\u0000\u0000\u0000\u07e2\u07e3"+ + "\u0001\u0000\u0000\u0000\u07e3\u07e1\u0001\u0000\u0000\u0000\u07e3\u07e4"+ + "\u0001\u0000\u0000\u0000\u07e4\u0207\u0001\u0000\u0000\u0000\u07e5\u07e6"+ + "\u0003\u0014\u0000\u0000\u07e6\u07e7\u0001\u0000\u0000\u0000\u07e7\u07e8"+ + "\u0006\u00fa\u0000\u0000\u07e8\u0209\u0001\u0000\u0000\u0000\u07e9\u07ea"+ + "\u0003\u0016\u0001\u0000\u07ea\u07eb\u0001\u0000\u0000\u0000\u07eb\u07ec"+ + "\u0006\u00fb\u0000\u0000\u07ec\u020b\u0001\u0000\u0000\u0000\u07ed\u07ee"+ + "\u0003\u0018\u0002\u0000\u07ee\u07ef\u0001\u0000\u0000\u0000\u07ef\u07f0"+ + "\u0006\u00fc\u0000\u0000\u07f0\u020d\u0001\u0000\u0000\u0000\u07f1\u07f5"+ + "\u0007%\u0000\u0000\u07f2\u07f4\u0007&\u0000\u0000\u07f3\u07f2\u0001\u0000"+ + "\u0000\u0000\u07f4\u07f7\u0001\u0000\u0000\u0000\u07f5\u07f3\u0001\u0000"+ + "\u0000\u0000\u07f5\u07f6\u0001\u0000\u0000\u0000\u07f6\u07ff\u0001\u0000"+ + "\u0000\u0000\u07f7\u07f5\u0001\u0000\u0000\u0000\u07f8\u07fa\u0007\'\u0000"+ + "\u0000\u07f9\u07fb\u0007&\u0000\u0000\u07fa\u07f9\u0001\u0000\u0000\u0000"+ + "\u07fb\u07fc\u0001\u0000\u0000\u0000\u07fc\u07fa\u0001\u0000\u0000\u0000"+ + "\u07fc\u07fd\u0001\u0000\u0000\u0000\u07fd\u07ff\u0001\u0000\u0000\u0000"+ + "\u07fe\u07f1\u0001\u0000\u0000\u0000\u07fe\u07f8\u0001\u0000\u0000\u0000"+ + "\u07ff\u020f\u0001\u0000\u0000\u0000\u0800\u0801\u0003\u00d0^\u0000\u0801"+ + "\u0802\u0001\u0000\u0000\u0000\u0802\u0803\u0006\u00fe\u001f\u0000\u0803"+ + "\u0211\u0001\u0000\u0000\u0000\u0804\u0805\u0003\u0138\u0092\u0000\u0805"+ + "\u0806\u0001\u0000\u0000\u0000\u0806\u0807\u0006\u00ff\u001a\u0000\u0807"+ + "\u0213\u0001\u0000\u0000\u0000\u0808\u0809\u0003\u0128\u008a\u0000\u0809"+ + "\u080a\u0001\u0000\u0000\u0000\u080a\u080b\u0006\u0100#\u0000\u080b\u0215"+ + "\u0001\u0000\u0000\u0000\u080c\u080d\u0003\u00baS\u0000\u080d\u080e\u0001"+ + "\u0000\u0000\u0000\u080e\u080f\u0006\u0101\u0011\u0000\u080f\u0810\u0006"+ + "\u0101\u0012\u0000\u0810\u0217\u0001\u0000\u0000\u0000\u0811\u0812\u0003"+ + "\u0130\u008e\u0000\u0812\u0813\u0006\u0102.\u0000\u0813\u0814\u0001\u0000"+ + "\u0000\u0000\u0814\u0815\u0006\u0102&\u0000\u0815\u0816\u0006\u0102/\u0000"+ + "\u0816\u0219\u0001\u0000\u0000\u0000\u0817\u0818\u0003\u0014\u0000\u0000"+ + "\u0818\u0819\u0001\u0000\u0000\u0000\u0819\u081a\u0006\u0103\u0000\u0000"+ + "\u081a\u021b\u0001\u0000\u0000\u0000\u081b\u081c\u0003\u0016\u0001\u0000"+ + "\u081c\u081d\u0001\u0000\u0000\u0000\u081d\u081e\u0006\u0104\u0000\u0000"+ + "\u081e\u021d\u0001\u0000\u0000\u0000\u081f\u0820\u0003\u0018\u0002\u0000"+ + "\u0820\u0821\u0001\u0000\u0000\u0000\u0821\u0822\u0006\u0105\u0000\u0000"+ + "\u0822\u021f\u0001\u0000\u0000\u0000\u0823\u0824\u0005(\u0000\u0000\u0824"+ + "\u0825\u0006\u01060\u0000\u0825\u0826\u0001\u0000\u0000\u0000\u0826\u0827"+ + "\u0006\u0106&\u0000\u0827\u0221\u0001\u0000\u0000\u0000\u0828\u082c\u0003"+ + "\u0224\u0108\u0000\u0829\u082c\u0003\u0226\u0109\u0000\u082a\u082c\b("+ + "\u0000\u0000\u082b\u0828\u0001\u0000\u0000\u0000\u082b\u0829\u0001\u0000"+ + "\u0000\u0000\u082b\u082a\u0001\u0000\u0000\u0000\u082c\u082d\u0001\u0000"+ + "\u0000\u0000\u082d\u082b\u0001\u0000\u0000\u0000\u082d\u082e\u0001\u0000"+ + "\u0000\u0000\u082e\u0223\u0001\u0000\u0000\u0000\u082f\u0835\u0005\"\u0000"+ + "\u0000\u0830\u0831\u0005\\\u0000\u0000\u0831\u0834\t\u0000\u0000\u0000"+ + "\u0832\u0834\b)\u0000\u0000\u0833\u0830\u0001\u0000\u0000\u0000\u0833"+ + "\u0832\u0001\u0000\u0000\u0000\u0834\u0837\u0001\u0000\u0000\u0000\u0835"+ + "\u0833\u0001\u0000\u0000\u0000\u0835\u0836\u0001\u0000\u0000\u0000\u0836"+ + "\u0838\u0001\u0000\u0000\u0000\u0837\u0835\u0001\u0000\u0000\u0000\u0838"+ + "\u084c\u0005\"\u0000\u0000\u0839\u083f\u0005\'\u0000\u0000\u083a\u083b"+ + "\u0005\\\u0000\u0000\u083b\u083e\t\u0000\u0000\u0000\u083c\u083e\b*\u0000"+ + "\u0000\u083d\u083a\u0001\u0000\u0000\u0000\u083d\u083c\u0001\u0000\u0000"+ + "\u0000\u083e\u0841\u0001\u0000\u0000\u0000\u083f\u083d\u0001\u0000\u0000"+ + "\u0000\u083f\u0840\u0001\u0000\u0000\u0000\u0840\u0842\u0001\u0000\u0000"+ + "\u0000\u0841\u083f\u0001\u0000\u0000\u0000\u0842\u084c\u0005\'\u0000\u0000"+ + "\u0843\u0847\u0005`\u0000\u0000\u0844\u0846\b\u001f\u0000\u0000\u0845"+ + "\u0844\u0001\u0000\u0000\u0000\u0846\u0849\u0001\u0000\u0000\u0000\u0847"+ + "\u0845\u0001\u0000\u0000\u0000\u0847\u0848\u0001\u0000\u0000\u0000\u0848"+ + "\u084a\u0001\u0000\u0000\u0000\u0849\u0847\u0001\u0000\u0000\u0000\u084a"+ + "\u084c\u0005`\u0000\u0000\u084b\u082f\u0001\u0000\u0000\u0000\u084b\u0839"+ + "\u0001\u0000\u0000\u0000\u084b\u0843\u0001\u0000\u0000\u0000\u084c\u0225"+ + "\u0001\u0000\u0000\u0000\u084d\u0851\u0005#\u0000\u0000\u084e\u0850\b"+ + "\u0000\u0000\u0000\u084f\u084e\u0001\u0000\u0000\u0000\u0850\u0853\u0001"+ + "\u0000\u0000\u0000\u0851\u084f\u0001\u0000\u0000\u0000\u0851\u0852\u0001"+ + "\u0000\u0000\u0000\u0852\u0855\u0001\u0000\u0000\u0000\u0853\u0851\u0001"+ + "\u0000\u0000\u0000\u0854\u0856\u0005\r\u0000\u0000\u0855\u0854\u0001\u0000"+ + "\u0000\u0000\u0855\u0856\u0001\u0000\u0000\u0000\u0856\u0858\u0001\u0000"+ + "\u0000\u0000\u0857\u0859\u0005\n\u0000\u0000\u0858\u0857\u0001\u0000\u0000"+ + "\u0000\u0858\u0859\u0001\u0000\u0000\u0000\u0859\u0227\u0001\u0000\u0000"+ + "\u0000\u085a\u085b\u0005)\u0000\u0000\u085b\u085c\u0004\u010a\u0007\u0000"+ + "\u085c\u085d\u0006\u010a1\u0000\u085d\u085e\u0001\u0000\u0000\u0000\u085e"+ + "\u085f\u0006\u010a\u0013\u0000\u085f\u0229\u0001\u0000\u0000\u0000\u0860"+ + "\u0861\u0005)\u0000\u0000\u0861\u0862\u0004\u010b\b\u0000\u0862\u0863"+ + "\u0006\u010b2\u0000\u0863\u0864\u0001\u0000\u0000\u0000\u0864\u0865\u0006"+ + "\u010b\u0013\u0000\u0865\u0866\u0006\u010b\u0012\u0000\u0866\u0867\u0006"+ + "\u010b\u0012\u0000\u0867\u022b\u0001\u0000\u0000\u0000\u0868\u0869\u0003"+ + "\u00baS\u0000\u0869\u086a\u0001\u0000\u0000\u0000\u086a\u086b\u0006\u010c"+ + "\u0011\u0000\u086b\u086c\u0006\u010c\u0012\u0000\u086c\u086d\u0006\u010c"+ + "\u0012\u0000\u086d\u022d\u0001\u0000\u0000\u0000\u086e\u086f\u0003\u0014"+ + "\u0000\u0000\u086f\u0870\u0001\u0000\u0000\u0000\u0870\u0871\u0006\u010d"+ + "\u0000\u0000\u0871\u022f\u0001\u0000\u0000\u0000\u0872\u0873\u0003\u0016"+ + "\u0001\u0000\u0873\u0874\u0001\u0000\u0000\u0000\u0874\u0875\u0006\u010e"+ + "\u0000\u0000\u0875\u0231\u0001\u0000\u0000\u0000\u0876\u0877\u0003\u0018"+ + "\u0002\u0000\u0877\u0878\u0001\u0000\u0000\u0000\u0878\u0879\u0006\u010f"+ + "\u0000\u0000\u0879\u0233\u0001\u0000\u0000\u0000\u087a\u087b\u0003\u00ba"+ + "S\u0000\u087b\u087c\u0001\u0000\u0000\u0000\u087c\u087d\u0006\u0110\u0011"+ + "\u0000\u087d\u087e\u0006\u0110\u0012\u0000\u087e\u0235\u0001\u0000\u0000"+ + "\u0000\u087f\u0880\u0003\u0132\u008f\u0000\u0880\u0881\u0001\u0000\u0000"+ + "\u0000\u0881\u0882\u0006\u0111\u0013\u0000\u0882\u0883\u0006\u0111\u0012"+ + "\u0000\u0883\u0884\u0006\u0111\u0012\u0000\u0884\u0237\u0001\u0000\u0000"+ + "\u0000\u0885\u0886\u0003\u012c\u008c\u0000\u0886\u0887\u0001\u0000\u0000"+ + "\u0000\u0887\u0888\u0006\u0112\u0018\u0000\u0888\u0239\u0001\u0000\u0000"+ + "\u0000\u0889\u088a\u0003\u012e\u008d\u0000\u088a\u088b\u0001\u0000\u0000"+ + "\u0000\u088b\u088c\u0006\u0113\u0019\u0000\u088c\u023b\u0001\u0000\u0000"+ + "\u0000\u088d\u088e\u0003\u00dac\u0000\u088e\u088f\u0001\u0000\u0000\u0000"+ + "\u088f\u0890\u0006\u0114 \u0000\u0890\u023d\u0001\u0000\u0000\u0000\u0891"+ + "\u0892\u0003\u00e4h\u0000\u0892\u0893\u0001\u0000\u0000\u0000\u0893\u0894"+ + "\u0006\u0115\u0017\u0000\u0894\u023f\u0001\u0000\u0000\u0000\u0895\u0896"+ + "\u0003\u00e8j\u0000\u0896\u0897\u0001\u0000\u0000\u0000\u0897\u0898\u0006"+ + "\u0116\u0016\u0000\u0898\u0241\u0001\u0000\u0000\u0000\u0899\u089a\u0003"+ + "\u0100v\u0000\u089a\u089b\u0001\u0000\u0000\u0000\u089b\u089c\u0006\u0117"+ + "\"\u0000\u089c\u0243\u0001\u0000\u0000\u0000\u089d\u089e\u0003\u0128\u008a"+ + "\u0000\u089e\u089f\u0001\u0000\u0000\u0000\u089f\u08a0\u0006\u0118#\u0000"+ + "\u08a0\u0245\u0001\u0000\u0000\u0000\u08a1\u08a2\u0003\u0124\u0088\u0000"+ + "\u08a2\u08a3\u0001\u0000\u0000\u0000\u08a3\u08a4\u0006\u0119$\u0000\u08a4"+ + "\u0247\u0001\u0000\u0000\u0000\u08a5\u08a6\u0003\u012a\u008b\u0000\u08a6"+ + "\u08a7\u0001\u0000\u0000\u0000\u08a7\u08a8\u0006\u011a%\u0000\u08a8\u0249"+ + "\u0001\u0000\u0000\u0000\u08a9\u08aa\u0007\u0004\u0000\u0000\u08aa\u08ab"+ + "\u0007\u0011\u0000\u0000\u08ab\u024b\u0001\u0000\u0000\u0000\u08ac\u08ad"+ + "\u0003\u0206\u00f9\u0000\u08ad\u08ae\u0001\u0000\u0000\u0000\u08ae\u08af"+ + "\u0006\u011c!\u0000\u08af\u024d\u0001\u0000\u0000\u0000\u08b0\u08b1\u0003"+ + "\u0014\u0000\u0000\u08b1\u08b2\u0001\u0000\u0000\u0000\u08b2\u08b3\u0006"+ + "\u011d\u0000\u0000\u08b3\u024f\u0001\u0000\u0000\u0000\u08b4\u08b5\u0003"+ + "\u0016\u0001\u0000\u08b5\u08b6\u0001\u0000\u0000\u0000\u08b6\u08b7\u0006"+ + "\u011e\u0000\u0000\u08b7\u0251\u0001\u0000\u0000\u0000\u08b8\u08b9\u0003"+ + "\u0018\u0002\u0000\u08b9\u08ba\u0001\u0000\u0000\u0000\u08ba\u08bb\u0006"+ + "\u011f\u0000\u0000\u08bb\u0253\u0001\u0000\u0000\u0000\u08bc\u08bd\u0003"+ + "\u0104x\u0000\u08bd\u08be\u0001\u0000\u0000\u0000\u08be\u08bf\u0006\u0120"+ + "3\u0000\u08bf\u0255\u0001\u0000\u0000\u0000\u08c0\u08c1\u0003\u00eak\u0000"+ + "\u08c1\u08c2\u0001\u0000\u0000\u0000\u08c2\u08c3\u0006\u01214\u0000\u08c3"+ + "\u0257\u0001\u0000\u0000\u0000\u08c4\u08c5\u0003\u00f8r\u0000\u08c5\u08c6"+ + "\u0001\u0000\u0000\u0000\u08c6\u08c7\u0006\u01225\u0000\u08c7\u0259\u0001"+ + "\u0000\u0000\u0000\u08c8\u08c9\u0003\u00e2g\u0000\u08c9\u08ca\u0001\u0000"+ + "\u0000\u0000\u08ca\u08cb\u0006\u01236\u0000\u08cb\u08cc\u0006\u0123\u0012"+ + "\u0000\u08cc\u025b\u0001\u0000\u0000\u0000\u08cd\u08ce\u0003\u00dac\u0000"+ + "\u08ce\u08cf\u0001\u0000\u0000\u0000\u08cf\u08d0\u0006\u0124 \u0000\u08d0"+ + "\u025d\u0001\u0000\u0000\u0000\u08d1\u08d2\u0003\u00d0^\u0000\u08d2\u08d3"+ + "\u0001\u0000\u0000\u0000\u08d3\u08d4\u0006\u0125\u001f\u0000\u08d4\u025f"+ + "\u0001\u0000\u0000\u0000\u08d5\u08d6\u0003\u0134\u0090\u0000\u08d6\u08d7"+ + "\u0001\u0000\u0000\u0000\u08d7\u08d8\u0006\u0126\u001b\u0000\u08d8\u0261"+ + "\u0001\u0000\u0000\u0000\u08d9\u08da\u0003\u0138\u0092\u0000\u08da\u08db"+ + "\u0001\u0000\u0000\u0000\u08db\u08dc\u0006\u0127\u001a\u0000\u08dc\u0263"+ + "\u0001\u0000\u0000\u0000\u08dd\u08de\u0003\u00d4`\u0000\u08de\u08df\u0001"+ + "\u0000\u0000\u0000\u08df\u08e0\u0006\u01287\u0000\u08e0\u0265\u0001\u0000"+ + "\u0000\u0000\u08e1\u08e2\u0003\u00d2_\u0000\u08e2\u08e3\u0001\u0000\u0000"+ + "\u0000\u08e3\u08e4\u0006\u01298\u0000\u08e4\u0267\u0001\u0000\u0000\u0000"+ + "\u08e5\u08e6\u0003\u00e4h\u0000\u08e6\u08e7\u0001\u0000\u0000\u0000\u08e7"+ + "\u08e8\u0006\u012a\u0017\u0000\u08e8\u0269\u0001\u0000\u0000\u0000\u08e9"+ + "\u08ea\u0003\u00e8j\u0000\u08ea\u08eb\u0001\u0000\u0000\u0000\u08eb\u08ec"+ + "\u0006\u012b\u0016\u0000\u08ec\u026b\u0001\u0000\u0000\u0000\u08ed\u08ee"+ + "\u0003\u0100v\u0000\u08ee\u08ef\u0001\u0000\u0000\u0000\u08ef\u08f0\u0006"+ + "\u012c\"\u0000\u08f0\u026d\u0001\u0000\u0000\u0000\u08f1\u08f2\u0003\u0128"+ + "\u008a\u0000\u08f2\u08f3\u0001\u0000\u0000\u0000\u08f3\u08f4\u0006\u012d"+ + "#\u0000\u08f4\u026f\u0001\u0000\u0000\u0000\u08f5\u08f6\u0003\u0124\u0088"+ + "\u0000\u08f6\u08f7\u0001\u0000\u0000\u0000\u08f7\u08f8\u0006\u012e$\u0000"+ + "\u08f8\u0271\u0001\u0000\u0000\u0000\u08f9\u08fa\u0003\u012a\u008b\u0000"+ + "\u08fa\u08fb\u0001\u0000\u0000\u0000\u08fb\u08fc\u0006\u012f%\u0000\u08fc"+ + "\u0273\u0001\u0000\u0000\u0000\u08fd\u08fe\u0003\u012c\u008c\u0000\u08fe"+ + "\u08ff\u0001\u0000\u0000\u0000\u08ff\u0900\u0006\u0130\u0018\u0000\u0900"+ + "\u0275\u0001\u0000\u0000\u0000\u0901\u0902\u0003\u012e\u008d\u0000\u0902"+ + "\u0903\u0001\u0000\u0000\u0000\u0903\u0904\u0006\u0131\u0019\u0000\u0904"+ + "\u0277\u0001\u0000\u0000\u0000\u0905\u0906\u0003\u0206\u00f9\u0000\u0906"+ + "\u0907\u0001\u0000\u0000\u0000\u0907\u0908\u0006\u0132!\u0000\u0908\u0279"+ + "\u0001\u0000\u0000\u0000\u0909\u090a\u0003\u0014\u0000\u0000\u090a\u090b"+ + "\u0001\u0000\u0000\u0000\u090b\u090c\u0006\u0133\u0000\u0000\u090c\u027b"+ + "\u0001\u0000\u0000\u0000\u090d\u090e\u0003\u0016\u0001\u0000\u090e\u090f"+ + "\u0001\u0000\u0000\u0000\u090f\u0910\u0006\u0134\u0000\u0000\u0910\u027d"+ + "\u0001\u0000\u0000\u0000\u0911\u0912\u0003\u0018\u0002\u0000\u0912\u0913"+ + "\u0001\u0000\u0000\u0000\u0913\u0914\u0006\u0135\u0000\u0000\u0914\u027f"+ + "\u0001\u0000\u0000\u0000\u0915\u0916\u0003\u00baS\u0000\u0916\u0917\u0001"+ + "\u0000\u0000\u0000\u0917\u0918\u0006\u0136\u0011\u0000\u0918\u0919\u0006"+ + "\u0136\u0012\u0000\u0919\u0281\u0001\u0000\u0000\u0000\u091a\u091b\u0007"+ + "\n\u0000\u0000\u091b\u091c\u0007\u0005\u0000\u0000\u091c\u091d\u0007\u0015"+ + "\u0000\u0000\u091d\u091e\u0007\t\u0000\u0000\u091e\u0283\u0001\u0000\u0000"+ + "\u0000\u091f\u0920\u0003\u0014\u0000\u0000\u0920\u0921\u0001\u0000\u0000"+ + "\u0000\u0921\u0922\u0006\u0138\u0000\u0000\u0922\u0285\u0001\u0000\u0000"+ + "\u0000\u0923\u0924\u0003\u0016\u0001\u0000\u0924\u0925\u0001\u0000\u0000"+ + "\u0000\u0925\u0926\u0006\u0139\u0000\u0000\u0926\u0287\u0001\u0000\u0000"+ + "\u0000\u0927\u0928\u0003\u0018\u0002\u0000\u0928\u0929\u0001\u0000\u0000"+ + "\u0000\u0929\u092a\u0006\u013a\u0000\u0000\u092a\u0289\u0001\u0000\u0000"+ + "\u0000V\u0000\u0001\u0002\u0003\u0004\u0005\u0006\u0007\b\t\n\u000b\f"+ + "\r\u000e\u000f\u0010\u0011\u0012\u0013\u0290\u0294\u0297\u02a0\u02a2\u02ad"+ + "\u03d8\u042d\u0431\u0436\u04ba\u04bf\u04c8\u04cf\u04d4\u04d6\u04e1\u04e9"+ + "\u04ec\u04ee\u04f3\u04f8\u04fe\u0505\u050a\u0510\u0513\u051b\u051f\u05ac"+ + "\u05b1\u05b8\u05ba\u05bf\u05c4\u05cb\u05cd\u05e7\u05ec\u05f1\u05f3\u05f9"+ + "\u0637\u063c\u07c8\u07cc\u07d1\u07d6\u07db\u07dd\u07e1\u07e3\u07f5\u07fc"+ + "\u07fe\u082b\u082d\u0833\u0835\u083d\u083f\u0847\u084b\u0851\u0855\u0858"+ + "9\u0000\u0001\u0000\u0005\u0001\u0000\u0005\u0002\u0000\u0005\u0004\u0000"+ + "\u0005\u0005\u0000\u0005\u0006\u0000\u0005\u0007\u0000\u0005\b\u0000\u0005"+ + "\t\u0000\u0005\n\u0000\u0005\u000b\u0000\u0005\r\u0000\u0005\u000e\u0000"+ + "\u0005\u000f\u0000\u0005\u0011\u0000\u0005\u0012\u0000\u0005\u0013\u0000"+ + "\u00073\u0000\u0004\u0000\u0000\u0007d\u0000\u0007J\u0000\u0007\u0096"+ + "\u0000\u0007@\u0000\u0007>\u0000\u0007a\u0000\u0007b\u0000\u0007f\u0000"+ + "\u0007e\u0000\u0005\u0003\u0000\u0007O\u0000\u0007)\u0000\u00074\u0000"+ + "\u00079\u0000\u0007\u008a\u0000\u0007L\u0000\u0007_\u0000\u0007^\u0000"+ + "\u0007`\u0000\u0007c\u0000\u0005\u0000\u0000\u0007\u0011\u0000\u0007<"+ + "\u0000\u0007;\u0000\u0007k\u0000\u0007:\u0000\u0005\f\u0000\u0001\u0102"+ + "\u0000\u0005\u0010\u0000\u0001\u0106\u0001\u0001\u010a\u0002\u0001\u010b"+ + "\u0003\u0007N\u0000\u0007A\u0000\u0007H\u0000\u0007=\u0000\u00076\u0000"+ + "\u00075\u0000"; public static final ATN _ATN = new ATNDeserializer().deserialize(_serializedATN.toCharArray()); static { diff --git a/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/parser/EsqlBaseParser.interp b/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/parser/EsqlBaseParser.interp index 3c357d48cef9a..c485b449c52d5 100644 --- a/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/parser/EsqlBaseParser.interp +++ b/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/parser/EsqlBaseParser.interp @@ -32,6 +32,7 @@ null 'drop' 'keep' null +null 'rename' 'set' 'show' @@ -140,6 +141,14 @@ null null null null +null +null +null +null +null +null +null +null 'as' null null @@ -186,6 +195,7 @@ MV_EXPAND DROP KEEP DEV_INSIST +DEV_PROMQL RENAME SET SHOW @@ -294,6 +304,14 @@ ID_PATTERN PROJECT_LINE_COMMENT PROJECT_MULTILINE_COMMENT PROJECT_WS +PROMQL_UNQUOTED_IDENTIFIER +PROMQL_PARAMS_LINE_COMMENT +PROMQL_PARAMS_MULTILINE_COMMENT +PROMQL_PARAMS_WS +PROMQL_QUERY_TEXT +PROMQL_QUERY_LINE_COMMENT +PROMQL_QUERY_MULTILINE_COMMENT +PROMQL_QUERY_WS AS RENAME_LINE_COMMENT RENAME_MULTILINE_COMMENT @@ -400,7 +418,11 @@ comparisonOperator joinCommand joinTarget joinCondition +promqlCommand +promqlParam +promqlParamContent +promqlQueryPart atn: -[4, 1, 151, 941, 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, 2, 26, 7, 26, 2, 27, 7, 27, 2, 28, 7, 28, 2, 29, 7, 29, 2, 30, 7, 30, 2, 31, 7, 31, 2, 32, 7, 32, 2, 33, 7, 33, 2, 34, 7, 34, 2, 35, 7, 35, 2, 36, 7, 36, 2, 37, 7, 37, 2, 38, 7, 38, 2, 39, 7, 39, 2, 40, 7, 40, 2, 41, 7, 41, 2, 42, 7, 42, 2, 43, 7, 43, 2, 44, 7, 44, 2, 45, 7, 45, 2, 46, 7, 46, 2, 47, 7, 47, 2, 48, 7, 48, 2, 49, 7, 49, 2, 50, 7, 50, 2, 51, 7, 51, 2, 52, 7, 52, 2, 53, 7, 53, 2, 54, 7, 54, 2, 55, 7, 55, 2, 56, 7, 56, 2, 57, 7, 57, 2, 58, 7, 58, 2, 59, 7, 59, 2, 60, 7, 60, 2, 61, 7, 61, 2, 62, 7, 62, 2, 63, 7, 63, 2, 64, 7, 64, 2, 65, 7, 65, 2, 66, 7, 66, 2, 67, 7, 67, 2, 68, 7, 68, 2, 69, 7, 69, 2, 70, 7, 70, 2, 71, 7, 71, 2, 72, 7, 72, 2, 73, 7, 73, 2, 74, 7, 74, 2, 75, 7, 75, 2, 76, 7, 76, 2, 77, 7, 77, 2, 78, 7, 78, 2, 79, 7, 79, 2, 80, 7, 80, 2, 81, 7, 81, 2, 82, 7, 82, 2, 83, 7, 83, 2, 84, 7, 84, 2, 85, 7, 85, 2, 86, 7, 86, 2, 87, 7, 87, 2, 88, 7, 88, 2, 89, 7, 89, 2, 90, 7, 90, 2, 91, 7, 91, 2, 92, 7, 92, 1, 0, 5, 0, 188, 8, 0, 10, 0, 12, 0, 191, 9, 0, 1, 0, 1, 0, 1, 0, 1, 1, 1, 1, 1, 1, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 5, 2, 205, 8, 2, 10, 2, 12, 2, 208, 9, 2, 1, 3, 1, 3, 1, 3, 1, 3, 1, 3, 1, 3, 3, 3, 216, 8, 3, 1, 4, 1, 4, 1, 4, 1, 4, 1, 4, 1, 4, 1, 4, 1, 4, 1, 4, 1, 4, 1, 4, 1, 4, 1, 4, 1, 4, 1, 4, 1, 4, 1, 4, 1, 4, 1, 4, 1, 4, 1, 4, 1, 4, 1, 4, 1, 4, 3, 4, 242, 8, 4, 1, 5, 1, 5, 1, 5, 1, 6, 1, 6, 1, 7, 1, 7, 1, 7, 1, 8, 1, 8, 1, 8, 5, 8, 255, 8, 8, 10, 8, 12, 8, 258, 9, 8, 1, 9, 1, 9, 1, 9, 3, 9, 263, 8, 9, 1, 9, 1, 9, 1, 10, 1, 10, 1, 10, 5, 10, 270, 8, 10, 10, 10, 12, 10, 273, 9, 10, 1, 11, 1, 11, 1, 11, 3, 11, 278, 8, 11, 1, 12, 1, 12, 1, 12, 1, 13, 1, 13, 1, 13, 1, 14, 1, 14, 1, 14, 5, 14, 289, 8, 14, 10, 14, 12, 14, 292, 9, 14, 1, 14, 3, 14, 295, 8, 14, 1, 15, 1, 15, 1, 15, 3, 15, 300, 8, 15, 1, 16, 1, 16, 1, 16, 1, 16, 5, 16, 306, 8, 16, 10, 16, 12, 16, 309, 9, 16, 1, 16, 1, 16, 1, 17, 1, 17, 1, 17, 1, 17, 1, 17, 1, 17, 1, 17, 1, 17, 1, 17, 3, 17, 322, 8, 17, 1, 18, 1, 18, 1, 19, 1, 19, 1, 20, 1, 20, 1, 21, 1, 21, 1, 22, 1, 22, 1, 22, 1, 22, 5, 22, 336, 8, 22, 10, 22, 12, 22, 339, 9, 22, 1, 23, 1, 23, 1, 23, 1, 24, 1, 24, 3, 24, 346, 8, 24, 1, 24, 1, 24, 3, 24, 350, 8, 24, 1, 25, 1, 25, 1, 25, 5, 25, 355, 8, 25, 10, 25, 12, 25, 358, 9, 25, 1, 26, 1, 26, 1, 26, 3, 26, 363, 8, 26, 1, 27, 1, 27, 1, 27, 3, 27, 368, 8, 27, 1, 27, 1, 27, 1, 27, 1, 27, 1, 27, 1, 27, 1, 27, 3, 27, 377, 8, 27, 1, 28, 1, 28, 1, 28, 5, 28, 382, 8, 28, 10, 28, 12, 28, 385, 9, 28, 1, 29, 1, 29, 1, 29, 3, 29, 390, 8, 29, 1, 29, 1, 29, 1, 29, 1, 29, 1, 29, 1, 29, 1, 29, 3, 29, 399, 8, 29, 1, 30, 1, 30, 1, 30, 5, 30, 404, 8, 30, 10, 30, 12, 30, 407, 9, 30, 1, 31, 1, 31, 1, 31, 5, 31, 412, 8, 31, 10, 31, 12, 31, 415, 9, 31, 1, 32, 1, 32, 1, 33, 1, 33, 1, 33, 3, 33, 422, 8, 33, 1, 34, 1, 34, 3, 34, 426, 8, 34, 1, 35, 1, 35, 3, 35, 430, 8, 35, 1, 36, 1, 36, 1, 36, 3, 36, 435, 8, 36, 1, 37, 1, 37, 1, 37, 1, 38, 1, 38, 1, 38, 1, 38, 5, 38, 444, 8, 38, 10, 38, 12, 38, 447, 9, 38, 1, 39, 1, 39, 3, 39, 451, 8, 39, 1, 39, 1, 39, 3, 39, 455, 8, 39, 1, 40, 1, 40, 1, 40, 1, 41, 1, 41, 1, 41, 1, 42, 1, 42, 1, 42, 1, 42, 5, 42, 467, 8, 42, 10, 42, 12, 42, 470, 9, 42, 1, 43, 1, 43, 1, 43, 1, 43, 1, 43, 1, 43, 1, 43, 1, 43, 3, 43, 480, 8, 43, 1, 44, 1, 44, 1, 44, 1, 44, 3, 44, 486, 8, 44, 1, 45, 1, 45, 1, 45, 5, 45, 491, 8, 45, 10, 45, 12, 45, 494, 9, 45, 1, 46, 1, 46, 1, 46, 1, 46, 1, 47, 1, 47, 3, 47, 502, 8, 47, 1, 48, 1, 48, 1, 48, 1, 48, 1, 48, 5, 48, 509, 8, 48, 10, 48, 12, 48, 512, 9, 48, 1, 49, 1, 49, 1, 49, 1, 50, 1, 50, 1, 50, 1, 51, 1, 51, 1, 51, 1, 51, 1, 52, 1, 52, 1, 52, 1, 53, 1, 53, 1, 53, 1, 53, 3, 53, 531, 8, 53, 1, 53, 1, 53, 1, 53, 1, 53, 5, 53, 537, 8, 53, 10, 53, 12, 53, 540, 9, 53, 3, 53, 542, 8, 53, 1, 54, 1, 54, 1, 55, 1, 55, 1, 55, 3, 55, 549, 8, 55, 1, 55, 1, 55, 1, 56, 1, 56, 1, 56, 1, 57, 1, 57, 1, 57, 1, 57, 3, 57, 560, 8, 57, 1, 57, 1, 57, 1, 57, 1, 57, 1, 57, 3, 57, 567, 8, 57, 1, 58, 1, 58, 1, 58, 1, 59, 4, 59, 573, 8, 59, 11, 59, 12, 59, 574, 1, 60, 1, 60, 1, 60, 1, 60, 1, 61, 1, 61, 1, 61, 1, 61, 1, 61, 1, 61, 5, 61, 587, 8, 61, 10, 61, 12, 61, 590, 9, 61, 1, 62, 1, 62, 1, 63, 1, 63, 1, 63, 1, 63, 3, 63, 598, 8, 63, 1, 63, 1, 63, 1, 63, 1, 63, 1, 63, 1, 64, 1, 64, 1, 64, 1, 64, 3, 64, 609, 8, 64, 1, 64, 1, 64, 1, 64, 1, 65, 1, 65, 1, 65, 1, 65, 1, 65, 3, 65, 619, 8, 65, 1, 65, 1, 65, 1, 65, 1, 65, 3, 65, 625, 8, 65, 3, 65, 627, 8, 65, 1, 66, 1, 66, 3, 66, 631, 8, 66, 1, 66, 5, 66, 634, 8, 66, 10, 66, 12, 66, 637, 9, 66, 1, 67, 1, 67, 1, 67, 1, 67, 1, 67, 1, 67, 1, 67, 1, 67, 1, 67, 1, 67, 1, 67, 3, 67, 650, 8, 67, 1, 68, 1, 68, 1, 68, 1, 68, 1, 68, 1, 69, 1, 69, 1, 69, 1, 70, 1, 70, 1, 70, 1, 70, 1, 71, 1, 71, 1, 71, 1, 71, 1, 72, 1, 72, 1, 72, 1, 72, 1, 72, 1, 72, 1, 72, 3, 72, 675, 8, 72, 1, 72, 1, 72, 1, 72, 1, 72, 1, 72, 5, 72, 682, 8, 72, 10, 72, 12, 72, 685, 9, 72, 1, 72, 1, 72, 1, 72, 1, 72, 1, 72, 3, 72, 692, 8, 72, 1, 72, 1, 72, 1, 72, 3, 72, 697, 8, 72, 1, 72, 1, 72, 1, 72, 1, 72, 1, 72, 1, 72, 5, 72, 705, 8, 72, 10, 72, 12, 72, 708, 9, 72, 1, 73, 1, 73, 3, 73, 712, 8, 73, 1, 73, 1, 73, 1, 73, 1, 73, 1, 73, 3, 73, 719, 8, 73, 1, 73, 1, 73, 1, 73, 1, 73, 1, 73, 3, 73, 726, 8, 73, 1, 73, 1, 73, 1, 73, 1, 73, 1, 73, 5, 73, 733, 8, 73, 10, 73, 12, 73, 736, 9, 73, 1, 73, 1, 73, 1, 73, 1, 73, 3, 73, 742, 8, 73, 1, 73, 1, 73, 1, 73, 1, 73, 1, 73, 5, 73, 749, 8, 73, 10, 73, 12, 73, 752, 9, 73, 1, 73, 1, 73, 3, 73, 756, 8, 73, 1, 74, 1, 74, 1, 74, 3, 74, 761, 8, 74, 1, 74, 1, 74, 1, 74, 1, 75, 1, 75, 1, 75, 1, 75, 1, 75, 3, 75, 771, 8, 75, 1, 76, 1, 76, 1, 76, 1, 76, 3, 76, 777, 8, 76, 1, 76, 1, 76, 1, 76, 1, 76, 1, 76, 1, 76, 5, 76, 785, 8, 76, 10, 76, 12, 76, 788, 9, 76, 1, 77, 1, 77, 1, 77, 1, 77, 1, 77, 1, 77, 1, 77, 1, 77, 3, 77, 798, 8, 77, 1, 77, 1, 77, 1, 77, 5, 77, 803, 8, 77, 10, 77, 12, 77, 806, 9, 77, 1, 78, 1, 78, 1, 78, 1, 78, 1, 78, 1, 78, 5, 78, 814, 8, 78, 10, 78, 12, 78, 817, 9, 78, 1, 78, 1, 78, 3, 78, 821, 8, 78, 3, 78, 823, 8, 78, 1, 78, 1, 78, 1, 79, 1, 79, 1, 79, 3, 79, 830, 8, 79, 1, 80, 1, 80, 1, 80, 1, 80, 5, 80, 836, 8, 80, 10, 80, 12, 80, 839, 9, 80, 3, 80, 841, 8, 80, 1, 80, 1, 80, 1, 81, 1, 81, 1, 81, 1, 81, 1, 82, 1, 82, 3, 82, 851, 8, 82, 1, 83, 1, 83, 1, 83, 1, 83, 1, 83, 1, 83, 1, 83, 1, 83, 1, 83, 1, 83, 1, 83, 1, 83, 1, 83, 5, 83, 866, 8, 83, 10, 83, 12, 83, 869, 9, 83, 1, 83, 1, 83, 1, 83, 1, 83, 1, 83, 1, 83, 5, 83, 877, 8, 83, 10, 83, 12, 83, 880, 9, 83, 1, 83, 1, 83, 1, 83, 1, 83, 1, 83, 1, 83, 5, 83, 888, 8, 83, 10, 83, 12, 83, 891, 9, 83, 1, 83, 1, 83, 3, 83, 895, 8, 83, 1, 84, 1, 84, 1, 85, 1, 85, 3, 85, 901, 8, 85, 1, 86, 3, 86, 904, 8, 86, 1, 86, 1, 86, 1, 87, 3, 87, 909, 8, 87, 1, 87, 1, 87, 1, 88, 1, 88, 1, 89, 1, 89, 1, 90, 1, 90, 1, 90, 1, 90, 1, 90, 1, 91, 1, 91, 1, 91, 3, 91, 925, 8, 91, 1, 91, 1, 91, 1, 91, 3, 91, 930, 8, 91, 1, 92, 1, 92, 1, 92, 1, 92, 5, 92, 936, 8, 92, 10, 92, 12, 92, 939, 9, 92, 1, 92, 0, 5, 4, 122, 144, 152, 154, 93, 0, 2, 4, 6, 8, 10, 12, 14, 16, 18, 20, 22, 24, 26, 28, 30, 32, 34, 36, 38, 40, 42, 44, 46, 48, 50, 52, 54, 56, 58, 60, 62, 64, 66, 68, 70, 72, 74, 76, 78, 80, 82, 84, 86, 88, 90, 92, 94, 96, 98, 100, 102, 104, 106, 108, 110, 112, 114, 116, 118, 120, 122, 124, 126, 128, 130, 132, 134, 136, 138, 140, 142, 144, 146, 148, 150, 152, 154, 156, 158, 160, 162, 164, 166, 168, 170, 172, 174, 176, 178, 180, 182, 184, 0, 10, 2, 0, 51, 51, 106, 106, 1, 0, 100, 101, 2, 0, 55, 55, 62, 62, 2, 0, 65, 65, 68, 68, 2, 0, 40, 40, 51, 51, 1, 0, 86, 87, 1, 0, 88, 90, 2, 0, 64, 64, 77, 77, 2, 0, 79, 79, 81, 85, 2, 0, 24, 24, 26, 27, 984, 0, 189, 1, 0, 0, 0, 2, 195, 1, 0, 0, 0, 4, 198, 1, 0, 0, 0, 6, 215, 1, 0, 0, 0, 8, 241, 1, 0, 0, 0, 10, 243, 1, 0, 0, 0, 12, 246, 1, 0, 0, 0, 14, 248, 1, 0, 0, 0, 16, 251, 1, 0, 0, 0, 18, 262, 1, 0, 0, 0, 20, 266, 1, 0, 0, 0, 22, 274, 1, 0, 0, 0, 24, 279, 1, 0, 0, 0, 26, 282, 1, 0, 0, 0, 28, 285, 1, 0, 0, 0, 30, 299, 1, 0, 0, 0, 32, 301, 1, 0, 0, 0, 34, 321, 1, 0, 0, 0, 36, 323, 1, 0, 0, 0, 38, 325, 1, 0, 0, 0, 40, 327, 1, 0, 0, 0, 42, 329, 1, 0, 0, 0, 44, 331, 1, 0, 0, 0, 46, 340, 1, 0, 0, 0, 48, 343, 1, 0, 0, 0, 50, 351, 1, 0, 0, 0, 52, 359, 1, 0, 0, 0, 54, 376, 1, 0, 0, 0, 56, 378, 1, 0, 0, 0, 58, 398, 1, 0, 0, 0, 60, 400, 1, 0, 0, 0, 62, 408, 1, 0, 0, 0, 64, 416, 1, 0, 0, 0, 66, 421, 1, 0, 0, 0, 68, 425, 1, 0, 0, 0, 70, 429, 1, 0, 0, 0, 72, 434, 1, 0, 0, 0, 74, 436, 1, 0, 0, 0, 76, 439, 1, 0, 0, 0, 78, 448, 1, 0, 0, 0, 80, 456, 1, 0, 0, 0, 82, 459, 1, 0, 0, 0, 84, 462, 1, 0, 0, 0, 86, 479, 1, 0, 0, 0, 88, 481, 1, 0, 0, 0, 90, 487, 1, 0, 0, 0, 92, 495, 1, 0, 0, 0, 94, 501, 1, 0, 0, 0, 96, 503, 1, 0, 0, 0, 98, 513, 1, 0, 0, 0, 100, 516, 1, 0, 0, 0, 102, 519, 1, 0, 0, 0, 104, 523, 1, 0, 0, 0, 106, 526, 1, 0, 0, 0, 108, 543, 1, 0, 0, 0, 110, 548, 1, 0, 0, 0, 112, 552, 1, 0, 0, 0, 114, 555, 1, 0, 0, 0, 116, 568, 1, 0, 0, 0, 118, 572, 1, 0, 0, 0, 120, 576, 1, 0, 0, 0, 122, 580, 1, 0, 0, 0, 124, 591, 1, 0, 0, 0, 126, 593, 1, 0, 0, 0, 128, 604, 1, 0, 0, 0, 130, 626, 1, 0, 0, 0, 132, 628, 1, 0, 0, 0, 134, 649, 1, 0, 0, 0, 136, 651, 1, 0, 0, 0, 138, 656, 1, 0, 0, 0, 140, 659, 1, 0, 0, 0, 142, 663, 1, 0, 0, 0, 144, 696, 1, 0, 0, 0, 146, 755, 1, 0, 0, 0, 148, 757, 1, 0, 0, 0, 150, 770, 1, 0, 0, 0, 152, 776, 1, 0, 0, 0, 154, 797, 1, 0, 0, 0, 156, 807, 1, 0, 0, 0, 158, 829, 1, 0, 0, 0, 160, 831, 1, 0, 0, 0, 162, 844, 1, 0, 0, 0, 164, 850, 1, 0, 0, 0, 166, 894, 1, 0, 0, 0, 168, 896, 1, 0, 0, 0, 170, 900, 1, 0, 0, 0, 172, 903, 1, 0, 0, 0, 174, 908, 1, 0, 0, 0, 176, 912, 1, 0, 0, 0, 178, 914, 1, 0, 0, 0, 180, 916, 1, 0, 0, 0, 182, 929, 1, 0, 0, 0, 184, 931, 1, 0, 0, 0, 186, 188, 3, 140, 70, 0, 187, 186, 1, 0, 0, 0, 188, 191, 1, 0, 0, 0, 189, 187, 1, 0, 0, 0, 189, 190, 1, 0, 0, 0, 190, 192, 1, 0, 0, 0, 191, 189, 1, 0, 0, 0, 192, 193, 3, 2, 1, 0, 193, 194, 5, 0, 0, 1, 194, 1, 1, 0, 0, 0, 195, 196, 3, 4, 2, 0, 196, 197, 5, 0, 0, 1, 197, 3, 1, 0, 0, 0, 198, 199, 6, 2, -1, 0, 199, 200, 3, 6, 3, 0, 200, 206, 1, 0, 0, 0, 201, 202, 10, 1, 0, 0, 202, 203, 5, 50, 0, 0, 203, 205, 3, 8, 4, 0, 204, 201, 1, 0, 0, 0, 205, 208, 1, 0, 0, 0, 206, 204, 1, 0, 0, 0, 206, 207, 1, 0, 0, 0, 207, 5, 1, 0, 0, 0, 208, 206, 1, 0, 0, 0, 209, 216, 3, 24, 12, 0, 210, 216, 3, 14, 7, 0, 211, 216, 3, 104, 52, 0, 212, 216, 3, 26, 13, 0, 213, 214, 4, 3, 1, 0, 214, 216, 3, 100, 50, 0, 215, 209, 1, 0, 0, 0, 215, 210, 1, 0, 0, 0, 215, 211, 1, 0, 0, 0, 215, 212, 1, 0, 0, 0, 215, 213, 1, 0, 0, 0, 216, 7, 1, 0, 0, 0, 217, 242, 3, 46, 23, 0, 218, 242, 3, 10, 5, 0, 219, 242, 3, 80, 40, 0, 220, 242, 3, 74, 37, 0, 221, 242, 3, 48, 24, 0, 222, 242, 3, 76, 38, 0, 223, 242, 3, 82, 41, 0, 224, 242, 3, 84, 42, 0, 225, 242, 3, 88, 44, 0, 226, 242, 3, 96, 48, 0, 227, 242, 3, 106, 53, 0, 228, 242, 3, 98, 49, 0, 229, 242, 3, 180, 90, 0, 230, 242, 3, 114, 57, 0, 231, 242, 3, 128, 64, 0, 232, 242, 3, 112, 56, 0, 233, 242, 3, 116, 58, 0, 234, 242, 3, 126, 63, 0, 235, 242, 3, 130, 65, 0, 236, 242, 3, 132, 66, 0, 237, 238, 4, 4, 2, 0, 238, 242, 3, 136, 68, 0, 239, 240, 4, 4, 3, 0, 240, 242, 3, 138, 69, 0, 241, 217, 1, 0, 0, 0, 241, 218, 1, 0, 0, 0, 241, 219, 1, 0, 0, 0, 241, 220, 1, 0, 0, 0, 241, 221, 1, 0, 0, 0, 241, 222, 1, 0, 0, 0, 241, 223, 1, 0, 0, 0, 241, 224, 1, 0, 0, 0, 241, 225, 1, 0, 0, 0, 241, 226, 1, 0, 0, 0, 241, 227, 1, 0, 0, 0, 241, 228, 1, 0, 0, 0, 241, 229, 1, 0, 0, 0, 241, 230, 1, 0, 0, 0, 241, 231, 1, 0, 0, 0, 241, 232, 1, 0, 0, 0, 241, 233, 1, 0, 0, 0, 241, 234, 1, 0, 0, 0, 241, 235, 1, 0, 0, 0, 241, 236, 1, 0, 0, 0, 241, 237, 1, 0, 0, 0, 241, 239, 1, 0, 0, 0, 242, 9, 1, 0, 0, 0, 243, 244, 5, 17, 0, 0, 244, 245, 3, 144, 72, 0, 245, 11, 1, 0, 0, 0, 246, 247, 3, 64, 32, 0, 247, 13, 1, 0, 0, 0, 248, 249, 5, 13, 0, 0, 249, 250, 3, 16, 8, 0, 250, 15, 1, 0, 0, 0, 251, 256, 3, 18, 9, 0, 252, 253, 5, 61, 0, 0, 253, 255, 3, 18, 9, 0, 254, 252, 1, 0, 0, 0, 255, 258, 1, 0, 0, 0, 256, 254, 1, 0, 0, 0, 256, 257, 1, 0, 0, 0, 257, 17, 1, 0, 0, 0, 258, 256, 1, 0, 0, 0, 259, 260, 3, 54, 27, 0, 260, 261, 5, 56, 0, 0, 261, 263, 1, 0, 0, 0, 262, 259, 1, 0, 0, 0, 262, 263, 1, 0, 0, 0, 263, 264, 1, 0, 0, 0, 264, 265, 3, 144, 72, 0, 265, 19, 1, 0, 0, 0, 266, 271, 3, 22, 11, 0, 267, 268, 5, 61, 0, 0, 268, 270, 3, 22, 11, 0, 269, 267, 1, 0, 0, 0, 270, 273, 1, 0, 0, 0, 271, 269, 1, 0, 0, 0, 271, 272, 1, 0, 0, 0, 272, 21, 1, 0, 0, 0, 273, 271, 1, 0, 0, 0, 274, 277, 3, 54, 27, 0, 275, 276, 5, 56, 0, 0, 276, 278, 3, 144, 72, 0, 277, 275, 1, 0, 0, 0, 277, 278, 1, 0, 0, 0, 278, 23, 1, 0, 0, 0, 279, 280, 5, 18, 0, 0, 280, 281, 3, 28, 14, 0, 281, 25, 1, 0, 0, 0, 282, 283, 5, 19, 0, 0, 283, 284, 3, 28, 14, 0, 284, 27, 1, 0, 0, 0, 285, 290, 3, 30, 15, 0, 286, 287, 5, 61, 0, 0, 287, 289, 3, 30, 15, 0, 288, 286, 1, 0, 0, 0, 289, 292, 1, 0, 0, 0, 290, 288, 1, 0, 0, 0, 290, 291, 1, 0, 0, 0, 291, 294, 1, 0, 0, 0, 292, 290, 1, 0, 0, 0, 293, 295, 3, 44, 22, 0, 294, 293, 1, 0, 0, 0, 294, 295, 1, 0, 0, 0, 295, 29, 1, 0, 0, 0, 296, 300, 3, 34, 17, 0, 297, 298, 4, 15, 4, 0, 298, 300, 3, 32, 16, 0, 299, 296, 1, 0, 0, 0, 299, 297, 1, 0, 0, 0, 300, 31, 1, 0, 0, 0, 301, 302, 5, 98, 0, 0, 302, 307, 3, 24, 12, 0, 303, 304, 5, 50, 0, 0, 304, 306, 3, 8, 4, 0, 305, 303, 1, 0, 0, 0, 306, 309, 1, 0, 0, 0, 307, 305, 1, 0, 0, 0, 307, 308, 1, 0, 0, 0, 308, 310, 1, 0, 0, 0, 309, 307, 1, 0, 0, 0, 310, 311, 5, 99, 0, 0, 311, 33, 1, 0, 0, 0, 312, 313, 3, 36, 18, 0, 313, 314, 5, 59, 0, 0, 314, 315, 3, 40, 20, 0, 315, 322, 1, 0, 0, 0, 316, 317, 3, 40, 20, 0, 317, 318, 5, 58, 0, 0, 318, 319, 3, 38, 19, 0, 319, 322, 1, 0, 0, 0, 320, 322, 3, 42, 21, 0, 321, 312, 1, 0, 0, 0, 321, 316, 1, 0, 0, 0, 321, 320, 1, 0, 0, 0, 322, 35, 1, 0, 0, 0, 323, 324, 5, 106, 0, 0, 324, 37, 1, 0, 0, 0, 325, 326, 5, 106, 0, 0, 326, 39, 1, 0, 0, 0, 327, 328, 5, 106, 0, 0, 328, 41, 1, 0, 0, 0, 329, 330, 7, 0, 0, 0, 330, 43, 1, 0, 0, 0, 331, 332, 5, 105, 0, 0, 332, 337, 5, 106, 0, 0, 333, 334, 5, 61, 0, 0, 334, 336, 5, 106, 0, 0, 335, 333, 1, 0, 0, 0, 336, 339, 1, 0, 0, 0, 337, 335, 1, 0, 0, 0, 337, 338, 1, 0, 0, 0, 338, 45, 1, 0, 0, 0, 339, 337, 1, 0, 0, 0, 340, 341, 5, 9, 0, 0, 341, 342, 3, 16, 8, 0, 342, 47, 1, 0, 0, 0, 343, 345, 5, 16, 0, 0, 344, 346, 3, 50, 25, 0, 345, 344, 1, 0, 0, 0, 345, 346, 1, 0, 0, 0, 346, 349, 1, 0, 0, 0, 347, 348, 5, 57, 0, 0, 348, 350, 3, 16, 8, 0, 349, 347, 1, 0, 0, 0, 349, 350, 1, 0, 0, 0, 350, 49, 1, 0, 0, 0, 351, 356, 3, 52, 26, 0, 352, 353, 5, 61, 0, 0, 353, 355, 3, 52, 26, 0, 354, 352, 1, 0, 0, 0, 355, 358, 1, 0, 0, 0, 356, 354, 1, 0, 0, 0, 356, 357, 1, 0, 0, 0, 357, 51, 1, 0, 0, 0, 358, 356, 1, 0, 0, 0, 359, 362, 3, 18, 9, 0, 360, 361, 5, 17, 0, 0, 361, 363, 3, 144, 72, 0, 362, 360, 1, 0, 0, 0, 362, 363, 1, 0, 0, 0, 363, 53, 1, 0, 0, 0, 364, 365, 4, 27, 5, 0, 365, 367, 5, 96, 0, 0, 366, 368, 5, 100, 0, 0, 367, 366, 1, 0, 0, 0, 367, 368, 1, 0, 0, 0, 368, 369, 1, 0, 0, 0, 369, 370, 5, 97, 0, 0, 370, 371, 5, 63, 0, 0, 371, 372, 5, 96, 0, 0, 372, 373, 3, 56, 28, 0, 373, 374, 5, 97, 0, 0, 374, 377, 1, 0, 0, 0, 375, 377, 3, 56, 28, 0, 376, 364, 1, 0, 0, 0, 376, 375, 1, 0, 0, 0, 377, 55, 1, 0, 0, 0, 378, 383, 3, 72, 36, 0, 379, 380, 5, 63, 0, 0, 380, 382, 3, 72, 36, 0, 381, 379, 1, 0, 0, 0, 382, 385, 1, 0, 0, 0, 383, 381, 1, 0, 0, 0, 383, 384, 1, 0, 0, 0, 384, 57, 1, 0, 0, 0, 385, 383, 1, 0, 0, 0, 386, 387, 4, 29, 6, 0, 387, 389, 5, 96, 0, 0, 388, 390, 5, 137, 0, 0, 389, 388, 1, 0, 0, 0, 389, 390, 1, 0, 0, 0, 390, 391, 1, 0, 0, 0, 391, 392, 5, 97, 0, 0, 392, 393, 5, 63, 0, 0, 393, 394, 5, 96, 0, 0, 394, 395, 3, 60, 30, 0, 395, 396, 5, 97, 0, 0, 396, 399, 1, 0, 0, 0, 397, 399, 3, 60, 30, 0, 398, 386, 1, 0, 0, 0, 398, 397, 1, 0, 0, 0, 399, 59, 1, 0, 0, 0, 400, 405, 3, 66, 33, 0, 401, 402, 5, 63, 0, 0, 402, 404, 3, 66, 33, 0, 403, 401, 1, 0, 0, 0, 404, 407, 1, 0, 0, 0, 405, 403, 1, 0, 0, 0, 405, 406, 1, 0, 0, 0, 406, 61, 1, 0, 0, 0, 407, 405, 1, 0, 0, 0, 408, 413, 3, 58, 29, 0, 409, 410, 5, 61, 0, 0, 410, 412, 3, 58, 29, 0, 411, 409, 1, 0, 0, 0, 412, 415, 1, 0, 0, 0, 413, 411, 1, 0, 0, 0, 413, 414, 1, 0, 0, 0, 414, 63, 1, 0, 0, 0, 415, 413, 1, 0, 0, 0, 416, 417, 7, 1, 0, 0, 417, 65, 1, 0, 0, 0, 418, 422, 5, 137, 0, 0, 419, 422, 3, 68, 34, 0, 420, 422, 3, 70, 35, 0, 421, 418, 1, 0, 0, 0, 421, 419, 1, 0, 0, 0, 421, 420, 1, 0, 0, 0, 422, 67, 1, 0, 0, 0, 423, 426, 5, 75, 0, 0, 424, 426, 5, 94, 0, 0, 425, 423, 1, 0, 0, 0, 425, 424, 1, 0, 0, 0, 426, 69, 1, 0, 0, 0, 427, 430, 5, 93, 0, 0, 428, 430, 5, 95, 0, 0, 429, 427, 1, 0, 0, 0, 429, 428, 1, 0, 0, 0, 430, 71, 1, 0, 0, 0, 431, 435, 3, 64, 32, 0, 432, 435, 3, 68, 34, 0, 433, 435, 3, 70, 35, 0, 434, 431, 1, 0, 0, 0, 434, 432, 1, 0, 0, 0, 434, 433, 1, 0, 0, 0, 435, 73, 1, 0, 0, 0, 436, 437, 5, 11, 0, 0, 437, 438, 3, 166, 83, 0, 438, 75, 1, 0, 0, 0, 439, 440, 5, 15, 0, 0, 440, 445, 3, 78, 39, 0, 441, 442, 5, 61, 0, 0, 442, 444, 3, 78, 39, 0, 443, 441, 1, 0, 0, 0, 444, 447, 1, 0, 0, 0, 445, 443, 1, 0, 0, 0, 445, 446, 1, 0, 0, 0, 446, 77, 1, 0, 0, 0, 447, 445, 1, 0, 0, 0, 448, 450, 3, 144, 72, 0, 449, 451, 7, 2, 0, 0, 450, 449, 1, 0, 0, 0, 450, 451, 1, 0, 0, 0, 451, 454, 1, 0, 0, 0, 452, 453, 5, 72, 0, 0, 453, 455, 7, 3, 0, 0, 454, 452, 1, 0, 0, 0, 454, 455, 1, 0, 0, 0, 455, 79, 1, 0, 0, 0, 456, 457, 5, 31, 0, 0, 457, 458, 3, 62, 31, 0, 458, 81, 1, 0, 0, 0, 459, 460, 5, 30, 0, 0, 460, 461, 3, 62, 31, 0, 461, 83, 1, 0, 0, 0, 462, 463, 5, 33, 0, 0, 463, 468, 3, 86, 43, 0, 464, 465, 5, 61, 0, 0, 465, 467, 3, 86, 43, 0, 466, 464, 1, 0, 0, 0, 467, 470, 1, 0, 0, 0, 468, 466, 1, 0, 0, 0, 468, 469, 1, 0, 0, 0, 469, 85, 1, 0, 0, 0, 470, 468, 1, 0, 0, 0, 471, 472, 3, 58, 29, 0, 472, 473, 5, 141, 0, 0, 473, 474, 3, 58, 29, 0, 474, 480, 1, 0, 0, 0, 475, 476, 3, 58, 29, 0, 476, 477, 5, 56, 0, 0, 477, 478, 3, 58, 29, 0, 478, 480, 1, 0, 0, 0, 479, 471, 1, 0, 0, 0, 479, 475, 1, 0, 0, 0, 480, 87, 1, 0, 0, 0, 481, 482, 5, 8, 0, 0, 482, 483, 3, 154, 77, 0, 483, 485, 3, 176, 88, 0, 484, 486, 3, 90, 45, 0, 485, 484, 1, 0, 0, 0, 485, 486, 1, 0, 0, 0, 486, 89, 1, 0, 0, 0, 487, 492, 3, 92, 46, 0, 488, 489, 5, 61, 0, 0, 489, 491, 3, 92, 46, 0, 490, 488, 1, 0, 0, 0, 491, 494, 1, 0, 0, 0, 492, 490, 1, 0, 0, 0, 492, 493, 1, 0, 0, 0, 493, 91, 1, 0, 0, 0, 494, 492, 1, 0, 0, 0, 495, 496, 3, 64, 32, 0, 496, 497, 5, 56, 0, 0, 497, 498, 3, 166, 83, 0, 498, 93, 1, 0, 0, 0, 499, 500, 5, 78, 0, 0, 500, 502, 3, 160, 80, 0, 501, 499, 1, 0, 0, 0, 501, 502, 1, 0, 0, 0, 502, 95, 1, 0, 0, 0, 503, 504, 5, 10, 0, 0, 504, 505, 3, 154, 77, 0, 505, 510, 3, 176, 88, 0, 506, 507, 5, 61, 0, 0, 507, 509, 3, 176, 88, 0, 508, 506, 1, 0, 0, 0, 509, 512, 1, 0, 0, 0, 510, 508, 1, 0, 0, 0, 510, 511, 1, 0, 0, 0, 511, 97, 1, 0, 0, 0, 512, 510, 1, 0, 0, 0, 513, 514, 5, 29, 0, 0, 514, 515, 3, 54, 27, 0, 515, 99, 1, 0, 0, 0, 516, 517, 5, 6, 0, 0, 517, 518, 3, 102, 51, 0, 518, 101, 1, 0, 0, 0, 519, 520, 5, 98, 0, 0, 520, 521, 3, 4, 2, 0, 521, 522, 5, 99, 0, 0, 522, 103, 1, 0, 0, 0, 523, 524, 5, 35, 0, 0, 524, 525, 5, 148, 0, 0, 525, 105, 1, 0, 0, 0, 526, 527, 5, 5, 0, 0, 527, 530, 3, 108, 54, 0, 528, 529, 5, 73, 0, 0, 529, 531, 3, 58, 29, 0, 530, 528, 1, 0, 0, 0, 530, 531, 1, 0, 0, 0, 531, 541, 1, 0, 0, 0, 532, 533, 5, 78, 0, 0, 533, 538, 3, 110, 55, 0, 534, 535, 5, 61, 0, 0, 535, 537, 3, 110, 55, 0, 536, 534, 1, 0, 0, 0, 537, 540, 1, 0, 0, 0, 538, 536, 1, 0, 0, 0, 538, 539, 1, 0, 0, 0, 539, 542, 1, 0, 0, 0, 540, 538, 1, 0, 0, 0, 541, 532, 1, 0, 0, 0, 541, 542, 1, 0, 0, 0, 542, 107, 1, 0, 0, 0, 543, 544, 7, 4, 0, 0, 544, 109, 1, 0, 0, 0, 545, 546, 3, 58, 29, 0, 546, 547, 5, 56, 0, 0, 547, 549, 1, 0, 0, 0, 548, 545, 1, 0, 0, 0, 548, 549, 1, 0, 0, 0, 549, 550, 1, 0, 0, 0, 550, 551, 3, 58, 29, 0, 551, 111, 1, 0, 0, 0, 552, 553, 5, 14, 0, 0, 553, 554, 3, 166, 83, 0, 554, 113, 1, 0, 0, 0, 555, 556, 5, 4, 0, 0, 556, 559, 3, 54, 27, 0, 557, 558, 5, 73, 0, 0, 558, 560, 3, 54, 27, 0, 559, 557, 1, 0, 0, 0, 559, 560, 1, 0, 0, 0, 560, 566, 1, 0, 0, 0, 561, 562, 5, 141, 0, 0, 562, 563, 3, 54, 27, 0, 563, 564, 5, 61, 0, 0, 564, 565, 3, 54, 27, 0, 565, 567, 1, 0, 0, 0, 566, 561, 1, 0, 0, 0, 566, 567, 1, 0, 0, 0, 567, 115, 1, 0, 0, 0, 568, 569, 5, 20, 0, 0, 569, 570, 3, 118, 59, 0, 570, 117, 1, 0, 0, 0, 571, 573, 3, 120, 60, 0, 572, 571, 1, 0, 0, 0, 573, 574, 1, 0, 0, 0, 574, 572, 1, 0, 0, 0, 574, 575, 1, 0, 0, 0, 575, 119, 1, 0, 0, 0, 576, 577, 5, 98, 0, 0, 577, 578, 3, 122, 61, 0, 578, 579, 5, 99, 0, 0, 579, 121, 1, 0, 0, 0, 580, 581, 6, 61, -1, 0, 581, 582, 3, 124, 62, 0, 582, 588, 1, 0, 0, 0, 583, 584, 10, 1, 0, 0, 584, 585, 5, 50, 0, 0, 585, 587, 3, 124, 62, 0, 586, 583, 1, 0, 0, 0, 587, 590, 1, 0, 0, 0, 588, 586, 1, 0, 0, 0, 588, 589, 1, 0, 0, 0, 589, 123, 1, 0, 0, 0, 590, 588, 1, 0, 0, 0, 591, 592, 3, 8, 4, 0, 592, 125, 1, 0, 0, 0, 593, 597, 5, 12, 0, 0, 594, 595, 3, 54, 27, 0, 595, 596, 5, 56, 0, 0, 596, 598, 1, 0, 0, 0, 597, 594, 1, 0, 0, 0, 597, 598, 1, 0, 0, 0, 598, 599, 1, 0, 0, 0, 599, 600, 3, 166, 83, 0, 600, 601, 5, 73, 0, 0, 601, 602, 3, 20, 10, 0, 602, 603, 3, 94, 47, 0, 603, 127, 1, 0, 0, 0, 604, 608, 5, 7, 0, 0, 605, 606, 3, 54, 27, 0, 606, 607, 5, 56, 0, 0, 607, 609, 1, 0, 0, 0, 608, 605, 1, 0, 0, 0, 608, 609, 1, 0, 0, 0, 609, 610, 1, 0, 0, 0, 610, 611, 3, 154, 77, 0, 611, 612, 3, 94, 47, 0, 612, 129, 1, 0, 0, 0, 613, 614, 5, 22, 0, 0, 614, 615, 5, 119, 0, 0, 615, 618, 3, 50, 25, 0, 616, 617, 5, 57, 0, 0, 617, 619, 3, 16, 8, 0, 618, 616, 1, 0, 0, 0, 618, 619, 1, 0, 0, 0, 619, 627, 1, 0, 0, 0, 620, 621, 5, 23, 0, 0, 621, 624, 3, 50, 25, 0, 622, 623, 5, 57, 0, 0, 623, 625, 3, 16, 8, 0, 624, 622, 1, 0, 0, 0, 624, 625, 1, 0, 0, 0, 625, 627, 1, 0, 0, 0, 626, 613, 1, 0, 0, 0, 626, 620, 1, 0, 0, 0, 627, 131, 1, 0, 0, 0, 628, 630, 5, 21, 0, 0, 629, 631, 3, 64, 32, 0, 630, 629, 1, 0, 0, 0, 630, 631, 1, 0, 0, 0, 631, 635, 1, 0, 0, 0, 632, 634, 3, 134, 67, 0, 633, 632, 1, 0, 0, 0, 634, 637, 1, 0, 0, 0, 635, 633, 1, 0, 0, 0, 635, 636, 1, 0, 0, 0, 636, 133, 1, 0, 0, 0, 637, 635, 1, 0, 0, 0, 638, 639, 5, 114, 0, 0, 639, 640, 5, 57, 0, 0, 640, 650, 3, 54, 27, 0, 641, 642, 5, 115, 0, 0, 642, 643, 5, 57, 0, 0, 643, 650, 3, 16, 8, 0, 644, 645, 5, 113, 0, 0, 645, 646, 5, 57, 0, 0, 646, 650, 3, 54, 27, 0, 647, 648, 5, 78, 0, 0, 648, 650, 3, 160, 80, 0, 649, 638, 1, 0, 0, 0, 649, 641, 1, 0, 0, 0, 649, 644, 1, 0, 0, 0, 649, 647, 1, 0, 0, 0, 650, 135, 1, 0, 0, 0, 651, 652, 5, 28, 0, 0, 652, 653, 3, 34, 17, 0, 653, 654, 5, 73, 0, 0, 654, 655, 3, 62, 31, 0, 655, 137, 1, 0, 0, 0, 656, 657, 5, 32, 0, 0, 657, 658, 3, 62, 31, 0, 658, 139, 1, 0, 0, 0, 659, 660, 5, 34, 0, 0, 660, 661, 3, 142, 71, 0, 661, 662, 5, 60, 0, 0, 662, 141, 1, 0, 0, 0, 663, 664, 3, 64, 32, 0, 664, 665, 5, 56, 0, 0, 665, 666, 3, 166, 83, 0, 666, 143, 1, 0, 0, 0, 667, 668, 6, 72, -1, 0, 668, 669, 5, 70, 0, 0, 669, 697, 3, 144, 72, 8, 670, 697, 3, 150, 75, 0, 671, 697, 3, 146, 73, 0, 672, 674, 3, 150, 75, 0, 673, 675, 5, 70, 0, 0, 674, 673, 1, 0, 0, 0, 674, 675, 1, 0, 0, 0, 675, 676, 1, 0, 0, 0, 676, 677, 5, 66, 0, 0, 677, 678, 5, 98, 0, 0, 678, 683, 3, 150, 75, 0, 679, 680, 5, 61, 0, 0, 680, 682, 3, 150, 75, 0, 681, 679, 1, 0, 0, 0, 682, 685, 1, 0, 0, 0, 683, 681, 1, 0, 0, 0, 683, 684, 1, 0, 0, 0, 684, 686, 1, 0, 0, 0, 685, 683, 1, 0, 0, 0, 686, 687, 5, 99, 0, 0, 687, 697, 1, 0, 0, 0, 688, 689, 3, 150, 75, 0, 689, 691, 5, 67, 0, 0, 690, 692, 5, 70, 0, 0, 691, 690, 1, 0, 0, 0, 691, 692, 1, 0, 0, 0, 692, 693, 1, 0, 0, 0, 693, 694, 5, 71, 0, 0, 694, 697, 1, 0, 0, 0, 695, 697, 3, 148, 74, 0, 696, 667, 1, 0, 0, 0, 696, 670, 1, 0, 0, 0, 696, 671, 1, 0, 0, 0, 696, 672, 1, 0, 0, 0, 696, 688, 1, 0, 0, 0, 696, 695, 1, 0, 0, 0, 697, 706, 1, 0, 0, 0, 698, 699, 10, 5, 0, 0, 699, 700, 5, 54, 0, 0, 700, 705, 3, 144, 72, 6, 701, 702, 10, 4, 0, 0, 702, 703, 5, 74, 0, 0, 703, 705, 3, 144, 72, 5, 704, 698, 1, 0, 0, 0, 704, 701, 1, 0, 0, 0, 705, 708, 1, 0, 0, 0, 706, 704, 1, 0, 0, 0, 706, 707, 1, 0, 0, 0, 707, 145, 1, 0, 0, 0, 708, 706, 1, 0, 0, 0, 709, 711, 3, 150, 75, 0, 710, 712, 5, 70, 0, 0, 711, 710, 1, 0, 0, 0, 711, 712, 1, 0, 0, 0, 712, 713, 1, 0, 0, 0, 713, 714, 5, 69, 0, 0, 714, 715, 3, 176, 88, 0, 715, 756, 1, 0, 0, 0, 716, 718, 3, 150, 75, 0, 717, 719, 5, 70, 0, 0, 718, 717, 1, 0, 0, 0, 718, 719, 1, 0, 0, 0, 719, 720, 1, 0, 0, 0, 720, 721, 5, 76, 0, 0, 721, 722, 3, 176, 88, 0, 722, 756, 1, 0, 0, 0, 723, 725, 3, 150, 75, 0, 724, 726, 5, 70, 0, 0, 725, 724, 1, 0, 0, 0, 725, 726, 1, 0, 0, 0, 726, 727, 1, 0, 0, 0, 727, 728, 5, 69, 0, 0, 728, 729, 5, 98, 0, 0, 729, 734, 3, 176, 88, 0, 730, 731, 5, 61, 0, 0, 731, 733, 3, 176, 88, 0, 732, 730, 1, 0, 0, 0, 733, 736, 1, 0, 0, 0, 734, 732, 1, 0, 0, 0, 734, 735, 1, 0, 0, 0, 735, 737, 1, 0, 0, 0, 736, 734, 1, 0, 0, 0, 737, 738, 5, 99, 0, 0, 738, 756, 1, 0, 0, 0, 739, 741, 3, 150, 75, 0, 740, 742, 5, 70, 0, 0, 741, 740, 1, 0, 0, 0, 741, 742, 1, 0, 0, 0, 742, 743, 1, 0, 0, 0, 743, 744, 5, 76, 0, 0, 744, 745, 5, 98, 0, 0, 745, 750, 3, 176, 88, 0, 746, 747, 5, 61, 0, 0, 747, 749, 3, 176, 88, 0, 748, 746, 1, 0, 0, 0, 749, 752, 1, 0, 0, 0, 750, 748, 1, 0, 0, 0, 750, 751, 1, 0, 0, 0, 751, 753, 1, 0, 0, 0, 752, 750, 1, 0, 0, 0, 753, 754, 5, 99, 0, 0, 754, 756, 1, 0, 0, 0, 755, 709, 1, 0, 0, 0, 755, 716, 1, 0, 0, 0, 755, 723, 1, 0, 0, 0, 755, 739, 1, 0, 0, 0, 756, 147, 1, 0, 0, 0, 757, 760, 3, 54, 27, 0, 758, 759, 5, 58, 0, 0, 759, 761, 3, 12, 6, 0, 760, 758, 1, 0, 0, 0, 760, 761, 1, 0, 0, 0, 761, 762, 1, 0, 0, 0, 762, 763, 5, 59, 0, 0, 763, 764, 3, 166, 83, 0, 764, 149, 1, 0, 0, 0, 765, 771, 3, 152, 76, 0, 766, 767, 3, 152, 76, 0, 767, 768, 3, 178, 89, 0, 768, 769, 3, 152, 76, 0, 769, 771, 1, 0, 0, 0, 770, 765, 1, 0, 0, 0, 770, 766, 1, 0, 0, 0, 771, 151, 1, 0, 0, 0, 772, 773, 6, 76, -1, 0, 773, 777, 3, 154, 77, 0, 774, 775, 7, 5, 0, 0, 775, 777, 3, 152, 76, 3, 776, 772, 1, 0, 0, 0, 776, 774, 1, 0, 0, 0, 777, 786, 1, 0, 0, 0, 778, 779, 10, 2, 0, 0, 779, 780, 7, 6, 0, 0, 780, 785, 3, 152, 76, 3, 781, 782, 10, 1, 0, 0, 782, 783, 7, 5, 0, 0, 783, 785, 3, 152, 76, 2, 784, 778, 1, 0, 0, 0, 784, 781, 1, 0, 0, 0, 785, 788, 1, 0, 0, 0, 786, 784, 1, 0, 0, 0, 786, 787, 1, 0, 0, 0, 787, 153, 1, 0, 0, 0, 788, 786, 1, 0, 0, 0, 789, 790, 6, 77, -1, 0, 790, 798, 3, 166, 83, 0, 791, 798, 3, 54, 27, 0, 792, 798, 3, 156, 78, 0, 793, 794, 5, 98, 0, 0, 794, 795, 3, 144, 72, 0, 795, 796, 5, 99, 0, 0, 796, 798, 1, 0, 0, 0, 797, 789, 1, 0, 0, 0, 797, 791, 1, 0, 0, 0, 797, 792, 1, 0, 0, 0, 797, 793, 1, 0, 0, 0, 798, 804, 1, 0, 0, 0, 799, 800, 10, 1, 0, 0, 800, 801, 5, 58, 0, 0, 801, 803, 3, 12, 6, 0, 802, 799, 1, 0, 0, 0, 803, 806, 1, 0, 0, 0, 804, 802, 1, 0, 0, 0, 804, 805, 1, 0, 0, 0, 805, 155, 1, 0, 0, 0, 806, 804, 1, 0, 0, 0, 807, 808, 3, 158, 79, 0, 808, 822, 5, 98, 0, 0, 809, 823, 5, 88, 0, 0, 810, 815, 3, 144, 72, 0, 811, 812, 5, 61, 0, 0, 812, 814, 3, 144, 72, 0, 813, 811, 1, 0, 0, 0, 814, 817, 1, 0, 0, 0, 815, 813, 1, 0, 0, 0, 815, 816, 1, 0, 0, 0, 816, 820, 1, 0, 0, 0, 817, 815, 1, 0, 0, 0, 818, 819, 5, 61, 0, 0, 819, 821, 3, 160, 80, 0, 820, 818, 1, 0, 0, 0, 820, 821, 1, 0, 0, 0, 821, 823, 1, 0, 0, 0, 822, 809, 1, 0, 0, 0, 822, 810, 1, 0, 0, 0, 822, 823, 1, 0, 0, 0, 823, 824, 1, 0, 0, 0, 824, 825, 5, 99, 0, 0, 825, 157, 1, 0, 0, 0, 826, 830, 3, 72, 36, 0, 827, 830, 5, 65, 0, 0, 828, 830, 5, 68, 0, 0, 829, 826, 1, 0, 0, 0, 829, 827, 1, 0, 0, 0, 829, 828, 1, 0, 0, 0, 830, 159, 1, 0, 0, 0, 831, 840, 5, 91, 0, 0, 832, 837, 3, 162, 81, 0, 833, 834, 5, 61, 0, 0, 834, 836, 3, 162, 81, 0, 835, 833, 1, 0, 0, 0, 836, 839, 1, 0, 0, 0, 837, 835, 1, 0, 0, 0, 837, 838, 1, 0, 0, 0, 838, 841, 1, 0, 0, 0, 839, 837, 1, 0, 0, 0, 840, 832, 1, 0, 0, 0, 840, 841, 1, 0, 0, 0, 841, 842, 1, 0, 0, 0, 842, 843, 5, 92, 0, 0, 843, 161, 1, 0, 0, 0, 844, 845, 3, 176, 88, 0, 845, 846, 5, 59, 0, 0, 846, 847, 3, 164, 82, 0, 847, 163, 1, 0, 0, 0, 848, 851, 3, 166, 83, 0, 849, 851, 3, 160, 80, 0, 850, 848, 1, 0, 0, 0, 850, 849, 1, 0, 0, 0, 851, 165, 1, 0, 0, 0, 852, 895, 5, 71, 0, 0, 853, 854, 3, 174, 87, 0, 854, 855, 5, 100, 0, 0, 855, 895, 1, 0, 0, 0, 856, 895, 3, 172, 86, 0, 857, 895, 3, 174, 87, 0, 858, 895, 3, 168, 84, 0, 859, 895, 3, 68, 34, 0, 860, 895, 3, 176, 88, 0, 861, 862, 5, 96, 0, 0, 862, 867, 3, 170, 85, 0, 863, 864, 5, 61, 0, 0, 864, 866, 3, 170, 85, 0, 865, 863, 1, 0, 0, 0, 866, 869, 1, 0, 0, 0, 867, 865, 1, 0, 0, 0, 867, 868, 1, 0, 0, 0, 868, 870, 1, 0, 0, 0, 869, 867, 1, 0, 0, 0, 870, 871, 5, 97, 0, 0, 871, 895, 1, 0, 0, 0, 872, 873, 5, 96, 0, 0, 873, 878, 3, 168, 84, 0, 874, 875, 5, 61, 0, 0, 875, 877, 3, 168, 84, 0, 876, 874, 1, 0, 0, 0, 877, 880, 1, 0, 0, 0, 878, 876, 1, 0, 0, 0, 878, 879, 1, 0, 0, 0, 879, 881, 1, 0, 0, 0, 880, 878, 1, 0, 0, 0, 881, 882, 5, 97, 0, 0, 882, 895, 1, 0, 0, 0, 883, 884, 5, 96, 0, 0, 884, 889, 3, 176, 88, 0, 885, 886, 5, 61, 0, 0, 886, 888, 3, 176, 88, 0, 887, 885, 1, 0, 0, 0, 888, 891, 1, 0, 0, 0, 889, 887, 1, 0, 0, 0, 889, 890, 1, 0, 0, 0, 890, 892, 1, 0, 0, 0, 891, 889, 1, 0, 0, 0, 892, 893, 5, 97, 0, 0, 893, 895, 1, 0, 0, 0, 894, 852, 1, 0, 0, 0, 894, 853, 1, 0, 0, 0, 894, 856, 1, 0, 0, 0, 894, 857, 1, 0, 0, 0, 894, 858, 1, 0, 0, 0, 894, 859, 1, 0, 0, 0, 894, 860, 1, 0, 0, 0, 894, 861, 1, 0, 0, 0, 894, 872, 1, 0, 0, 0, 894, 883, 1, 0, 0, 0, 895, 167, 1, 0, 0, 0, 896, 897, 7, 7, 0, 0, 897, 169, 1, 0, 0, 0, 898, 901, 3, 172, 86, 0, 899, 901, 3, 174, 87, 0, 900, 898, 1, 0, 0, 0, 900, 899, 1, 0, 0, 0, 901, 171, 1, 0, 0, 0, 902, 904, 7, 5, 0, 0, 903, 902, 1, 0, 0, 0, 903, 904, 1, 0, 0, 0, 904, 905, 1, 0, 0, 0, 905, 906, 5, 53, 0, 0, 906, 173, 1, 0, 0, 0, 907, 909, 7, 5, 0, 0, 908, 907, 1, 0, 0, 0, 908, 909, 1, 0, 0, 0, 909, 910, 1, 0, 0, 0, 910, 911, 5, 52, 0, 0, 911, 175, 1, 0, 0, 0, 912, 913, 5, 51, 0, 0, 913, 177, 1, 0, 0, 0, 914, 915, 7, 8, 0, 0, 915, 179, 1, 0, 0, 0, 916, 917, 7, 9, 0, 0, 917, 918, 5, 123, 0, 0, 918, 919, 3, 182, 91, 0, 919, 920, 3, 184, 92, 0, 920, 181, 1, 0, 0, 0, 921, 922, 4, 91, 13, 0, 922, 924, 3, 34, 17, 0, 923, 925, 5, 141, 0, 0, 924, 923, 1, 0, 0, 0, 924, 925, 1, 0, 0, 0, 925, 926, 1, 0, 0, 0, 926, 927, 5, 106, 0, 0, 927, 930, 1, 0, 0, 0, 928, 930, 3, 34, 17, 0, 929, 921, 1, 0, 0, 0, 929, 928, 1, 0, 0, 0, 930, 183, 1, 0, 0, 0, 931, 932, 5, 73, 0, 0, 932, 937, 3, 144, 72, 0, 933, 934, 5, 61, 0, 0, 934, 936, 3, 144, 72, 0, 935, 933, 1, 0, 0, 0, 936, 939, 1, 0, 0, 0, 937, 935, 1, 0, 0, 0, 937, 938, 1, 0, 0, 0, 938, 185, 1, 0, 0, 0, 939, 937, 1, 0, 0, 0, 91, 189, 206, 215, 241, 256, 262, 271, 277, 290, 294, 299, 307, 321, 337, 345, 349, 356, 362, 367, 376, 383, 389, 398, 405, 413, 421, 425, 429, 434, 445, 450, 454, 468, 479, 485, 492, 501, 510, 530, 538, 541, 548, 559, 566, 574, 588, 597, 608, 618, 624, 626, 630, 635, 649, 674, 683, 691, 696, 704, 706, 711, 718, 725, 734, 741, 750, 755, 760, 770, 776, 784, 786, 797, 804, 815, 820, 822, 829, 837, 840, 850, 867, 878, 889, 894, 900, 903, 908, 924, 929, 937] \ No newline at end of file +[4, 1, 160, 982, 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, 2, 26, 7, 26, 2, 27, 7, 27, 2, 28, 7, 28, 2, 29, 7, 29, 2, 30, 7, 30, 2, 31, 7, 31, 2, 32, 7, 32, 2, 33, 7, 33, 2, 34, 7, 34, 2, 35, 7, 35, 2, 36, 7, 36, 2, 37, 7, 37, 2, 38, 7, 38, 2, 39, 7, 39, 2, 40, 7, 40, 2, 41, 7, 41, 2, 42, 7, 42, 2, 43, 7, 43, 2, 44, 7, 44, 2, 45, 7, 45, 2, 46, 7, 46, 2, 47, 7, 47, 2, 48, 7, 48, 2, 49, 7, 49, 2, 50, 7, 50, 2, 51, 7, 51, 2, 52, 7, 52, 2, 53, 7, 53, 2, 54, 7, 54, 2, 55, 7, 55, 2, 56, 7, 56, 2, 57, 7, 57, 2, 58, 7, 58, 2, 59, 7, 59, 2, 60, 7, 60, 2, 61, 7, 61, 2, 62, 7, 62, 2, 63, 7, 63, 2, 64, 7, 64, 2, 65, 7, 65, 2, 66, 7, 66, 2, 67, 7, 67, 2, 68, 7, 68, 2, 69, 7, 69, 2, 70, 7, 70, 2, 71, 7, 71, 2, 72, 7, 72, 2, 73, 7, 73, 2, 74, 7, 74, 2, 75, 7, 75, 2, 76, 7, 76, 2, 77, 7, 77, 2, 78, 7, 78, 2, 79, 7, 79, 2, 80, 7, 80, 2, 81, 7, 81, 2, 82, 7, 82, 2, 83, 7, 83, 2, 84, 7, 84, 2, 85, 7, 85, 2, 86, 7, 86, 2, 87, 7, 87, 2, 88, 7, 88, 2, 89, 7, 89, 2, 90, 7, 90, 2, 91, 7, 91, 2, 92, 7, 92, 2, 93, 7, 93, 2, 94, 7, 94, 2, 95, 7, 95, 2, 96, 7, 96, 1, 0, 5, 0, 196, 8, 0, 10, 0, 12, 0, 199, 9, 0, 1, 0, 1, 0, 1, 0, 1, 1, 1, 1, 1, 1, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 5, 2, 213, 8, 2, 10, 2, 12, 2, 216, 9, 2, 1, 3, 1, 3, 1, 3, 1, 3, 1, 3, 1, 3, 3, 3, 224, 8, 3, 1, 4, 1, 4, 1, 4, 1, 4, 1, 4, 1, 4, 1, 4, 1, 4, 1, 4, 1, 4, 1, 4, 1, 4, 1, 4, 1, 4, 1, 4, 1, 4, 1, 4, 1, 4, 1, 4, 1, 4, 1, 4, 1, 4, 1, 4, 1, 4, 1, 4, 1, 4, 3, 4, 252, 8, 4, 1, 5, 1, 5, 1, 5, 1, 6, 1, 6, 1, 7, 1, 7, 1, 7, 1, 8, 1, 8, 1, 8, 5, 8, 265, 8, 8, 10, 8, 12, 8, 268, 9, 8, 1, 9, 1, 9, 1, 9, 3, 9, 273, 8, 9, 1, 9, 1, 9, 1, 10, 1, 10, 1, 10, 5, 10, 280, 8, 10, 10, 10, 12, 10, 283, 9, 10, 1, 11, 1, 11, 1, 11, 3, 11, 288, 8, 11, 1, 12, 1, 12, 1, 12, 1, 13, 1, 13, 1, 13, 1, 14, 1, 14, 1, 14, 5, 14, 299, 8, 14, 10, 14, 12, 14, 302, 9, 14, 1, 14, 3, 14, 305, 8, 14, 1, 15, 1, 15, 1, 15, 3, 15, 310, 8, 15, 1, 16, 1, 16, 1, 16, 1, 16, 5, 16, 316, 8, 16, 10, 16, 12, 16, 319, 9, 16, 1, 16, 1, 16, 1, 17, 1, 17, 1, 17, 1, 17, 1, 17, 1, 17, 1, 17, 1, 17, 1, 17, 3, 17, 332, 8, 17, 1, 18, 1, 18, 1, 19, 1, 19, 1, 20, 1, 20, 1, 21, 1, 21, 1, 22, 1, 22, 1, 22, 1, 22, 5, 22, 346, 8, 22, 10, 22, 12, 22, 349, 9, 22, 1, 23, 1, 23, 1, 23, 1, 24, 1, 24, 3, 24, 356, 8, 24, 1, 24, 1, 24, 3, 24, 360, 8, 24, 1, 25, 1, 25, 1, 25, 5, 25, 365, 8, 25, 10, 25, 12, 25, 368, 9, 25, 1, 26, 1, 26, 1, 26, 3, 26, 373, 8, 26, 1, 27, 1, 27, 1, 27, 3, 27, 378, 8, 27, 1, 27, 1, 27, 1, 27, 1, 27, 1, 27, 1, 27, 1, 27, 3, 27, 387, 8, 27, 1, 28, 1, 28, 1, 28, 5, 28, 392, 8, 28, 10, 28, 12, 28, 395, 9, 28, 1, 29, 1, 29, 1, 29, 3, 29, 400, 8, 29, 1, 29, 1, 29, 1, 29, 1, 29, 1, 29, 1, 29, 1, 29, 3, 29, 409, 8, 29, 1, 30, 1, 30, 1, 30, 5, 30, 414, 8, 30, 10, 30, 12, 30, 417, 9, 30, 1, 31, 1, 31, 1, 31, 5, 31, 422, 8, 31, 10, 31, 12, 31, 425, 9, 31, 1, 32, 1, 32, 1, 33, 1, 33, 1, 33, 3, 33, 432, 8, 33, 1, 34, 1, 34, 3, 34, 436, 8, 34, 1, 35, 1, 35, 3, 35, 440, 8, 35, 1, 36, 1, 36, 1, 36, 3, 36, 445, 8, 36, 1, 37, 1, 37, 1, 37, 1, 38, 1, 38, 1, 38, 1, 38, 5, 38, 454, 8, 38, 10, 38, 12, 38, 457, 9, 38, 1, 39, 1, 39, 3, 39, 461, 8, 39, 1, 39, 1, 39, 3, 39, 465, 8, 39, 1, 40, 1, 40, 1, 40, 1, 41, 1, 41, 1, 41, 1, 42, 1, 42, 1, 42, 1, 42, 5, 42, 477, 8, 42, 10, 42, 12, 42, 480, 9, 42, 1, 43, 1, 43, 1, 43, 1, 43, 1, 43, 1, 43, 1, 43, 1, 43, 3, 43, 490, 8, 43, 1, 44, 1, 44, 1, 44, 1, 44, 3, 44, 496, 8, 44, 1, 45, 1, 45, 1, 45, 5, 45, 501, 8, 45, 10, 45, 12, 45, 504, 9, 45, 1, 46, 1, 46, 1, 46, 1, 46, 1, 47, 1, 47, 3, 47, 512, 8, 47, 1, 48, 1, 48, 1, 48, 1, 48, 1, 48, 5, 48, 519, 8, 48, 10, 48, 12, 48, 522, 9, 48, 1, 49, 1, 49, 1, 49, 1, 50, 1, 50, 1, 50, 1, 51, 1, 51, 1, 51, 1, 51, 1, 52, 1, 52, 1, 52, 1, 53, 1, 53, 1, 53, 1, 53, 3, 53, 541, 8, 53, 1, 53, 1, 53, 1, 53, 1, 53, 5, 53, 547, 8, 53, 10, 53, 12, 53, 550, 9, 53, 3, 53, 552, 8, 53, 1, 54, 1, 54, 1, 55, 1, 55, 1, 55, 3, 55, 559, 8, 55, 1, 55, 1, 55, 1, 56, 1, 56, 1, 56, 1, 57, 1, 57, 1, 57, 1, 57, 3, 57, 570, 8, 57, 1, 57, 1, 57, 1, 57, 1, 57, 1, 57, 3, 57, 577, 8, 57, 1, 58, 1, 58, 1, 58, 1, 59, 4, 59, 583, 8, 59, 11, 59, 12, 59, 584, 1, 60, 1, 60, 1, 60, 1, 60, 1, 61, 1, 61, 1, 61, 1, 61, 1, 61, 1, 61, 5, 61, 597, 8, 61, 10, 61, 12, 61, 600, 9, 61, 1, 62, 1, 62, 1, 63, 1, 63, 1, 63, 1, 63, 3, 63, 608, 8, 63, 1, 63, 1, 63, 1, 63, 1, 63, 1, 63, 1, 64, 1, 64, 1, 64, 1, 64, 3, 64, 619, 8, 64, 1, 64, 1, 64, 1, 64, 1, 65, 1, 65, 1, 65, 1, 65, 1, 65, 3, 65, 629, 8, 65, 1, 65, 1, 65, 1, 65, 1, 65, 3, 65, 635, 8, 65, 3, 65, 637, 8, 65, 1, 66, 1, 66, 3, 66, 641, 8, 66, 1, 66, 5, 66, 644, 8, 66, 10, 66, 12, 66, 647, 9, 66, 1, 67, 1, 67, 1, 67, 1, 67, 1, 67, 1, 67, 1, 67, 1, 67, 1, 67, 1, 67, 1, 67, 3, 67, 660, 8, 67, 1, 68, 1, 68, 1, 68, 1, 68, 1, 68, 1, 69, 1, 69, 1, 69, 1, 70, 1, 70, 1, 70, 1, 70, 1, 71, 1, 71, 1, 71, 1, 71, 1, 72, 1, 72, 1, 72, 1, 72, 1, 72, 1, 72, 1, 72, 3, 72, 685, 8, 72, 1, 72, 1, 72, 1, 72, 1, 72, 1, 72, 5, 72, 692, 8, 72, 10, 72, 12, 72, 695, 9, 72, 1, 72, 1, 72, 1, 72, 1, 72, 1, 72, 3, 72, 702, 8, 72, 1, 72, 1, 72, 1, 72, 3, 72, 707, 8, 72, 1, 72, 1, 72, 1, 72, 1, 72, 1, 72, 1, 72, 5, 72, 715, 8, 72, 10, 72, 12, 72, 718, 9, 72, 1, 73, 1, 73, 3, 73, 722, 8, 73, 1, 73, 1, 73, 1, 73, 1, 73, 1, 73, 3, 73, 729, 8, 73, 1, 73, 1, 73, 1, 73, 1, 73, 1, 73, 3, 73, 736, 8, 73, 1, 73, 1, 73, 1, 73, 1, 73, 1, 73, 5, 73, 743, 8, 73, 10, 73, 12, 73, 746, 9, 73, 1, 73, 1, 73, 1, 73, 1, 73, 3, 73, 752, 8, 73, 1, 73, 1, 73, 1, 73, 1, 73, 1, 73, 5, 73, 759, 8, 73, 10, 73, 12, 73, 762, 9, 73, 1, 73, 1, 73, 3, 73, 766, 8, 73, 1, 74, 1, 74, 1, 74, 3, 74, 771, 8, 74, 1, 74, 1, 74, 1, 74, 1, 75, 1, 75, 1, 75, 1, 75, 1, 75, 3, 75, 781, 8, 75, 1, 76, 1, 76, 1, 76, 1, 76, 3, 76, 787, 8, 76, 1, 76, 1, 76, 1, 76, 1, 76, 1, 76, 1, 76, 5, 76, 795, 8, 76, 10, 76, 12, 76, 798, 9, 76, 1, 77, 1, 77, 1, 77, 1, 77, 1, 77, 1, 77, 1, 77, 1, 77, 3, 77, 808, 8, 77, 1, 77, 1, 77, 1, 77, 5, 77, 813, 8, 77, 10, 77, 12, 77, 816, 9, 77, 1, 78, 1, 78, 1, 78, 1, 78, 1, 78, 1, 78, 5, 78, 824, 8, 78, 10, 78, 12, 78, 827, 9, 78, 1, 78, 1, 78, 3, 78, 831, 8, 78, 3, 78, 833, 8, 78, 1, 78, 1, 78, 1, 79, 1, 79, 1, 79, 3, 79, 840, 8, 79, 1, 80, 1, 80, 1, 80, 1, 80, 5, 80, 846, 8, 80, 10, 80, 12, 80, 849, 9, 80, 3, 80, 851, 8, 80, 1, 80, 1, 80, 1, 81, 1, 81, 1, 81, 1, 81, 1, 82, 1, 82, 3, 82, 861, 8, 82, 1, 83, 1, 83, 1, 83, 1, 83, 1, 83, 1, 83, 1, 83, 1, 83, 1, 83, 1, 83, 1, 83, 1, 83, 1, 83, 5, 83, 876, 8, 83, 10, 83, 12, 83, 879, 9, 83, 1, 83, 1, 83, 1, 83, 1, 83, 1, 83, 1, 83, 5, 83, 887, 8, 83, 10, 83, 12, 83, 890, 9, 83, 1, 83, 1, 83, 1, 83, 1, 83, 1, 83, 1, 83, 5, 83, 898, 8, 83, 10, 83, 12, 83, 901, 9, 83, 1, 83, 1, 83, 3, 83, 905, 8, 83, 1, 84, 1, 84, 1, 85, 1, 85, 3, 85, 911, 8, 85, 1, 86, 3, 86, 914, 8, 86, 1, 86, 1, 86, 1, 87, 3, 87, 919, 8, 87, 1, 87, 1, 87, 1, 88, 1, 88, 1, 89, 1, 89, 1, 90, 1, 90, 1, 90, 1, 90, 1, 90, 1, 91, 1, 91, 1, 91, 3, 91, 935, 8, 91, 1, 91, 1, 91, 1, 91, 3, 91, 940, 8, 91, 1, 92, 1, 92, 1, 92, 1, 92, 5, 92, 946, 8, 92, 10, 92, 12, 92, 949, 9, 92, 1, 93, 1, 93, 4, 93, 953, 8, 93, 11, 93, 12, 93, 954, 1, 93, 1, 93, 5, 93, 959, 8, 93, 10, 93, 12, 93, 962, 9, 93, 1, 93, 1, 93, 1, 94, 1, 94, 1, 94, 1, 95, 1, 95, 1, 96, 1, 96, 1, 96, 5, 96, 974, 8, 96, 10, 96, 12, 96, 977, 9, 96, 1, 96, 3, 96, 980, 8, 96, 1, 96, 0, 5, 4, 122, 144, 152, 154, 97, 0, 2, 4, 6, 8, 10, 12, 14, 16, 18, 20, 22, 24, 26, 28, 30, 32, 34, 36, 38, 40, 42, 44, 46, 48, 50, 52, 54, 56, 58, 60, 62, 64, 66, 68, 70, 72, 74, 76, 78, 80, 82, 84, 86, 88, 90, 92, 94, 96, 98, 100, 102, 104, 106, 108, 110, 112, 114, 116, 118, 120, 122, 124, 126, 128, 130, 132, 134, 136, 138, 140, 142, 144, 146, 148, 150, 152, 154, 156, 158, 160, 162, 164, 166, 168, 170, 172, 174, 176, 178, 180, 182, 184, 186, 188, 190, 192, 0, 11, 2, 0, 52, 52, 107, 107, 1, 0, 101, 102, 2, 0, 56, 56, 63, 63, 2, 0, 66, 66, 69, 69, 2, 0, 41, 41, 52, 52, 1, 0, 87, 88, 1, 0, 89, 91, 2, 0, 65, 65, 78, 78, 2, 0, 80, 80, 82, 86, 2, 0, 24, 24, 26, 27, 4, 0, 52, 52, 95, 95, 102, 102, 142, 142, 1026, 0, 197, 1, 0, 0, 0, 2, 203, 1, 0, 0, 0, 4, 206, 1, 0, 0, 0, 6, 223, 1, 0, 0, 0, 8, 251, 1, 0, 0, 0, 10, 253, 1, 0, 0, 0, 12, 256, 1, 0, 0, 0, 14, 258, 1, 0, 0, 0, 16, 261, 1, 0, 0, 0, 18, 272, 1, 0, 0, 0, 20, 276, 1, 0, 0, 0, 22, 284, 1, 0, 0, 0, 24, 289, 1, 0, 0, 0, 26, 292, 1, 0, 0, 0, 28, 295, 1, 0, 0, 0, 30, 309, 1, 0, 0, 0, 32, 311, 1, 0, 0, 0, 34, 331, 1, 0, 0, 0, 36, 333, 1, 0, 0, 0, 38, 335, 1, 0, 0, 0, 40, 337, 1, 0, 0, 0, 42, 339, 1, 0, 0, 0, 44, 341, 1, 0, 0, 0, 46, 350, 1, 0, 0, 0, 48, 353, 1, 0, 0, 0, 50, 361, 1, 0, 0, 0, 52, 369, 1, 0, 0, 0, 54, 386, 1, 0, 0, 0, 56, 388, 1, 0, 0, 0, 58, 408, 1, 0, 0, 0, 60, 410, 1, 0, 0, 0, 62, 418, 1, 0, 0, 0, 64, 426, 1, 0, 0, 0, 66, 431, 1, 0, 0, 0, 68, 435, 1, 0, 0, 0, 70, 439, 1, 0, 0, 0, 72, 444, 1, 0, 0, 0, 74, 446, 1, 0, 0, 0, 76, 449, 1, 0, 0, 0, 78, 458, 1, 0, 0, 0, 80, 466, 1, 0, 0, 0, 82, 469, 1, 0, 0, 0, 84, 472, 1, 0, 0, 0, 86, 489, 1, 0, 0, 0, 88, 491, 1, 0, 0, 0, 90, 497, 1, 0, 0, 0, 92, 505, 1, 0, 0, 0, 94, 511, 1, 0, 0, 0, 96, 513, 1, 0, 0, 0, 98, 523, 1, 0, 0, 0, 100, 526, 1, 0, 0, 0, 102, 529, 1, 0, 0, 0, 104, 533, 1, 0, 0, 0, 106, 536, 1, 0, 0, 0, 108, 553, 1, 0, 0, 0, 110, 558, 1, 0, 0, 0, 112, 562, 1, 0, 0, 0, 114, 565, 1, 0, 0, 0, 116, 578, 1, 0, 0, 0, 118, 582, 1, 0, 0, 0, 120, 586, 1, 0, 0, 0, 122, 590, 1, 0, 0, 0, 124, 601, 1, 0, 0, 0, 126, 603, 1, 0, 0, 0, 128, 614, 1, 0, 0, 0, 130, 636, 1, 0, 0, 0, 132, 638, 1, 0, 0, 0, 134, 659, 1, 0, 0, 0, 136, 661, 1, 0, 0, 0, 138, 666, 1, 0, 0, 0, 140, 669, 1, 0, 0, 0, 142, 673, 1, 0, 0, 0, 144, 706, 1, 0, 0, 0, 146, 765, 1, 0, 0, 0, 148, 767, 1, 0, 0, 0, 150, 780, 1, 0, 0, 0, 152, 786, 1, 0, 0, 0, 154, 807, 1, 0, 0, 0, 156, 817, 1, 0, 0, 0, 158, 839, 1, 0, 0, 0, 160, 841, 1, 0, 0, 0, 162, 854, 1, 0, 0, 0, 164, 860, 1, 0, 0, 0, 166, 904, 1, 0, 0, 0, 168, 906, 1, 0, 0, 0, 170, 910, 1, 0, 0, 0, 172, 913, 1, 0, 0, 0, 174, 918, 1, 0, 0, 0, 176, 922, 1, 0, 0, 0, 178, 924, 1, 0, 0, 0, 180, 926, 1, 0, 0, 0, 182, 939, 1, 0, 0, 0, 184, 941, 1, 0, 0, 0, 186, 950, 1, 0, 0, 0, 188, 965, 1, 0, 0, 0, 190, 968, 1, 0, 0, 0, 192, 979, 1, 0, 0, 0, 194, 196, 3, 140, 70, 0, 195, 194, 1, 0, 0, 0, 196, 199, 1, 0, 0, 0, 197, 195, 1, 0, 0, 0, 197, 198, 1, 0, 0, 0, 198, 200, 1, 0, 0, 0, 199, 197, 1, 0, 0, 0, 200, 201, 3, 2, 1, 0, 201, 202, 5, 0, 0, 1, 202, 1, 1, 0, 0, 0, 203, 204, 3, 4, 2, 0, 204, 205, 5, 0, 0, 1, 205, 3, 1, 0, 0, 0, 206, 207, 6, 2, -1, 0, 207, 208, 3, 6, 3, 0, 208, 214, 1, 0, 0, 0, 209, 210, 10, 1, 0, 0, 210, 211, 5, 51, 0, 0, 211, 213, 3, 8, 4, 0, 212, 209, 1, 0, 0, 0, 213, 216, 1, 0, 0, 0, 214, 212, 1, 0, 0, 0, 214, 215, 1, 0, 0, 0, 215, 5, 1, 0, 0, 0, 216, 214, 1, 0, 0, 0, 217, 224, 3, 24, 12, 0, 218, 224, 3, 14, 7, 0, 219, 224, 3, 104, 52, 0, 220, 224, 3, 26, 13, 0, 221, 222, 4, 3, 1, 0, 222, 224, 3, 100, 50, 0, 223, 217, 1, 0, 0, 0, 223, 218, 1, 0, 0, 0, 223, 219, 1, 0, 0, 0, 223, 220, 1, 0, 0, 0, 223, 221, 1, 0, 0, 0, 224, 7, 1, 0, 0, 0, 225, 252, 3, 46, 23, 0, 226, 252, 3, 10, 5, 0, 227, 252, 3, 80, 40, 0, 228, 252, 3, 74, 37, 0, 229, 252, 3, 48, 24, 0, 230, 252, 3, 76, 38, 0, 231, 252, 3, 82, 41, 0, 232, 252, 3, 84, 42, 0, 233, 252, 3, 88, 44, 0, 234, 252, 3, 96, 48, 0, 235, 252, 3, 106, 53, 0, 236, 252, 3, 98, 49, 0, 237, 252, 3, 180, 90, 0, 238, 252, 3, 114, 57, 0, 239, 252, 3, 128, 64, 0, 240, 252, 3, 112, 56, 0, 241, 252, 3, 116, 58, 0, 242, 252, 3, 126, 63, 0, 243, 252, 3, 130, 65, 0, 244, 252, 3, 132, 66, 0, 245, 246, 4, 4, 2, 0, 246, 252, 3, 136, 68, 0, 247, 248, 4, 4, 3, 0, 248, 252, 3, 138, 69, 0, 249, 250, 4, 4, 4, 0, 250, 252, 3, 186, 93, 0, 251, 225, 1, 0, 0, 0, 251, 226, 1, 0, 0, 0, 251, 227, 1, 0, 0, 0, 251, 228, 1, 0, 0, 0, 251, 229, 1, 0, 0, 0, 251, 230, 1, 0, 0, 0, 251, 231, 1, 0, 0, 0, 251, 232, 1, 0, 0, 0, 251, 233, 1, 0, 0, 0, 251, 234, 1, 0, 0, 0, 251, 235, 1, 0, 0, 0, 251, 236, 1, 0, 0, 0, 251, 237, 1, 0, 0, 0, 251, 238, 1, 0, 0, 0, 251, 239, 1, 0, 0, 0, 251, 240, 1, 0, 0, 0, 251, 241, 1, 0, 0, 0, 251, 242, 1, 0, 0, 0, 251, 243, 1, 0, 0, 0, 251, 244, 1, 0, 0, 0, 251, 245, 1, 0, 0, 0, 251, 247, 1, 0, 0, 0, 251, 249, 1, 0, 0, 0, 252, 9, 1, 0, 0, 0, 253, 254, 5, 17, 0, 0, 254, 255, 3, 144, 72, 0, 255, 11, 1, 0, 0, 0, 256, 257, 3, 64, 32, 0, 257, 13, 1, 0, 0, 0, 258, 259, 5, 13, 0, 0, 259, 260, 3, 16, 8, 0, 260, 15, 1, 0, 0, 0, 261, 266, 3, 18, 9, 0, 262, 263, 5, 62, 0, 0, 263, 265, 3, 18, 9, 0, 264, 262, 1, 0, 0, 0, 265, 268, 1, 0, 0, 0, 266, 264, 1, 0, 0, 0, 266, 267, 1, 0, 0, 0, 267, 17, 1, 0, 0, 0, 268, 266, 1, 0, 0, 0, 269, 270, 3, 54, 27, 0, 270, 271, 5, 57, 0, 0, 271, 273, 1, 0, 0, 0, 272, 269, 1, 0, 0, 0, 272, 273, 1, 0, 0, 0, 273, 274, 1, 0, 0, 0, 274, 275, 3, 144, 72, 0, 275, 19, 1, 0, 0, 0, 276, 281, 3, 22, 11, 0, 277, 278, 5, 62, 0, 0, 278, 280, 3, 22, 11, 0, 279, 277, 1, 0, 0, 0, 280, 283, 1, 0, 0, 0, 281, 279, 1, 0, 0, 0, 281, 282, 1, 0, 0, 0, 282, 21, 1, 0, 0, 0, 283, 281, 1, 0, 0, 0, 284, 287, 3, 54, 27, 0, 285, 286, 5, 57, 0, 0, 286, 288, 3, 144, 72, 0, 287, 285, 1, 0, 0, 0, 287, 288, 1, 0, 0, 0, 288, 23, 1, 0, 0, 0, 289, 290, 5, 18, 0, 0, 290, 291, 3, 28, 14, 0, 291, 25, 1, 0, 0, 0, 292, 293, 5, 19, 0, 0, 293, 294, 3, 28, 14, 0, 294, 27, 1, 0, 0, 0, 295, 300, 3, 30, 15, 0, 296, 297, 5, 62, 0, 0, 297, 299, 3, 30, 15, 0, 298, 296, 1, 0, 0, 0, 299, 302, 1, 0, 0, 0, 300, 298, 1, 0, 0, 0, 300, 301, 1, 0, 0, 0, 301, 304, 1, 0, 0, 0, 302, 300, 1, 0, 0, 0, 303, 305, 3, 44, 22, 0, 304, 303, 1, 0, 0, 0, 304, 305, 1, 0, 0, 0, 305, 29, 1, 0, 0, 0, 306, 310, 3, 34, 17, 0, 307, 308, 4, 15, 5, 0, 308, 310, 3, 32, 16, 0, 309, 306, 1, 0, 0, 0, 309, 307, 1, 0, 0, 0, 310, 31, 1, 0, 0, 0, 311, 312, 5, 99, 0, 0, 312, 317, 3, 24, 12, 0, 313, 314, 5, 51, 0, 0, 314, 316, 3, 8, 4, 0, 315, 313, 1, 0, 0, 0, 316, 319, 1, 0, 0, 0, 317, 315, 1, 0, 0, 0, 317, 318, 1, 0, 0, 0, 318, 320, 1, 0, 0, 0, 319, 317, 1, 0, 0, 0, 320, 321, 5, 100, 0, 0, 321, 33, 1, 0, 0, 0, 322, 323, 3, 36, 18, 0, 323, 324, 5, 60, 0, 0, 324, 325, 3, 40, 20, 0, 325, 332, 1, 0, 0, 0, 326, 327, 3, 40, 20, 0, 327, 328, 5, 59, 0, 0, 328, 329, 3, 38, 19, 0, 329, 332, 1, 0, 0, 0, 330, 332, 3, 42, 21, 0, 331, 322, 1, 0, 0, 0, 331, 326, 1, 0, 0, 0, 331, 330, 1, 0, 0, 0, 332, 35, 1, 0, 0, 0, 333, 334, 5, 107, 0, 0, 334, 37, 1, 0, 0, 0, 335, 336, 5, 107, 0, 0, 336, 39, 1, 0, 0, 0, 337, 338, 5, 107, 0, 0, 338, 41, 1, 0, 0, 0, 339, 340, 7, 0, 0, 0, 340, 43, 1, 0, 0, 0, 341, 342, 5, 106, 0, 0, 342, 347, 5, 107, 0, 0, 343, 344, 5, 62, 0, 0, 344, 346, 5, 107, 0, 0, 345, 343, 1, 0, 0, 0, 346, 349, 1, 0, 0, 0, 347, 345, 1, 0, 0, 0, 347, 348, 1, 0, 0, 0, 348, 45, 1, 0, 0, 0, 349, 347, 1, 0, 0, 0, 350, 351, 5, 9, 0, 0, 351, 352, 3, 16, 8, 0, 352, 47, 1, 0, 0, 0, 353, 355, 5, 16, 0, 0, 354, 356, 3, 50, 25, 0, 355, 354, 1, 0, 0, 0, 355, 356, 1, 0, 0, 0, 356, 359, 1, 0, 0, 0, 357, 358, 5, 58, 0, 0, 358, 360, 3, 16, 8, 0, 359, 357, 1, 0, 0, 0, 359, 360, 1, 0, 0, 0, 360, 49, 1, 0, 0, 0, 361, 366, 3, 52, 26, 0, 362, 363, 5, 62, 0, 0, 363, 365, 3, 52, 26, 0, 364, 362, 1, 0, 0, 0, 365, 368, 1, 0, 0, 0, 366, 364, 1, 0, 0, 0, 366, 367, 1, 0, 0, 0, 367, 51, 1, 0, 0, 0, 368, 366, 1, 0, 0, 0, 369, 372, 3, 18, 9, 0, 370, 371, 5, 17, 0, 0, 371, 373, 3, 144, 72, 0, 372, 370, 1, 0, 0, 0, 372, 373, 1, 0, 0, 0, 373, 53, 1, 0, 0, 0, 374, 375, 4, 27, 6, 0, 375, 377, 5, 97, 0, 0, 376, 378, 5, 101, 0, 0, 377, 376, 1, 0, 0, 0, 377, 378, 1, 0, 0, 0, 378, 379, 1, 0, 0, 0, 379, 380, 5, 98, 0, 0, 380, 381, 5, 64, 0, 0, 381, 382, 5, 97, 0, 0, 382, 383, 3, 56, 28, 0, 383, 384, 5, 98, 0, 0, 384, 387, 1, 0, 0, 0, 385, 387, 3, 56, 28, 0, 386, 374, 1, 0, 0, 0, 386, 385, 1, 0, 0, 0, 387, 55, 1, 0, 0, 0, 388, 393, 3, 72, 36, 0, 389, 390, 5, 64, 0, 0, 390, 392, 3, 72, 36, 0, 391, 389, 1, 0, 0, 0, 392, 395, 1, 0, 0, 0, 393, 391, 1, 0, 0, 0, 393, 394, 1, 0, 0, 0, 394, 57, 1, 0, 0, 0, 395, 393, 1, 0, 0, 0, 396, 397, 4, 29, 7, 0, 397, 399, 5, 97, 0, 0, 398, 400, 5, 138, 0, 0, 399, 398, 1, 0, 0, 0, 399, 400, 1, 0, 0, 0, 400, 401, 1, 0, 0, 0, 401, 402, 5, 98, 0, 0, 402, 403, 5, 64, 0, 0, 403, 404, 5, 97, 0, 0, 404, 405, 3, 60, 30, 0, 405, 406, 5, 98, 0, 0, 406, 409, 1, 0, 0, 0, 407, 409, 3, 60, 30, 0, 408, 396, 1, 0, 0, 0, 408, 407, 1, 0, 0, 0, 409, 59, 1, 0, 0, 0, 410, 415, 3, 66, 33, 0, 411, 412, 5, 64, 0, 0, 412, 414, 3, 66, 33, 0, 413, 411, 1, 0, 0, 0, 414, 417, 1, 0, 0, 0, 415, 413, 1, 0, 0, 0, 415, 416, 1, 0, 0, 0, 416, 61, 1, 0, 0, 0, 417, 415, 1, 0, 0, 0, 418, 423, 3, 58, 29, 0, 419, 420, 5, 62, 0, 0, 420, 422, 3, 58, 29, 0, 421, 419, 1, 0, 0, 0, 422, 425, 1, 0, 0, 0, 423, 421, 1, 0, 0, 0, 423, 424, 1, 0, 0, 0, 424, 63, 1, 0, 0, 0, 425, 423, 1, 0, 0, 0, 426, 427, 7, 1, 0, 0, 427, 65, 1, 0, 0, 0, 428, 432, 5, 138, 0, 0, 429, 432, 3, 68, 34, 0, 430, 432, 3, 70, 35, 0, 431, 428, 1, 0, 0, 0, 431, 429, 1, 0, 0, 0, 431, 430, 1, 0, 0, 0, 432, 67, 1, 0, 0, 0, 433, 436, 5, 76, 0, 0, 434, 436, 5, 95, 0, 0, 435, 433, 1, 0, 0, 0, 435, 434, 1, 0, 0, 0, 436, 69, 1, 0, 0, 0, 437, 440, 5, 94, 0, 0, 438, 440, 5, 96, 0, 0, 439, 437, 1, 0, 0, 0, 439, 438, 1, 0, 0, 0, 440, 71, 1, 0, 0, 0, 441, 445, 3, 64, 32, 0, 442, 445, 3, 68, 34, 0, 443, 445, 3, 70, 35, 0, 444, 441, 1, 0, 0, 0, 444, 442, 1, 0, 0, 0, 444, 443, 1, 0, 0, 0, 445, 73, 1, 0, 0, 0, 446, 447, 5, 11, 0, 0, 447, 448, 3, 166, 83, 0, 448, 75, 1, 0, 0, 0, 449, 450, 5, 15, 0, 0, 450, 455, 3, 78, 39, 0, 451, 452, 5, 62, 0, 0, 452, 454, 3, 78, 39, 0, 453, 451, 1, 0, 0, 0, 454, 457, 1, 0, 0, 0, 455, 453, 1, 0, 0, 0, 455, 456, 1, 0, 0, 0, 456, 77, 1, 0, 0, 0, 457, 455, 1, 0, 0, 0, 458, 460, 3, 144, 72, 0, 459, 461, 7, 2, 0, 0, 460, 459, 1, 0, 0, 0, 460, 461, 1, 0, 0, 0, 461, 464, 1, 0, 0, 0, 462, 463, 5, 73, 0, 0, 463, 465, 7, 3, 0, 0, 464, 462, 1, 0, 0, 0, 464, 465, 1, 0, 0, 0, 465, 79, 1, 0, 0, 0, 466, 467, 5, 31, 0, 0, 467, 468, 3, 62, 31, 0, 468, 81, 1, 0, 0, 0, 469, 470, 5, 30, 0, 0, 470, 471, 3, 62, 31, 0, 471, 83, 1, 0, 0, 0, 472, 473, 5, 34, 0, 0, 473, 478, 3, 86, 43, 0, 474, 475, 5, 62, 0, 0, 475, 477, 3, 86, 43, 0, 476, 474, 1, 0, 0, 0, 477, 480, 1, 0, 0, 0, 478, 476, 1, 0, 0, 0, 478, 479, 1, 0, 0, 0, 479, 85, 1, 0, 0, 0, 480, 478, 1, 0, 0, 0, 481, 482, 3, 58, 29, 0, 482, 483, 5, 150, 0, 0, 483, 484, 3, 58, 29, 0, 484, 490, 1, 0, 0, 0, 485, 486, 3, 58, 29, 0, 486, 487, 5, 57, 0, 0, 487, 488, 3, 58, 29, 0, 488, 490, 1, 0, 0, 0, 489, 481, 1, 0, 0, 0, 489, 485, 1, 0, 0, 0, 490, 87, 1, 0, 0, 0, 491, 492, 5, 8, 0, 0, 492, 493, 3, 154, 77, 0, 493, 495, 3, 176, 88, 0, 494, 496, 3, 90, 45, 0, 495, 494, 1, 0, 0, 0, 495, 496, 1, 0, 0, 0, 496, 89, 1, 0, 0, 0, 497, 502, 3, 92, 46, 0, 498, 499, 5, 62, 0, 0, 499, 501, 3, 92, 46, 0, 500, 498, 1, 0, 0, 0, 501, 504, 1, 0, 0, 0, 502, 500, 1, 0, 0, 0, 502, 503, 1, 0, 0, 0, 503, 91, 1, 0, 0, 0, 504, 502, 1, 0, 0, 0, 505, 506, 3, 64, 32, 0, 506, 507, 5, 57, 0, 0, 507, 508, 3, 166, 83, 0, 508, 93, 1, 0, 0, 0, 509, 510, 5, 79, 0, 0, 510, 512, 3, 160, 80, 0, 511, 509, 1, 0, 0, 0, 511, 512, 1, 0, 0, 0, 512, 95, 1, 0, 0, 0, 513, 514, 5, 10, 0, 0, 514, 515, 3, 154, 77, 0, 515, 520, 3, 176, 88, 0, 516, 517, 5, 62, 0, 0, 517, 519, 3, 176, 88, 0, 518, 516, 1, 0, 0, 0, 519, 522, 1, 0, 0, 0, 520, 518, 1, 0, 0, 0, 520, 521, 1, 0, 0, 0, 521, 97, 1, 0, 0, 0, 522, 520, 1, 0, 0, 0, 523, 524, 5, 29, 0, 0, 524, 525, 3, 54, 27, 0, 525, 99, 1, 0, 0, 0, 526, 527, 5, 6, 0, 0, 527, 528, 3, 102, 51, 0, 528, 101, 1, 0, 0, 0, 529, 530, 5, 99, 0, 0, 530, 531, 3, 4, 2, 0, 531, 532, 5, 100, 0, 0, 532, 103, 1, 0, 0, 0, 533, 534, 5, 36, 0, 0, 534, 535, 5, 157, 0, 0, 535, 105, 1, 0, 0, 0, 536, 537, 5, 5, 0, 0, 537, 540, 3, 108, 54, 0, 538, 539, 5, 74, 0, 0, 539, 541, 3, 58, 29, 0, 540, 538, 1, 0, 0, 0, 540, 541, 1, 0, 0, 0, 541, 551, 1, 0, 0, 0, 542, 543, 5, 79, 0, 0, 543, 548, 3, 110, 55, 0, 544, 545, 5, 62, 0, 0, 545, 547, 3, 110, 55, 0, 546, 544, 1, 0, 0, 0, 547, 550, 1, 0, 0, 0, 548, 546, 1, 0, 0, 0, 548, 549, 1, 0, 0, 0, 549, 552, 1, 0, 0, 0, 550, 548, 1, 0, 0, 0, 551, 542, 1, 0, 0, 0, 551, 552, 1, 0, 0, 0, 552, 107, 1, 0, 0, 0, 553, 554, 7, 4, 0, 0, 554, 109, 1, 0, 0, 0, 555, 556, 3, 58, 29, 0, 556, 557, 5, 57, 0, 0, 557, 559, 1, 0, 0, 0, 558, 555, 1, 0, 0, 0, 558, 559, 1, 0, 0, 0, 559, 560, 1, 0, 0, 0, 560, 561, 3, 58, 29, 0, 561, 111, 1, 0, 0, 0, 562, 563, 5, 14, 0, 0, 563, 564, 3, 166, 83, 0, 564, 113, 1, 0, 0, 0, 565, 566, 5, 4, 0, 0, 566, 569, 3, 54, 27, 0, 567, 568, 5, 74, 0, 0, 568, 570, 3, 54, 27, 0, 569, 567, 1, 0, 0, 0, 569, 570, 1, 0, 0, 0, 570, 576, 1, 0, 0, 0, 571, 572, 5, 150, 0, 0, 572, 573, 3, 54, 27, 0, 573, 574, 5, 62, 0, 0, 574, 575, 3, 54, 27, 0, 575, 577, 1, 0, 0, 0, 576, 571, 1, 0, 0, 0, 576, 577, 1, 0, 0, 0, 577, 115, 1, 0, 0, 0, 578, 579, 5, 20, 0, 0, 579, 580, 3, 118, 59, 0, 580, 117, 1, 0, 0, 0, 581, 583, 3, 120, 60, 0, 582, 581, 1, 0, 0, 0, 583, 584, 1, 0, 0, 0, 584, 582, 1, 0, 0, 0, 584, 585, 1, 0, 0, 0, 585, 119, 1, 0, 0, 0, 586, 587, 5, 99, 0, 0, 587, 588, 3, 122, 61, 0, 588, 589, 5, 100, 0, 0, 589, 121, 1, 0, 0, 0, 590, 591, 6, 61, -1, 0, 591, 592, 3, 124, 62, 0, 592, 598, 1, 0, 0, 0, 593, 594, 10, 1, 0, 0, 594, 595, 5, 51, 0, 0, 595, 597, 3, 124, 62, 0, 596, 593, 1, 0, 0, 0, 597, 600, 1, 0, 0, 0, 598, 596, 1, 0, 0, 0, 598, 599, 1, 0, 0, 0, 599, 123, 1, 0, 0, 0, 600, 598, 1, 0, 0, 0, 601, 602, 3, 8, 4, 0, 602, 125, 1, 0, 0, 0, 603, 607, 5, 12, 0, 0, 604, 605, 3, 54, 27, 0, 605, 606, 5, 57, 0, 0, 606, 608, 1, 0, 0, 0, 607, 604, 1, 0, 0, 0, 607, 608, 1, 0, 0, 0, 608, 609, 1, 0, 0, 0, 609, 610, 3, 166, 83, 0, 610, 611, 5, 74, 0, 0, 611, 612, 3, 20, 10, 0, 612, 613, 3, 94, 47, 0, 613, 127, 1, 0, 0, 0, 614, 618, 5, 7, 0, 0, 615, 616, 3, 54, 27, 0, 616, 617, 5, 57, 0, 0, 617, 619, 1, 0, 0, 0, 618, 615, 1, 0, 0, 0, 618, 619, 1, 0, 0, 0, 619, 620, 1, 0, 0, 0, 620, 621, 3, 154, 77, 0, 621, 622, 3, 94, 47, 0, 622, 129, 1, 0, 0, 0, 623, 624, 5, 22, 0, 0, 624, 625, 5, 120, 0, 0, 625, 628, 3, 50, 25, 0, 626, 627, 5, 58, 0, 0, 627, 629, 3, 16, 8, 0, 628, 626, 1, 0, 0, 0, 628, 629, 1, 0, 0, 0, 629, 637, 1, 0, 0, 0, 630, 631, 5, 23, 0, 0, 631, 634, 3, 50, 25, 0, 632, 633, 5, 58, 0, 0, 633, 635, 3, 16, 8, 0, 634, 632, 1, 0, 0, 0, 634, 635, 1, 0, 0, 0, 635, 637, 1, 0, 0, 0, 636, 623, 1, 0, 0, 0, 636, 630, 1, 0, 0, 0, 637, 131, 1, 0, 0, 0, 638, 640, 5, 21, 0, 0, 639, 641, 3, 64, 32, 0, 640, 639, 1, 0, 0, 0, 640, 641, 1, 0, 0, 0, 641, 645, 1, 0, 0, 0, 642, 644, 3, 134, 67, 0, 643, 642, 1, 0, 0, 0, 644, 647, 1, 0, 0, 0, 645, 643, 1, 0, 0, 0, 645, 646, 1, 0, 0, 0, 646, 133, 1, 0, 0, 0, 647, 645, 1, 0, 0, 0, 648, 649, 5, 115, 0, 0, 649, 650, 5, 58, 0, 0, 650, 660, 3, 54, 27, 0, 651, 652, 5, 116, 0, 0, 652, 653, 5, 58, 0, 0, 653, 660, 3, 16, 8, 0, 654, 655, 5, 114, 0, 0, 655, 656, 5, 58, 0, 0, 656, 660, 3, 54, 27, 0, 657, 658, 5, 79, 0, 0, 658, 660, 3, 160, 80, 0, 659, 648, 1, 0, 0, 0, 659, 651, 1, 0, 0, 0, 659, 654, 1, 0, 0, 0, 659, 657, 1, 0, 0, 0, 660, 135, 1, 0, 0, 0, 661, 662, 5, 28, 0, 0, 662, 663, 3, 34, 17, 0, 663, 664, 5, 74, 0, 0, 664, 665, 3, 62, 31, 0, 665, 137, 1, 0, 0, 0, 666, 667, 5, 32, 0, 0, 667, 668, 3, 62, 31, 0, 668, 139, 1, 0, 0, 0, 669, 670, 5, 35, 0, 0, 670, 671, 3, 142, 71, 0, 671, 672, 5, 61, 0, 0, 672, 141, 1, 0, 0, 0, 673, 674, 3, 64, 32, 0, 674, 675, 5, 57, 0, 0, 675, 676, 3, 166, 83, 0, 676, 143, 1, 0, 0, 0, 677, 678, 6, 72, -1, 0, 678, 679, 5, 71, 0, 0, 679, 707, 3, 144, 72, 8, 680, 707, 3, 150, 75, 0, 681, 707, 3, 146, 73, 0, 682, 684, 3, 150, 75, 0, 683, 685, 5, 71, 0, 0, 684, 683, 1, 0, 0, 0, 684, 685, 1, 0, 0, 0, 685, 686, 1, 0, 0, 0, 686, 687, 5, 67, 0, 0, 687, 688, 5, 99, 0, 0, 688, 693, 3, 150, 75, 0, 689, 690, 5, 62, 0, 0, 690, 692, 3, 150, 75, 0, 691, 689, 1, 0, 0, 0, 692, 695, 1, 0, 0, 0, 693, 691, 1, 0, 0, 0, 693, 694, 1, 0, 0, 0, 694, 696, 1, 0, 0, 0, 695, 693, 1, 0, 0, 0, 696, 697, 5, 100, 0, 0, 697, 707, 1, 0, 0, 0, 698, 699, 3, 150, 75, 0, 699, 701, 5, 68, 0, 0, 700, 702, 5, 71, 0, 0, 701, 700, 1, 0, 0, 0, 701, 702, 1, 0, 0, 0, 702, 703, 1, 0, 0, 0, 703, 704, 5, 72, 0, 0, 704, 707, 1, 0, 0, 0, 705, 707, 3, 148, 74, 0, 706, 677, 1, 0, 0, 0, 706, 680, 1, 0, 0, 0, 706, 681, 1, 0, 0, 0, 706, 682, 1, 0, 0, 0, 706, 698, 1, 0, 0, 0, 706, 705, 1, 0, 0, 0, 707, 716, 1, 0, 0, 0, 708, 709, 10, 5, 0, 0, 709, 710, 5, 55, 0, 0, 710, 715, 3, 144, 72, 6, 711, 712, 10, 4, 0, 0, 712, 713, 5, 75, 0, 0, 713, 715, 3, 144, 72, 5, 714, 708, 1, 0, 0, 0, 714, 711, 1, 0, 0, 0, 715, 718, 1, 0, 0, 0, 716, 714, 1, 0, 0, 0, 716, 717, 1, 0, 0, 0, 717, 145, 1, 0, 0, 0, 718, 716, 1, 0, 0, 0, 719, 721, 3, 150, 75, 0, 720, 722, 5, 71, 0, 0, 721, 720, 1, 0, 0, 0, 721, 722, 1, 0, 0, 0, 722, 723, 1, 0, 0, 0, 723, 724, 5, 70, 0, 0, 724, 725, 3, 176, 88, 0, 725, 766, 1, 0, 0, 0, 726, 728, 3, 150, 75, 0, 727, 729, 5, 71, 0, 0, 728, 727, 1, 0, 0, 0, 728, 729, 1, 0, 0, 0, 729, 730, 1, 0, 0, 0, 730, 731, 5, 77, 0, 0, 731, 732, 3, 176, 88, 0, 732, 766, 1, 0, 0, 0, 733, 735, 3, 150, 75, 0, 734, 736, 5, 71, 0, 0, 735, 734, 1, 0, 0, 0, 735, 736, 1, 0, 0, 0, 736, 737, 1, 0, 0, 0, 737, 738, 5, 70, 0, 0, 738, 739, 5, 99, 0, 0, 739, 744, 3, 176, 88, 0, 740, 741, 5, 62, 0, 0, 741, 743, 3, 176, 88, 0, 742, 740, 1, 0, 0, 0, 743, 746, 1, 0, 0, 0, 744, 742, 1, 0, 0, 0, 744, 745, 1, 0, 0, 0, 745, 747, 1, 0, 0, 0, 746, 744, 1, 0, 0, 0, 747, 748, 5, 100, 0, 0, 748, 766, 1, 0, 0, 0, 749, 751, 3, 150, 75, 0, 750, 752, 5, 71, 0, 0, 751, 750, 1, 0, 0, 0, 751, 752, 1, 0, 0, 0, 752, 753, 1, 0, 0, 0, 753, 754, 5, 77, 0, 0, 754, 755, 5, 99, 0, 0, 755, 760, 3, 176, 88, 0, 756, 757, 5, 62, 0, 0, 757, 759, 3, 176, 88, 0, 758, 756, 1, 0, 0, 0, 759, 762, 1, 0, 0, 0, 760, 758, 1, 0, 0, 0, 760, 761, 1, 0, 0, 0, 761, 763, 1, 0, 0, 0, 762, 760, 1, 0, 0, 0, 763, 764, 5, 100, 0, 0, 764, 766, 1, 0, 0, 0, 765, 719, 1, 0, 0, 0, 765, 726, 1, 0, 0, 0, 765, 733, 1, 0, 0, 0, 765, 749, 1, 0, 0, 0, 766, 147, 1, 0, 0, 0, 767, 770, 3, 54, 27, 0, 768, 769, 5, 59, 0, 0, 769, 771, 3, 12, 6, 0, 770, 768, 1, 0, 0, 0, 770, 771, 1, 0, 0, 0, 771, 772, 1, 0, 0, 0, 772, 773, 5, 60, 0, 0, 773, 774, 3, 166, 83, 0, 774, 149, 1, 0, 0, 0, 775, 781, 3, 152, 76, 0, 776, 777, 3, 152, 76, 0, 777, 778, 3, 178, 89, 0, 778, 779, 3, 152, 76, 0, 779, 781, 1, 0, 0, 0, 780, 775, 1, 0, 0, 0, 780, 776, 1, 0, 0, 0, 781, 151, 1, 0, 0, 0, 782, 783, 6, 76, -1, 0, 783, 787, 3, 154, 77, 0, 784, 785, 7, 5, 0, 0, 785, 787, 3, 152, 76, 3, 786, 782, 1, 0, 0, 0, 786, 784, 1, 0, 0, 0, 787, 796, 1, 0, 0, 0, 788, 789, 10, 2, 0, 0, 789, 790, 7, 6, 0, 0, 790, 795, 3, 152, 76, 3, 791, 792, 10, 1, 0, 0, 792, 793, 7, 5, 0, 0, 793, 795, 3, 152, 76, 2, 794, 788, 1, 0, 0, 0, 794, 791, 1, 0, 0, 0, 795, 798, 1, 0, 0, 0, 796, 794, 1, 0, 0, 0, 796, 797, 1, 0, 0, 0, 797, 153, 1, 0, 0, 0, 798, 796, 1, 0, 0, 0, 799, 800, 6, 77, -1, 0, 800, 808, 3, 166, 83, 0, 801, 808, 3, 54, 27, 0, 802, 808, 3, 156, 78, 0, 803, 804, 5, 99, 0, 0, 804, 805, 3, 144, 72, 0, 805, 806, 5, 100, 0, 0, 806, 808, 1, 0, 0, 0, 807, 799, 1, 0, 0, 0, 807, 801, 1, 0, 0, 0, 807, 802, 1, 0, 0, 0, 807, 803, 1, 0, 0, 0, 808, 814, 1, 0, 0, 0, 809, 810, 10, 1, 0, 0, 810, 811, 5, 59, 0, 0, 811, 813, 3, 12, 6, 0, 812, 809, 1, 0, 0, 0, 813, 816, 1, 0, 0, 0, 814, 812, 1, 0, 0, 0, 814, 815, 1, 0, 0, 0, 815, 155, 1, 0, 0, 0, 816, 814, 1, 0, 0, 0, 817, 818, 3, 158, 79, 0, 818, 832, 5, 99, 0, 0, 819, 833, 5, 89, 0, 0, 820, 825, 3, 144, 72, 0, 821, 822, 5, 62, 0, 0, 822, 824, 3, 144, 72, 0, 823, 821, 1, 0, 0, 0, 824, 827, 1, 0, 0, 0, 825, 823, 1, 0, 0, 0, 825, 826, 1, 0, 0, 0, 826, 830, 1, 0, 0, 0, 827, 825, 1, 0, 0, 0, 828, 829, 5, 62, 0, 0, 829, 831, 3, 160, 80, 0, 830, 828, 1, 0, 0, 0, 830, 831, 1, 0, 0, 0, 831, 833, 1, 0, 0, 0, 832, 819, 1, 0, 0, 0, 832, 820, 1, 0, 0, 0, 832, 833, 1, 0, 0, 0, 833, 834, 1, 0, 0, 0, 834, 835, 5, 100, 0, 0, 835, 157, 1, 0, 0, 0, 836, 840, 3, 72, 36, 0, 837, 840, 5, 66, 0, 0, 838, 840, 5, 69, 0, 0, 839, 836, 1, 0, 0, 0, 839, 837, 1, 0, 0, 0, 839, 838, 1, 0, 0, 0, 840, 159, 1, 0, 0, 0, 841, 850, 5, 92, 0, 0, 842, 847, 3, 162, 81, 0, 843, 844, 5, 62, 0, 0, 844, 846, 3, 162, 81, 0, 845, 843, 1, 0, 0, 0, 846, 849, 1, 0, 0, 0, 847, 845, 1, 0, 0, 0, 847, 848, 1, 0, 0, 0, 848, 851, 1, 0, 0, 0, 849, 847, 1, 0, 0, 0, 850, 842, 1, 0, 0, 0, 850, 851, 1, 0, 0, 0, 851, 852, 1, 0, 0, 0, 852, 853, 5, 93, 0, 0, 853, 161, 1, 0, 0, 0, 854, 855, 3, 176, 88, 0, 855, 856, 5, 60, 0, 0, 856, 857, 3, 164, 82, 0, 857, 163, 1, 0, 0, 0, 858, 861, 3, 166, 83, 0, 859, 861, 3, 160, 80, 0, 860, 858, 1, 0, 0, 0, 860, 859, 1, 0, 0, 0, 861, 165, 1, 0, 0, 0, 862, 905, 5, 72, 0, 0, 863, 864, 3, 174, 87, 0, 864, 865, 5, 101, 0, 0, 865, 905, 1, 0, 0, 0, 866, 905, 3, 172, 86, 0, 867, 905, 3, 174, 87, 0, 868, 905, 3, 168, 84, 0, 869, 905, 3, 68, 34, 0, 870, 905, 3, 176, 88, 0, 871, 872, 5, 97, 0, 0, 872, 877, 3, 170, 85, 0, 873, 874, 5, 62, 0, 0, 874, 876, 3, 170, 85, 0, 875, 873, 1, 0, 0, 0, 876, 879, 1, 0, 0, 0, 877, 875, 1, 0, 0, 0, 877, 878, 1, 0, 0, 0, 878, 880, 1, 0, 0, 0, 879, 877, 1, 0, 0, 0, 880, 881, 5, 98, 0, 0, 881, 905, 1, 0, 0, 0, 882, 883, 5, 97, 0, 0, 883, 888, 3, 168, 84, 0, 884, 885, 5, 62, 0, 0, 885, 887, 3, 168, 84, 0, 886, 884, 1, 0, 0, 0, 887, 890, 1, 0, 0, 0, 888, 886, 1, 0, 0, 0, 888, 889, 1, 0, 0, 0, 889, 891, 1, 0, 0, 0, 890, 888, 1, 0, 0, 0, 891, 892, 5, 98, 0, 0, 892, 905, 1, 0, 0, 0, 893, 894, 5, 97, 0, 0, 894, 899, 3, 176, 88, 0, 895, 896, 5, 62, 0, 0, 896, 898, 3, 176, 88, 0, 897, 895, 1, 0, 0, 0, 898, 901, 1, 0, 0, 0, 899, 897, 1, 0, 0, 0, 899, 900, 1, 0, 0, 0, 900, 902, 1, 0, 0, 0, 901, 899, 1, 0, 0, 0, 902, 903, 5, 98, 0, 0, 903, 905, 1, 0, 0, 0, 904, 862, 1, 0, 0, 0, 904, 863, 1, 0, 0, 0, 904, 866, 1, 0, 0, 0, 904, 867, 1, 0, 0, 0, 904, 868, 1, 0, 0, 0, 904, 869, 1, 0, 0, 0, 904, 870, 1, 0, 0, 0, 904, 871, 1, 0, 0, 0, 904, 882, 1, 0, 0, 0, 904, 893, 1, 0, 0, 0, 905, 167, 1, 0, 0, 0, 906, 907, 7, 7, 0, 0, 907, 169, 1, 0, 0, 0, 908, 911, 3, 172, 86, 0, 909, 911, 3, 174, 87, 0, 910, 908, 1, 0, 0, 0, 910, 909, 1, 0, 0, 0, 911, 171, 1, 0, 0, 0, 912, 914, 7, 5, 0, 0, 913, 912, 1, 0, 0, 0, 913, 914, 1, 0, 0, 0, 914, 915, 1, 0, 0, 0, 915, 916, 5, 54, 0, 0, 916, 173, 1, 0, 0, 0, 917, 919, 7, 5, 0, 0, 918, 917, 1, 0, 0, 0, 918, 919, 1, 0, 0, 0, 919, 920, 1, 0, 0, 0, 920, 921, 5, 53, 0, 0, 921, 175, 1, 0, 0, 0, 922, 923, 5, 52, 0, 0, 923, 177, 1, 0, 0, 0, 924, 925, 7, 8, 0, 0, 925, 179, 1, 0, 0, 0, 926, 927, 7, 9, 0, 0, 927, 928, 5, 124, 0, 0, 928, 929, 3, 182, 91, 0, 929, 930, 3, 184, 92, 0, 930, 181, 1, 0, 0, 0, 931, 932, 4, 91, 14, 0, 932, 934, 3, 34, 17, 0, 933, 935, 5, 150, 0, 0, 934, 933, 1, 0, 0, 0, 934, 935, 1, 0, 0, 0, 935, 936, 1, 0, 0, 0, 936, 937, 5, 107, 0, 0, 937, 940, 1, 0, 0, 0, 938, 940, 3, 34, 17, 0, 939, 931, 1, 0, 0, 0, 939, 938, 1, 0, 0, 0, 940, 183, 1, 0, 0, 0, 941, 942, 5, 74, 0, 0, 942, 947, 3, 144, 72, 0, 943, 944, 5, 62, 0, 0, 944, 946, 3, 144, 72, 0, 945, 943, 1, 0, 0, 0, 946, 949, 1, 0, 0, 0, 947, 945, 1, 0, 0, 0, 947, 948, 1, 0, 0, 0, 948, 185, 1, 0, 0, 0, 949, 947, 1, 0, 0, 0, 950, 952, 5, 33, 0, 0, 951, 953, 3, 188, 94, 0, 952, 951, 1, 0, 0, 0, 953, 954, 1, 0, 0, 0, 954, 952, 1, 0, 0, 0, 954, 955, 1, 0, 0, 0, 955, 956, 1, 0, 0, 0, 956, 960, 5, 99, 0, 0, 957, 959, 3, 192, 96, 0, 958, 957, 1, 0, 0, 0, 959, 962, 1, 0, 0, 0, 960, 958, 1, 0, 0, 0, 960, 961, 1, 0, 0, 0, 961, 963, 1, 0, 0, 0, 962, 960, 1, 0, 0, 0, 963, 964, 5, 100, 0, 0, 964, 187, 1, 0, 0, 0, 965, 966, 3, 190, 95, 0, 966, 967, 3, 190, 95, 0, 967, 189, 1, 0, 0, 0, 968, 969, 7, 10, 0, 0, 969, 191, 1, 0, 0, 0, 970, 980, 5, 146, 0, 0, 971, 975, 5, 99, 0, 0, 972, 974, 3, 192, 96, 0, 973, 972, 1, 0, 0, 0, 974, 977, 1, 0, 0, 0, 975, 973, 1, 0, 0, 0, 975, 976, 1, 0, 0, 0, 976, 978, 1, 0, 0, 0, 977, 975, 1, 0, 0, 0, 978, 980, 5, 100, 0, 0, 979, 970, 1, 0, 0, 0, 979, 971, 1, 0, 0, 0, 980, 193, 1, 0, 0, 0, 95, 197, 214, 223, 251, 266, 272, 281, 287, 300, 304, 309, 317, 331, 347, 355, 359, 366, 372, 377, 386, 393, 399, 408, 415, 423, 431, 435, 439, 444, 455, 460, 464, 478, 489, 495, 502, 511, 520, 540, 548, 551, 558, 569, 576, 584, 598, 607, 618, 628, 634, 636, 640, 645, 659, 684, 693, 701, 706, 714, 716, 721, 728, 735, 744, 751, 760, 765, 770, 780, 786, 794, 796, 807, 814, 825, 830, 832, 839, 847, 850, 860, 877, 888, 899, 904, 910, 913, 918, 934, 939, 947, 954, 960, 975, 979] \ No newline at end of file diff --git a/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/parser/EsqlBaseParser.java b/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/parser/EsqlBaseParser.java index bd51bf8b75e86..a438e1015f3e6 100644 --- a/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/parser/EsqlBaseParser.java +++ b/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/parser/EsqlBaseParser.java @@ -30,32 +30,35 @@ public class EsqlBaseParser extends ParserConfig { SAMPLE=14, SORT=15, STATS=16, WHERE=17, FROM=18, TS=19, FORK=20, FUSE=21, INLINE=22, INLINESTATS=23, JOIN_LOOKUP=24, DEV_JOIN_FULL=25, DEV_JOIN_LEFT=26, DEV_JOIN_RIGHT=27, DEV_LOOKUP=28, MV_EXPAND=29, DROP=30, KEEP=31, DEV_INSIST=32, - RENAME=33, SET=34, SHOW=35, UNKNOWN_CMD=36, CHANGE_POINT_LINE_COMMENT=37, - CHANGE_POINT_MULTILINE_COMMENT=38, CHANGE_POINT_WS=39, ENRICH_POLICY_NAME=40, - ENRICH_LINE_COMMENT=41, ENRICH_MULTILINE_COMMENT=42, ENRICH_WS=43, ENRICH_FIELD_LINE_COMMENT=44, - ENRICH_FIELD_MULTILINE_COMMENT=45, ENRICH_FIELD_WS=46, EXPLAIN_WS=47, - EXPLAIN_LINE_COMMENT=48, EXPLAIN_MULTILINE_COMMENT=49, PIPE=50, QUOTED_STRING=51, - INTEGER_LITERAL=52, DECIMAL_LITERAL=53, AND=54, ASC=55, ASSIGN=56, BY=57, - CAST_OP=58, COLON=59, SEMICOLON=60, COMMA=61, DESC=62, DOT=63, FALSE=64, - FIRST=65, IN=66, IS=67, LAST=68, LIKE=69, NOT=70, NULL=71, NULLS=72, ON=73, - OR=74, PARAM=75, RLIKE=76, TRUE=77, WITH=78, EQ=79, CIEQ=80, NEQ=81, LT=82, - LTE=83, GT=84, GTE=85, PLUS=86, MINUS=87, ASTERISK=88, SLASH=89, PERCENT=90, - LEFT_BRACES=91, RIGHT_BRACES=92, DOUBLE_PARAMS=93, NAMED_OR_POSITIONAL_PARAM=94, - NAMED_OR_POSITIONAL_DOUBLE_PARAMS=95, OPENING_BRACKET=96, CLOSING_BRACKET=97, - LP=98, RP=99, UNQUOTED_IDENTIFIER=100, QUOTED_IDENTIFIER=101, EXPR_LINE_COMMENT=102, - EXPR_MULTILINE_COMMENT=103, EXPR_WS=104, METADATA=105, UNQUOTED_SOURCE=106, - FROM_LINE_COMMENT=107, FROM_MULTILINE_COMMENT=108, FROM_WS=109, FORK_WS=110, - FORK_LINE_COMMENT=111, FORK_MULTILINE_COMMENT=112, GROUP=113, SCORE=114, - KEY=115, FUSE_LINE_COMMENT=116, FUSE_MULTILINE_COMMENT=117, FUSE_WS=118, - INLINE_STATS=119, INLINE_LINE_COMMENT=120, INLINE_MULTILINE_COMMENT=121, - INLINE_WS=122, JOIN=123, USING=124, JOIN_LINE_COMMENT=125, JOIN_MULTILINE_COMMENT=126, - JOIN_WS=127, LOOKUP_LINE_COMMENT=128, LOOKUP_MULTILINE_COMMENT=129, LOOKUP_WS=130, - LOOKUP_FIELD_LINE_COMMENT=131, LOOKUP_FIELD_MULTILINE_COMMENT=132, LOOKUP_FIELD_WS=133, - MVEXPAND_LINE_COMMENT=134, MVEXPAND_MULTILINE_COMMENT=135, MVEXPAND_WS=136, - ID_PATTERN=137, PROJECT_LINE_COMMENT=138, PROJECT_MULTILINE_COMMENT=139, - PROJECT_WS=140, AS=141, RENAME_LINE_COMMENT=142, RENAME_MULTILINE_COMMENT=143, - RENAME_WS=144, SET_LINE_COMMENT=145, SET_MULTILINE_COMMENT=146, SET_WS=147, - INFO=148, SHOW_LINE_COMMENT=149, SHOW_MULTILINE_COMMENT=150, SHOW_WS=151; + DEV_PROMQL=33, RENAME=34, SET=35, SHOW=36, UNKNOWN_CMD=37, CHANGE_POINT_LINE_COMMENT=38, + CHANGE_POINT_MULTILINE_COMMENT=39, CHANGE_POINT_WS=40, ENRICH_POLICY_NAME=41, + ENRICH_LINE_COMMENT=42, ENRICH_MULTILINE_COMMENT=43, ENRICH_WS=44, ENRICH_FIELD_LINE_COMMENT=45, + ENRICH_FIELD_MULTILINE_COMMENT=46, ENRICH_FIELD_WS=47, EXPLAIN_WS=48, + EXPLAIN_LINE_COMMENT=49, EXPLAIN_MULTILINE_COMMENT=50, PIPE=51, QUOTED_STRING=52, + INTEGER_LITERAL=53, DECIMAL_LITERAL=54, AND=55, ASC=56, ASSIGN=57, BY=58, + CAST_OP=59, COLON=60, SEMICOLON=61, COMMA=62, DESC=63, DOT=64, FALSE=65, + FIRST=66, IN=67, IS=68, LAST=69, LIKE=70, NOT=71, NULL=72, NULLS=73, ON=74, + OR=75, PARAM=76, RLIKE=77, TRUE=78, WITH=79, EQ=80, CIEQ=81, NEQ=82, LT=83, + LTE=84, GT=85, GTE=86, PLUS=87, MINUS=88, ASTERISK=89, SLASH=90, PERCENT=91, + LEFT_BRACES=92, RIGHT_BRACES=93, DOUBLE_PARAMS=94, NAMED_OR_POSITIONAL_PARAM=95, + NAMED_OR_POSITIONAL_DOUBLE_PARAMS=96, OPENING_BRACKET=97, CLOSING_BRACKET=98, + LP=99, RP=100, UNQUOTED_IDENTIFIER=101, QUOTED_IDENTIFIER=102, EXPR_LINE_COMMENT=103, + EXPR_MULTILINE_COMMENT=104, EXPR_WS=105, METADATA=106, UNQUOTED_SOURCE=107, + FROM_LINE_COMMENT=108, FROM_MULTILINE_COMMENT=109, FROM_WS=110, FORK_WS=111, + FORK_LINE_COMMENT=112, FORK_MULTILINE_COMMENT=113, GROUP=114, SCORE=115, + KEY=116, FUSE_LINE_COMMENT=117, FUSE_MULTILINE_COMMENT=118, FUSE_WS=119, + INLINE_STATS=120, INLINE_LINE_COMMENT=121, INLINE_MULTILINE_COMMENT=122, + INLINE_WS=123, JOIN=124, USING=125, JOIN_LINE_COMMENT=126, JOIN_MULTILINE_COMMENT=127, + JOIN_WS=128, LOOKUP_LINE_COMMENT=129, LOOKUP_MULTILINE_COMMENT=130, LOOKUP_WS=131, + LOOKUP_FIELD_LINE_COMMENT=132, LOOKUP_FIELD_MULTILINE_COMMENT=133, LOOKUP_FIELD_WS=134, + MVEXPAND_LINE_COMMENT=135, MVEXPAND_MULTILINE_COMMENT=136, MVEXPAND_WS=137, + ID_PATTERN=138, PROJECT_LINE_COMMENT=139, PROJECT_MULTILINE_COMMENT=140, + PROJECT_WS=141, PROMQL_UNQUOTED_IDENTIFIER=142, PROMQL_PARAMS_LINE_COMMENT=143, + PROMQL_PARAMS_MULTILINE_COMMENT=144, PROMQL_PARAMS_WS=145, PROMQL_QUERY_TEXT=146, + PROMQL_QUERY_LINE_COMMENT=147, PROMQL_QUERY_MULTILINE_COMMENT=148, PROMQL_QUERY_WS=149, + AS=150, RENAME_LINE_COMMENT=151, RENAME_MULTILINE_COMMENT=152, RENAME_WS=153, + SET_LINE_COMMENT=154, SET_MULTILINE_COMMENT=155, SET_WS=156, INFO=157, + SHOW_LINE_COMMENT=158, SHOW_MULTILINE_COMMENT=159, SHOW_WS=160; public static final int RULE_statements = 0, RULE_singleStatement = 1, RULE_query = 2, RULE_sourceCommand = 3, RULE_processingCommand = 4, RULE_whereCommand = 5, RULE_dataType = 6, @@ -85,7 +88,9 @@ public class EsqlBaseParser extends ParserConfig { RULE_functionName = 79, RULE_mapExpression = 80, RULE_entryExpression = 81, RULE_mapValue = 82, RULE_constant = 83, RULE_booleanValue = 84, RULE_numericValue = 85, RULE_decimalValue = 86, RULE_integerValue = 87, RULE_string = 88, RULE_comparisonOperator = 89, - RULE_joinCommand = 90, RULE_joinTarget = 91, RULE_joinCondition = 92; + RULE_joinCommand = 90, RULE_joinTarget = 91, RULE_joinCondition = 92, + RULE_promqlCommand = 93, RULE_promqlParam = 94, RULE_promqlParamContent = 95, + RULE_promqlQueryPart = 96; private static String[] makeRuleNames() { return new String[] { "statements", "singleStatement", "query", "sourceCommand", "processingCommand", @@ -109,7 +114,8 @@ private static String[] makeRuleNames() { "functionExpression", "functionName", "mapExpression", "entryExpression", "mapValue", "constant", "booleanValue", "numericValue", "decimalValue", "integerValue", "string", "comparisonOperator", "joinCommand", "joinTarget", - "joinCondition" + "joinCondition", "promqlCommand", "promqlParam", "promqlParamContent", + "promqlQueryPart" }; } public static final String[] ruleNames = makeRuleNames(); @@ -120,18 +126,19 @@ private static String[] makeLiteralNames() { "'dissect'", "'eval'", "'grok'", "'limit'", "'rerank'", "'row'", "'sample'", "'sort'", null, "'where'", "'from'", "'ts'", "'fork'", "'fuse'", "'inline'", "'inlinestats'", "'lookup'", null, null, null, null, "'mv_expand'", "'drop'", - "'keep'", null, "'rename'", "'set'", "'show'", null, null, null, null, - null, null, null, null, null, null, null, null, null, null, "'|'", null, - null, null, "'and'", "'asc'", "'='", "'by'", "'::'", "':'", "';'", "','", - "'desc'", "'.'", "'false'", "'first'", "'in'", "'is'", "'last'", "'like'", - "'not'", "'null'", "'nulls'", "'on'", "'or'", "'?'", "'rlike'", "'true'", - "'with'", "'=='", "'=~'", "'!='", "'<'", "'<='", "'>'", "'>='", "'+'", - "'-'", "'*'", "'/'", "'%'", "'{'", "'}'", "'??'", null, null, null, "']'", - null, "')'", null, null, null, null, null, "'metadata'", null, null, - null, null, null, null, null, "'group'", "'score'", "'key'", null, null, - null, null, null, null, null, "'join'", "'USING'", null, null, null, + "'keep'", null, null, "'rename'", "'set'", "'show'", null, null, null, + null, null, null, null, null, null, null, null, null, null, null, "'|'", + null, null, null, "'and'", "'asc'", "'='", "'by'", "'::'", "':'", "';'", + "','", "'desc'", "'.'", "'false'", "'first'", "'in'", "'is'", "'last'", + "'like'", "'not'", "'null'", "'nulls'", "'on'", "'or'", "'?'", "'rlike'", + "'true'", "'with'", "'=='", "'=~'", "'!='", "'<'", "'<='", "'>'", "'>='", + "'+'", "'-'", "'*'", "'/'", "'%'", "'{'", "'}'", "'??'", null, null, + null, "']'", null, "')'", null, null, null, null, null, "'metadata'", + null, null, null, null, null, null, null, "'group'", "'score'", "'key'", + null, null, null, null, null, null, null, "'join'", "'USING'", null, null, null, null, null, null, null, null, null, null, null, null, null, - null, "'as'", null, null, null, null, null, null, "'info'" + null, null, null, null, null, null, null, null, null, null, null, "'as'", + null, null, null, null, null, null, "'info'" }; } private static final String[] _LITERAL_NAMES = makeLiteralNames(); @@ -142,7 +149,7 @@ private static String[] makeSymbolicNames() { "ROW", "SAMPLE", "SORT", "STATS", "WHERE", "FROM", "TS", "FORK", "FUSE", "INLINE", "INLINESTATS", "JOIN_LOOKUP", "DEV_JOIN_FULL", "DEV_JOIN_LEFT", "DEV_JOIN_RIGHT", "DEV_LOOKUP", "MV_EXPAND", "DROP", "KEEP", "DEV_INSIST", - "RENAME", "SET", "SHOW", "UNKNOWN_CMD", "CHANGE_POINT_LINE_COMMENT", + "DEV_PROMQL", "RENAME", "SET", "SHOW", "UNKNOWN_CMD", "CHANGE_POINT_LINE_COMMENT", "CHANGE_POINT_MULTILINE_COMMENT", "CHANGE_POINT_WS", "ENRICH_POLICY_NAME", "ENRICH_LINE_COMMENT", "ENRICH_MULTILINE_COMMENT", "ENRICH_WS", "ENRICH_FIELD_LINE_COMMENT", "ENRICH_FIELD_MULTILINE_COMMENT", "ENRICH_FIELD_WS", "EXPLAIN_WS", "EXPLAIN_LINE_COMMENT", @@ -163,9 +170,12 @@ private static String[] makeSymbolicNames() { "LOOKUP_MULTILINE_COMMENT", "LOOKUP_WS", "LOOKUP_FIELD_LINE_COMMENT", "LOOKUP_FIELD_MULTILINE_COMMENT", "LOOKUP_FIELD_WS", "MVEXPAND_LINE_COMMENT", "MVEXPAND_MULTILINE_COMMENT", "MVEXPAND_WS", "ID_PATTERN", "PROJECT_LINE_COMMENT", - "PROJECT_MULTILINE_COMMENT", "PROJECT_WS", "AS", "RENAME_LINE_COMMENT", - "RENAME_MULTILINE_COMMENT", "RENAME_WS", "SET_LINE_COMMENT", "SET_MULTILINE_COMMENT", - "SET_WS", "INFO", "SHOW_LINE_COMMENT", "SHOW_MULTILINE_COMMENT", "SHOW_WS" + "PROJECT_MULTILINE_COMMENT", "PROJECT_WS", "PROMQL_UNQUOTED_IDENTIFIER", + "PROMQL_PARAMS_LINE_COMMENT", "PROMQL_PARAMS_MULTILINE_COMMENT", "PROMQL_PARAMS_WS", + "PROMQL_QUERY_TEXT", "PROMQL_QUERY_LINE_COMMENT", "PROMQL_QUERY_MULTILINE_COMMENT", + "PROMQL_QUERY_WS", "AS", "RENAME_LINE_COMMENT", "RENAME_MULTILINE_COMMENT", + "RENAME_WS", "SET_LINE_COMMENT", "SET_MULTILINE_COMMENT", "SET_WS", "INFO", + "SHOW_LINE_COMMENT", "SHOW_MULTILINE_COMMENT", "SHOW_WS" }; } private static final String[] _SYMBOLIC_NAMES = makeSymbolicNames(); @@ -259,25 +269,25 @@ public final StatementsContext statements() throws RecognitionException { int _alt; enterOuterAlt(_localctx, 1); { - setState(189); + setState(197); _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(186); + setState(194); setCommand(); } } } - setState(191); + setState(199); _errHandler.sync(this); _alt = getInterpreter().adaptivePredict(_input,0,_ctx); } - setState(192); + setState(200); singleStatement(); - setState(193); + setState(201); match(EOF); } } @@ -324,9 +334,9 @@ public final SingleStatementContext singleStatement() throws RecognitionExceptio try { enterOuterAlt(_localctx, 1); { - setState(195); + setState(203); query(0); - setState(196); + setState(204); match(EOF); } } @@ -422,11 +432,11 @@ private QueryContext query(int _p) throws RecognitionException { _ctx = _localctx; _prevctx = _localctx; - setState(199); + setState(207); sourceCommand(); } _ctx.stop = _input.LT(-1); - setState(206); + setState(214); _errHandler.sync(this); _alt = getInterpreter().adaptivePredict(_input,1,_ctx); while ( _alt!=2 && _alt!=org.antlr.v4.runtime.atn.ATN.INVALID_ALT_NUMBER ) { @@ -437,16 +447,16 @@ private QueryContext query(int _p) throws RecognitionException { { _localctx = new CompositeQueryContext(new QueryContext(_parentctx, _parentState)); pushNewRecursionContext(_localctx, _startState, RULE_query); - setState(201); + setState(209); if (!(precpred(_ctx, 1))) throw new FailedPredicateException(this, "precpred(_ctx, 1)"); - setState(202); + setState(210); match(PIPE); - setState(203); + setState(211); processingCommand(); } } } - setState(208); + setState(216); _errHandler.sync(this); _alt = getInterpreter().adaptivePredict(_input,1,_ctx); } @@ -504,43 +514,43 @@ public final SourceCommandContext sourceCommand() throws RecognitionException { SourceCommandContext _localctx = new SourceCommandContext(_ctx, getState()); enterRule(_localctx, 6, RULE_sourceCommand); try { - setState(215); + setState(223); _errHandler.sync(this); switch ( getInterpreter().adaptivePredict(_input,2,_ctx) ) { case 1: enterOuterAlt(_localctx, 1); { - setState(209); + setState(217); fromCommand(); } break; case 2: enterOuterAlt(_localctx, 2); { - setState(210); + setState(218); rowCommand(); } break; case 3: enterOuterAlt(_localctx, 3); { - setState(211); + setState(219); showCommand(); } break; case 4: enterOuterAlt(_localctx, 4); { - setState(212); + setState(220); timeSeriesCommand(); } break; case 5: enterOuterAlt(_localctx, 5); { - setState(213); + setState(221); if (!(this.isDevVersion())) throw new FailedPredicateException(this, "this.isDevVersion()"); - setState(214); + setState(222); explainCommand(); } break; @@ -625,6 +635,9 @@ public LookupCommandContext lookupCommand() { public InsistCommandContext insistCommand() { return getRuleContext(InsistCommandContext.class,0); } + public PromqlCommandContext promqlCommand() { + return getRuleContext(PromqlCommandContext.class,0); + } @SuppressWarnings("this-escape") public ProcessingCommandContext(ParserRuleContext parent, int invokingState) { super(parent, invokingState); @@ -649,167 +662,176 @@ public final ProcessingCommandContext processingCommand() throws RecognitionExce ProcessingCommandContext _localctx = new ProcessingCommandContext(_ctx, getState()); enterRule(_localctx, 8, RULE_processingCommand); try { - setState(241); + setState(251); _errHandler.sync(this); switch ( getInterpreter().adaptivePredict(_input,3,_ctx) ) { case 1: enterOuterAlt(_localctx, 1); { - setState(217); + setState(225); evalCommand(); } break; case 2: enterOuterAlt(_localctx, 2); { - setState(218); + setState(226); whereCommand(); } break; case 3: enterOuterAlt(_localctx, 3); { - setState(219); + setState(227); keepCommand(); } break; case 4: enterOuterAlt(_localctx, 4); { - setState(220); + setState(228); limitCommand(); } break; case 5: enterOuterAlt(_localctx, 5); { - setState(221); + setState(229); statsCommand(); } break; case 6: enterOuterAlt(_localctx, 6); { - setState(222); + setState(230); sortCommand(); } break; case 7: enterOuterAlt(_localctx, 7); { - setState(223); + setState(231); dropCommand(); } break; case 8: enterOuterAlt(_localctx, 8); { - setState(224); + setState(232); renameCommand(); } break; case 9: enterOuterAlt(_localctx, 9); { - setState(225); + setState(233); dissectCommand(); } break; case 10: enterOuterAlt(_localctx, 10); { - setState(226); + setState(234); grokCommand(); } break; case 11: enterOuterAlt(_localctx, 11); { - setState(227); + setState(235); enrichCommand(); } break; case 12: enterOuterAlt(_localctx, 12); { - setState(228); + setState(236); mvExpandCommand(); } break; case 13: enterOuterAlt(_localctx, 13); { - setState(229); + setState(237); joinCommand(); } break; case 14: enterOuterAlt(_localctx, 14); { - setState(230); + setState(238); changePointCommand(); } break; case 15: enterOuterAlt(_localctx, 15); { - setState(231); + setState(239); completionCommand(); } break; case 16: enterOuterAlt(_localctx, 16); { - setState(232); + setState(240); sampleCommand(); } break; case 17: enterOuterAlt(_localctx, 17); { - setState(233); + setState(241); forkCommand(); } break; case 18: enterOuterAlt(_localctx, 18); { - setState(234); + setState(242); rerankCommand(); } break; case 19: enterOuterAlt(_localctx, 19); { - setState(235); + setState(243); inlineStatsCommand(); } break; case 20: enterOuterAlt(_localctx, 20); { - setState(236); + setState(244); fuseCommand(); } break; case 21: enterOuterAlt(_localctx, 21); { - setState(237); + setState(245); if (!(this.isDevVersion())) throw new FailedPredicateException(this, "this.isDevVersion()"); - setState(238); + setState(246); lookupCommand(); } break; case 22: enterOuterAlt(_localctx, 22); { - setState(239); + setState(247); if (!(this.isDevVersion())) throw new FailedPredicateException(this, "this.isDevVersion()"); - setState(240); + setState(248); insistCommand(); } break; + case 23: + enterOuterAlt(_localctx, 23); + { + setState(249); + if (!(this.isDevVersion())) throw new FailedPredicateException(this, "this.isDevVersion()"); + setState(250); + promqlCommand(); + } + break; } } catch (RecognitionException re) { @@ -855,9 +877,9 @@ public final WhereCommandContext whereCommand() throws RecognitionException { try { enterOuterAlt(_localctx, 1); { - setState(243); + setState(253); match(WHERE); - setState(244); + setState(254); booleanExpression(0); } } @@ -915,7 +937,7 @@ public final DataTypeContext dataType() throws RecognitionException { _localctx = new ToDataTypeContext(_localctx); enterOuterAlt(_localctx, 1); { - setState(246); + setState(256); identifier(); } } @@ -962,9 +984,9 @@ public final RowCommandContext rowCommand() throws RecognitionException { try { enterOuterAlt(_localctx, 1); { - setState(248); + setState(258); match(ROW); - setState(249); + setState(259); fields(); } } @@ -1018,23 +1040,23 @@ public final FieldsContext fields() throws RecognitionException { int _alt; enterOuterAlt(_localctx, 1); { - setState(251); + setState(261); field(); - setState(256); + setState(266); _errHandler.sync(this); _alt = getInterpreter().adaptivePredict(_input,4,_ctx); while ( _alt!=2 && _alt!=org.antlr.v4.runtime.atn.ATN.INVALID_ALT_NUMBER ) { if ( _alt==1 ) { { { - setState(252); + setState(262); match(COMMA); - setState(253); + setState(263); field(); } } } - setState(258); + setState(268); _errHandler.sync(this); _alt = getInterpreter().adaptivePredict(_input,4,_ctx); } @@ -1086,19 +1108,19 @@ public final FieldContext field() throws RecognitionException { try { enterOuterAlt(_localctx, 1); { - setState(262); + setState(272); _errHandler.sync(this); switch ( getInterpreter().adaptivePredict(_input,5,_ctx) ) { case 1: { - setState(259); + setState(269); qualifiedName(); - setState(260); + setState(270); match(ASSIGN); } break; } - setState(264); + setState(274); booleanExpression(0); } } @@ -1152,23 +1174,23 @@ public final RerankFieldsContext rerankFields() throws RecognitionException { int _alt; enterOuterAlt(_localctx, 1); { - setState(266); + setState(276); rerankField(); - setState(271); + setState(281); _errHandler.sync(this); _alt = getInterpreter().adaptivePredict(_input,6,_ctx); while ( _alt!=2 && _alt!=org.antlr.v4.runtime.atn.ATN.INVALID_ALT_NUMBER ) { if ( _alt==1 ) { { { - setState(267); + setState(277); match(COMMA); - setState(268); + setState(278); rerankField(); } } } - setState(273); + setState(283); _errHandler.sync(this); _alt = getInterpreter().adaptivePredict(_input,6,_ctx); } @@ -1220,16 +1242,16 @@ public final RerankFieldContext rerankField() throws RecognitionException { try { enterOuterAlt(_localctx, 1); { - setState(274); + setState(284); qualifiedName(); - setState(277); + setState(287); _errHandler.sync(this); switch ( getInterpreter().adaptivePredict(_input,7,_ctx) ) { case 1: { - setState(275); + setState(285); match(ASSIGN); - setState(276); + setState(286); booleanExpression(0); } break; @@ -1279,9 +1301,9 @@ public final FromCommandContext fromCommand() throws RecognitionException { try { enterOuterAlt(_localctx, 1); { - setState(279); + setState(289); match(FROM); - setState(280); + setState(290); indexPatternAndMetadataFields(); } } @@ -1328,9 +1350,9 @@ public final TimeSeriesCommandContext timeSeriesCommand() throws RecognitionExce try { enterOuterAlt(_localctx, 1); { - setState(282); + setState(292); match(TS); - setState(283); + setState(293); indexPatternAndMetadataFields(); } } @@ -1387,32 +1409,32 @@ public final IndexPatternAndMetadataFieldsContext indexPatternAndMetadataFields( int _alt; enterOuterAlt(_localctx, 1); { - setState(285); + setState(295); indexPatternOrSubquery(); - setState(290); + setState(300); _errHandler.sync(this); _alt = getInterpreter().adaptivePredict(_input,8,_ctx); while ( _alt!=2 && _alt!=org.antlr.v4.runtime.atn.ATN.INVALID_ALT_NUMBER ) { if ( _alt==1 ) { { { - setState(286); + setState(296); match(COMMA); - setState(287); + setState(297); indexPatternOrSubquery(); } } } - setState(292); + setState(302); _errHandler.sync(this); _alt = getInterpreter().adaptivePredict(_input,8,_ctx); } - setState(294); + setState(304); _errHandler.sync(this); switch ( getInterpreter().adaptivePredict(_input,9,_ctx) ) { case 1: { - setState(293); + setState(303); metadata(); } break; @@ -1462,22 +1484,22 @@ public final IndexPatternOrSubqueryContext indexPatternOrSubquery() throws Recog IndexPatternOrSubqueryContext _localctx = new IndexPatternOrSubqueryContext(_ctx, getState()); enterRule(_localctx, 30, RULE_indexPatternOrSubquery); try { - setState(299); + setState(309); _errHandler.sync(this); switch ( getInterpreter().adaptivePredict(_input,10,_ctx) ) { case 1: enterOuterAlt(_localctx, 1); { - setState(296); + setState(306); indexPattern(); } break; case 2: enterOuterAlt(_localctx, 2); { - setState(297); + setState(307); if (!(this.isDevVersion())) throw new FailedPredicateException(this, "this.isDevVersion()"); - setState(298); + setState(308); subquery(); } break; @@ -1538,27 +1560,27 @@ public final SubqueryContext subquery() throws RecognitionException { try { enterOuterAlt(_localctx, 1); { - setState(301); + setState(311); match(LP); - setState(302); + setState(312); fromCommand(); - setState(307); + setState(317); _errHandler.sync(this); _la = _input.LA(1); while (_la==PIPE) { { { - setState(303); + setState(313); match(PIPE); - setState(304); + setState(314); processingCommand(); } } - setState(309); + setState(319); _errHandler.sync(this); _la = _input.LA(1); } - setState(310); + setState(320); match(RP); } } @@ -1613,35 +1635,35 @@ public final IndexPatternContext indexPattern() throws RecognitionException { IndexPatternContext _localctx = new IndexPatternContext(_ctx, getState()); enterRule(_localctx, 34, RULE_indexPattern); try { - setState(321); + setState(331); _errHandler.sync(this); switch ( getInterpreter().adaptivePredict(_input,12,_ctx) ) { case 1: enterOuterAlt(_localctx, 1); { - setState(312); + setState(322); clusterString(); - setState(313); + setState(323); match(COLON); - setState(314); + setState(324); unquotedIndexString(); } break; case 2: enterOuterAlt(_localctx, 2); { - setState(316); + setState(326); unquotedIndexString(); - setState(317); + setState(327); match(CAST_OP); - setState(318); + setState(328); selectorString(); } break; case 3: enterOuterAlt(_localctx, 3); { - setState(320); + setState(330); indexString(); } break; @@ -1687,7 +1709,7 @@ public final ClusterStringContext clusterString() throws RecognitionException { try { enterOuterAlt(_localctx, 1); { - setState(323); + setState(333); match(UNQUOTED_SOURCE); } } @@ -1731,7 +1753,7 @@ public final SelectorStringContext selectorString() throws RecognitionException try { enterOuterAlt(_localctx, 1); { - setState(325); + setState(335); match(UNQUOTED_SOURCE); } } @@ -1775,7 +1797,7 @@ public final UnquotedIndexStringContext unquotedIndexString() throws Recognition try { enterOuterAlt(_localctx, 1); { - setState(327); + setState(337); match(UNQUOTED_SOURCE); } } @@ -1821,7 +1843,7 @@ public final IndexStringContext indexString() throws RecognitionException { try { enterOuterAlt(_localctx, 1); { - setState(329); + setState(339); _la = _input.LA(1); if ( !(_la==QUOTED_STRING || _la==UNQUOTED_SOURCE) ) { _errHandler.recoverInline(this); @@ -1882,25 +1904,25 @@ public final MetadataContext metadata() throws RecognitionException { int _alt; enterOuterAlt(_localctx, 1); { - setState(331); + setState(341); match(METADATA); - setState(332); + setState(342); match(UNQUOTED_SOURCE); - setState(337); + setState(347); _errHandler.sync(this); _alt = getInterpreter().adaptivePredict(_input,13,_ctx); while ( _alt!=2 && _alt!=org.antlr.v4.runtime.atn.ATN.INVALID_ALT_NUMBER ) { if ( _alt==1 ) { { { - setState(333); + setState(343); match(COMMA); - setState(334); + setState(344); match(UNQUOTED_SOURCE); } } } - setState(339); + setState(349); _errHandler.sync(this); _alt = getInterpreter().adaptivePredict(_input,13,_ctx); } @@ -1949,9 +1971,9 @@ public final EvalCommandContext evalCommand() throws RecognitionException { try { enterOuterAlt(_localctx, 1); { - setState(340); + setState(350); match(EVAL); - setState(341); + setState(351); fields(); } } @@ -2004,26 +2026,26 @@ public final StatsCommandContext statsCommand() throws RecognitionException { try { enterOuterAlt(_localctx, 1); { - setState(343); + setState(353); match(STATS); - setState(345); + setState(355); _errHandler.sync(this); switch ( getInterpreter().adaptivePredict(_input,14,_ctx) ) { case 1: { - setState(344); + setState(354); ((StatsCommandContext)_localctx).stats = aggFields(); } break; } - setState(349); + setState(359); _errHandler.sync(this); switch ( getInterpreter().adaptivePredict(_input,15,_ctx) ) { case 1: { - setState(347); + setState(357); match(BY); - setState(348); + setState(358); ((StatsCommandContext)_localctx).grouping = fields(); } break; @@ -2080,23 +2102,23 @@ public final AggFieldsContext aggFields() throws RecognitionException { int _alt; enterOuterAlt(_localctx, 1); { - setState(351); + setState(361); aggField(); - setState(356); + setState(366); _errHandler.sync(this); _alt = getInterpreter().adaptivePredict(_input,16,_ctx); while ( _alt!=2 && _alt!=org.antlr.v4.runtime.atn.ATN.INVALID_ALT_NUMBER ) { if ( _alt==1 ) { { { - setState(352); + setState(362); match(COMMA); - setState(353); + setState(363); aggField(); } } } - setState(358); + setState(368); _errHandler.sync(this); _alt = getInterpreter().adaptivePredict(_input,16,_ctx); } @@ -2148,16 +2170,16 @@ public final AggFieldContext aggField() throws RecognitionException { try { enterOuterAlt(_localctx, 1); { - setState(359); + setState(369); field(); - setState(362); + setState(372); _errHandler.sync(this); switch ( getInterpreter().adaptivePredict(_input,17,_ctx) ) { case 1: { - setState(360); + setState(370); match(WHERE); - setState(361); + setState(371); booleanExpression(0); } break; @@ -2217,42 +2239,42 @@ public final QualifiedNameContext qualifiedName() throws RecognitionException { enterRule(_localctx, 54, RULE_qualifiedName); int _la; try { - setState(376); + setState(386); _errHandler.sync(this); switch ( getInterpreter().adaptivePredict(_input,19,_ctx) ) { case 1: enterOuterAlt(_localctx, 1); { - setState(364); + setState(374); if (!(this.isDevVersion())) throw new FailedPredicateException(this, "this.isDevVersion()"); - setState(365); + setState(375); match(OPENING_BRACKET); - setState(367); + setState(377); _errHandler.sync(this); _la = _input.LA(1); if (_la==UNQUOTED_IDENTIFIER) { { - setState(366); + setState(376); ((QualifiedNameContext)_localctx).qualifier = match(UNQUOTED_IDENTIFIER); } } - setState(369); + setState(379); match(CLOSING_BRACKET); - setState(370); + setState(380); match(DOT); - setState(371); + setState(381); match(OPENING_BRACKET); - setState(372); + setState(382); ((QualifiedNameContext)_localctx).name = fieldName(); - setState(373); + setState(383); match(CLOSING_BRACKET); } break; case 2: enterOuterAlt(_localctx, 2); { - setState(375); + setState(385); ((QualifiedNameContext)_localctx).name = fieldName(); } break; @@ -2308,23 +2330,23 @@ public final FieldNameContext fieldName() throws RecognitionException { int _alt; enterOuterAlt(_localctx, 1); { - setState(378); + setState(388); identifierOrParameter(); - setState(383); + setState(393); _errHandler.sync(this); _alt = getInterpreter().adaptivePredict(_input,20,_ctx); while ( _alt!=2 && _alt!=org.antlr.v4.runtime.atn.ATN.INVALID_ALT_NUMBER ) { if ( _alt==1 ) { { { - setState(379); + setState(389); match(DOT); - setState(380); + setState(390); identifierOrParameter(); } } } - setState(385); + setState(395); _errHandler.sync(this); _alt = getInterpreter().adaptivePredict(_input,20,_ctx); } @@ -2383,42 +2405,42 @@ public final QualifiedNamePatternContext qualifiedNamePattern() throws Recogniti enterRule(_localctx, 58, RULE_qualifiedNamePattern); int _la; try { - setState(398); + setState(408); _errHandler.sync(this); switch ( getInterpreter().adaptivePredict(_input,22,_ctx) ) { case 1: enterOuterAlt(_localctx, 1); { - setState(386); + setState(396); if (!(this.isDevVersion())) throw new FailedPredicateException(this, "this.isDevVersion()"); - setState(387); + setState(397); match(OPENING_BRACKET); - setState(389); + setState(399); _errHandler.sync(this); _la = _input.LA(1); if (_la==ID_PATTERN) { { - setState(388); + setState(398); ((QualifiedNamePatternContext)_localctx).qualifier = match(ID_PATTERN); } } - setState(391); + setState(401); match(CLOSING_BRACKET); - setState(392); + setState(402); match(DOT); - setState(393); + setState(403); match(OPENING_BRACKET); - setState(394); + setState(404); ((QualifiedNamePatternContext)_localctx).name = fieldNamePattern(); - setState(395); + setState(405); match(CLOSING_BRACKET); } break; case 2: enterOuterAlt(_localctx, 2); { - setState(397); + setState(407); ((QualifiedNamePatternContext)_localctx).name = fieldNamePattern(); } break; @@ -2475,23 +2497,23 @@ public final FieldNamePatternContext fieldNamePattern() throws RecognitionExcept enterOuterAlt(_localctx, 1); { { - setState(400); + setState(410); identifierPattern(); - setState(405); + setState(415); _errHandler.sync(this); _alt = getInterpreter().adaptivePredict(_input,23,_ctx); while ( _alt!=2 && _alt!=org.antlr.v4.runtime.atn.ATN.INVALID_ALT_NUMBER ) { if ( _alt==1 ) { { { - setState(401); + setState(411); match(DOT); - setState(402); + setState(412); identifierPattern(); } } } - setState(407); + setState(417); _errHandler.sync(this); _alt = getInterpreter().adaptivePredict(_input,23,_ctx); } @@ -2548,23 +2570,23 @@ public final QualifiedNamePatternsContext qualifiedNamePatterns() throws Recogni int _alt; enterOuterAlt(_localctx, 1); { - setState(408); + setState(418); qualifiedNamePattern(); - setState(413); + setState(423); _errHandler.sync(this); _alt = getInterpreter().adaptivePredict(_input,24,_ctx); while ( _alt!=2 && _alt!=org.antlr.v4.runtime.atn.ATN.INVALID_ALT_NUMBER ) { if ( _alt==1 ) { { { - setState(409); + setState(419); match(COMMA); - setState(410); + setState(420); qualifiedNamePattern(); } } } - setState(415); + setState(425); _errHandler.sync(this); _alt = getInterpreter().adaptivePredict(_input,24,_ctx); } @@ -2612,7 +2634,7 @@ public final IdentifierContext identifier() throws RecognitionException { try { enterOuterAlt(_localctx, 1); { - setState(416); + setState(426); _la = _input.LA(1); if ( !(_la==UNQUOTED_IDENTIFIER || _la==QUOTED_IDENTIFIER) ) { _errHandler.recoverInline(this); @@ -2668,13 +2690,13 @@ public final IdentifierPatternContext identifierPattern() throws RecognitionExce IdentifierPatternContext _localctx = new IdentifierPatternContext(_ctx, getState()); enterRule(_localctx, 66, RULE_identifierPattern); try { - setState(421); + setState(431); _errHandler.sync(this); switch (_input.LA(1)) { case ID_PATTERN: enterOuterAlt(_localctx, 1); { - setState(418); + setState(428); match(ID_PATTERN); } break; @@ -2682,7 +2704,7 @@ public final IdentifierPatternContext identifierPattern() throws RecognitionExce case NAMED_OR_POSITIONAL_PARAM: enterOuterAlt(_localctx, 2); { - setState(419); + setState(429); parameter(); } break; @@ -2690,7 +2712,7 @@ public final IdentifierPatternContext identifierPattern() throws RecognitionExce case NAMED_OR_POSITIONAL_DOUBLE_PARAMS: enterOuterAlt(_localctx, 3); { - setState(420); + setState(430); doubleParameter(); } break; @@ -2766,14 +2788,14 @@ public final ParameterContext parameter() throws RecognitionException { ParameterContext _localctx = new ParameterContext(_ctx, getState()); enterRule(_localctx, 68, RULE_parameter); try { - setState(425); + setState(435); _errHandler.sync(this); switch (_input.LA(1)) { case PARAM: _localctx = new InputParamContext(_localctx); enterOuterAlt(_localctx, 1); { - setState(423); + setState(433); match(PARAM); } break; @@ -2781,7 +2803,7 @@ public final ParameterContext parameter() throws RecognitionException { _localctx = new InputNamedOrPositionalParamContext(_localctx); enterOuterAlt(_localctx, 2); { - setState(424); + setState(434); match(NAMED_OR_POSITIONAL_PARAM); } break; @@ -2857,14 +2879,14 @@ public final DoubleParameterContext doubleParameter() throws RecognitionExceptio DoubleParameterContext _localctx = new DoubleParameterContext(_ctx, getState()); enterRule(_localctx, 70, RULE_doubleParameter); try { - setState(429); + setState(439); _errHandler.sync(this); switch (_input.LA(1)) { case DOUBLE_PARAMS: _localctx = new InputDoubleParamsContext(_localctx); enterOuterAlt(_localctx, 1); { - setState(427); + setState(437); match(DOUBLE_PARAMS); } break; @@ -2872,7 +2894,7 @@ public final DoubleParameterContext doubleParameter() throws RecognitionExceptio _localctx = new InputNamedOrPositionalDoubleParamsContext(_localctx); enterOuterAlt(_localctx, 2); { - setState(428); + setState(438); match(NAMED_OR_POSITIONAL_DOUBLE_PARAMS); } break; @@ -2926,14 +2948,14 @@ public final IdentifierOrParameterContext identifierOrParameter() throws Recogni IdentifierOrParameterContext _localctx = new IdentifierOrParameterContext(_ctx, getState()); enterRule(_localctx, 72, RULE_identifierOrParameter); try { - setState(434); + setState(444); _errHandler.sync(this); switch (_input.LA(1)) { case UNQUOTED_IDENTIFIER: case QUOTED_IDENTIFIER: enterOuterAlt(_localctx, 1); { - setState(431); + setState(441); identifier(); } break; @@ -2941,7 +2963,7 @@ public final IdentifierOrParameterContext identifierOrParameter() throws Recogni case NAMED_OR_POSITIONAL_PARAM: enterOuterAlt(_localctx, 2); { - setState(432); + setState(442); parameter(); } break; @@ -2949,7 +2971,7 @@ public final IdentifierOrParameterContext identifierOrParameter() throws Recogni case NAMED_OR_POSITIONAL_DOUBLE_PARAMS: enterOuterAlt(_localctx, 3); { - setState(433); + setState(443); doubleParameter(); } break; @@ -3000,9 +3022,9 @@ public final LimitCommandContext limitCommand() throws RecognitionException { try { enterOuterAlt(_localctx, 1); { - setState(436); + setState(446); match(LIMIT); - setState(437); + setState(447); constant(); } } @@ -3057,25 +3079,25 @@ public final SortCommandContext sortCommand() throws RecognitionException { int _alt; enterOuterAlt(_localctx, 1); { - setState(439); + setState(449); match(SORT); - setState(440); + setState(450); orderExpression(); - setState(445); + setState(455); _errHandler.sync(this); _alt = getInterpreter().adaptivePredict(_input,29,_ctx); while ( _alt!=2 && _alt!=org.antlr.v4.runtime.atn.ATN.INVALID_ALT_NUMBER ) { if ( _alt==1 ) { { { - setState(441); + setState(451); match(COMMA); - setState(442); + setState(452); orderExpression(); } } } - setState(447); + setState(457); _errHandler.sync(this); _alt = getInterpreter().adaptivePredict(_input,29,_ctx); } @@ -3131,14 +3153,14 @@ public final OrderExpressionContext orderExpression() throws RecognitionExceptio try { enterOuterAlt(_localctx, 1); { - setState(448); + setState(458); booleanExpression(0); - setState(450); + setState(460); _errHandler.sync(this); switch ( getInterpreter().adaptivePredict(_input,30,_ctx) ) { case 1: { - setState(449); + setState(459); ((OrderExpressionContext)_localctx).ordering = _input.LT(1); _la = _input.LA(1); if ( !(_la==ASC || _la==DESC) ) { @@ -3152,14 +3174,14 @@ public final OrderExpressionContext orderExpression() throws RecognitionExceptio } break; } - setState(454); + setState(464); _errHandler.sync(this); switch ( getInterpreter().adaptivePredict(_input,31,_ctx) ) { case 1: { - setState(452); + setState(462); match(NULLS); - setState(453); + setState(463); ((OrderExpressionContext)_localctx).nullOrdering = _input.LT(1); _la = _input.LA(1); if ( !(_la==FIRST || _la==LAST) ) { @@ -3218,9 +3240,9 @@ public final KeepCommandContext keepCommand() throws RecognitionException { try { enterOuterAlt(_localctx, 1); { - setState(456); + setState(466); match(KEEP); - setState(457); + setState(467); qualifiedNamePatterns(); } } @@ -3267,9 +3289,9 @@ public final DropCommandContext dropCommand() throws RecognitionException { try { enterOuterAlt(_localctx, 1); { - setState(459); + setState(469); match(DROP); - setState(460); + setState(470); qualifiedNamePatterns(); } } @@ -3324,25 +3346,25 @@ public final RenameCommandContext renameCommand() throws RecognitionException { int _alt; enterOuterAlt(_localctx, 1); { - setState(462); + setState(472); match(RENAME); - setState(463); + setState(473); renameClause(); - setState(468); + setState(478); _errHandler.sync(this); _alt = getInterpreter().adaptivePredict(_input,32,_ctx); while ( _alt!=2 && _alt!=org.antlr.v4.runtime.atn.ATN.INVALID_ALT_NUMBER ) { if ( _alt==1 ) { { { - setState(464); + setState(474); match(COMMA); - setState(465); + setState(475); renameClause(); } } } - setState(470); + setState(480); _errHandler.sync(this); _alt = getInterpreter().adaptivePredict(_input,32,_ctx); } @@ -3395,28 +3417,28 @@ public final RenameClauseContext renameClause() throws RecognitionException { RenameClauseContext _localctx = new RenameClauseContext(_ctx, getState()); enterRule(_localctx, 86, RULE_renameClause); try { - setState(479); + setState(489); _errHandler.sync(this); switch ( getInterpreter().adaptivePredict(_input,33,_ctx) ) { case 1: enterOuterAlt(_localctx, 1); { - setState(471); + setState(481); ((RenameClauseContext)_localctx).oldName = qualifiedNamePattern(); - setState(472); + setState(482); match(AS); - setState(473); + setState(483); ((RenameClauseContext)_localctx).newName = qualifiedNamePattern(); } break; case 2: enterOuterAlt(_localctx, 2); { - setState(475); + setState(485); ((RenameClauseContext)_localctx).newName = qualifiedNamePattern(); - setState(476); + setState(486); match(ASSIGN); - setState(477); + setState(487); ((RenameClauseContext)_localctx).oldName = qualifiedNamePattern(); } break; @@ -3471,18 +3493,18 @@ public final DissectCommandContext dissectCommand() throws RecognitionException try { enterOuterAlt(_localctx, 1); { - setState(481); + setState(491); match(DISSECT); - setState(482); + setState(492); primaryExpression(0); - setState(483); + setState(493); string(); - setState(485); + setState(495); _errHandler.sync(this); switch ( getInterpreter().adaptivePredict(_input,34,_ctx) ) { case 1: { - setState(484); + setState(494); dissectCommandOptions(); } break; @@ -3539,23 +3561,23 @@ public final DissectCommandOptionsContext dissectCommandOptions() throws Recogni int _alt; enterOuterAlt(_localctx, 1); { - setState(487); + setState(497); dissectCommandOption(); - setState(492); + setState(502); _errHandler.sync(this); _alt = getInterpreter().adaptivePredict(_input,35,_ctx); while ( _alt!=2 && _alt!=org.antlr.v4.runtime.atn.ATN.INVALID_ALT_NUMBER ) { if ( _alt==1 ) { { { - setState(488); + setState(498); match(COMMA); - setState(489); + setState(499); dissectCommandOption(); } } } - setState(494); + setState(504); _errHandler.sync(this); _alt = getInterpreter().adaptivePredict(_input,35,_ctx); } @@ -3607,11 +3629,11 @@ public final DissectCommandOptionContext dissectCommandOption() throws Recogniti try { enterOuterAlt(_localctx, 1); { - setState(495); + setState(505); identifier(); - setState(496); + setState(506); match(ASSIGN); - setState(497); + setState(507); constant(); } } @@ -3658,14 +3680,14 @@ public final CommandNamedParametersContext commandNamedParameters() throws Recog try { enterOuterAlt(_localctx, 1); { - setState(501); + setState(511); _errHandler.sync(this); switch ( getInterpreter().adaptivePredict(_input,36,_ctx) ) { case 1: { - setState(499); + setState(509); match(WITH); - setState(500); + setState(510); mapExpression(); } break; @@ -3726,27 +3748,27 @@ public final GrokCommandContext grokCommand() throws RecognitionException { int _alt; enterOuterAlt(_localctx, 1); { - setState(503); + setState(513); match(GROK); - setState(504); + setState(514); primaryExpression(0); - setState(505); + setState(515); string(); - setState(510); + setState(520); _errHandler.sync(this); _alt = getInterpreter().adaptivePredict(_input,37,_ctx); while ( _alt!=2 && _alt!=org.antlr.v4.runtime.atn.ATN.INVALID_ALT_NUMBER ) { if ( _alt==1 ) { { { - setState(506); + setState(516); match(COMMA); - setState(507); + setState(517); string(); } } } - setState(512); + setState(522); _errHandler.sync(this); _alt = getInterpreter().adaptivePredict(_input,37,_ctx); } @@ -3795,9 +3817,9 @@ public final MvExpandCommandContext mvExpandCommand() throws RecognitionExceptio try { enterOuterAlt(_localctx, 1); { - setState(513); + setState(523); match(MV_EXPAND); - setState(514); + setState(524); qualifiedName(); } } @@ -3844,9 +3866,9 @@ public final ExplainCommandContext explainCommand() throws RecognitionException try { enterOuterAlt(_localctx, 1); { - setState(516); + setState(526); match(DEV_EXPLAIN); - setState(517); + setState(527); subqueryExpression(); } } @@ -3894,11 +3916,11 @@ public final SubqueryExpressionContext subqueryExpression() throws RecognitionEx try { enterOuterAlt(_localctx, 1); { - setState(519); + setState(529); match(LP); - setState(520); + setState(530); query(0); - setState(521); + setState(531); match(RP); } } @@ -3955,9 +3977,9 @@ public final ShowCommandContext showCommand() throws RecognitionException { _localctx = new ShowInfoContext(_localctx); enterOuterAlt(_localctx, 1); { - setState(523); + setState(533); match(SHOW); - setState(524); + setState(534); match(INFO); } } @@ -4022,46 +4044,46 @@ public final EnrichCommandContext enrichCommand() throws RecognitionException { int _alt; enterOuterAlt(_localctx, 1); { - setState(526); + setState(536); match(ENRICH); - setState(527); + setState(537); ((EnrichCommandContext)_localctx).policyName = enrichPolicyName(); - setState(530); + setState(540); _errHandler.sync(this); switch ( getInterpreter().adaptivePredict(_input,38,_ctx) ) { case 1: { - setState(528); + setState(538); match(ON); - setState(529); + setState(539); ((EnrichCommandContext)_localctx).matchField = qualifiedNamePattern(); } break; } - setState(541); + setState(551); _errHandler.sync(this); switch ( getInterpreter().adaptivePredict(_input,40,_ctx) ) { case 1: { - setState(532); + setState(542); match(WITH); - setState(533); + setState(543); enrichWithClause(); - setState(538); + setState(548); _errHandler.sync(this); _alt = getInterpreter().adaptivePredict(_input,39,_ctx); while ( _alt!=2 && _alt!=org.antlr.v4.runtime.atn.ATN.INVALID_ALT_NUMBER ) { if ( _alt==1 ) { { { - setState(534); + setState(544); match(COMMA); - setState(535); + setState(545); enrichWithClause(); } } } - setState(540); + setState(550); _errHandler.sync(this); _alt = getInterpreter().adaptivePredict(_input,39,_ctx); } @@ -4112,7 +4134,7 @@ public final EnrichPolicyNameContext enrichPolicyName() throws RecognitionExcept try { enterOuterAlt(_localctx, 1); { - setState(543); + setState(553); _la = _input.LA(1); if ( !(_la==ENRICH_POLICY_NAME || _la==QUOTED_STRING) ) { _errHandler.recoverInline(this); @@ -4172,19 +4194,19 @@ public final EnrichWithClauseContext enrichWithClause() throws RecognitionExcept try { enterOuterAlt(_localctx, 1); { - setState(548); + setState(558); _errHandler.sync(this); switch ( getInterpreter().adaptivePredict(_input,41,_ctx) ) { case 1: { - setState(545); + setState(555); ((EnrichWithClauseContext)_localctx).newName = qualifiedNamePattern(); - setState(546); + setState(556); match(ASSIGN); } break; } - setState(550); + setState(560); ((EnrichWithClauseContext)_localctx).enrichField = qualifiedNamePattern(); } } @@ -4232,9 +4254,9 @@ public final SampleCommandContext sampleCommand() throws RecognitionException { try { enterOuterAlt(_localctx, 1); { - setState(552); + setState(562); match(SAMPLE); - setState(553); + setState(563); ((SampleCommandContext)_localctx).probability = constant(); } } @@ -4291,34 +4313,34 @@ public final ChangePointCommandContext changePointCommand() throws RecognitionEx try { enterOuterAlt(_localctx, 1); { - setState(555); + setState(565); match(CHANGE_POINT); - setState(556); + setState(566); ((ChangePointCommandContext)_localctx).value = qualifiedName(); - setState(559); + setState(569); _errHandler.sync(this); switch ( getInterpreter().adaptivePredict(_input,42,_ctx) ) { case 1: { - setState(557); + setState(567); match(ON); - setState(558); + setState(568); ((ChangePointCommandContext)_localctx).key = qualifiedName(); } break; } - setState(566); + setState(576); _errHandler.sync(this); switch ( getInterpreter().adaptivePredict(_input,43,_ctx) ) { case 1: { - setState(561); + setState(571); match(AS); - setState(562); + setState(572); ((ChangePointCommandContext)_localctx).targetType = qualifiedName(); - setState(563); + setState(573); match(COMMA); - setState(564); + setState(574); ((ChangePointCommandContext)_localctx).targetPvalue = qualifiedName(); } break; @@ -4368,9 +4390,9 @@ public final ForkCommandContext forkCommand() throws RecognitionException { try { enterOuterAlt(_localctx, 1); { - setState(568); + setState(578); match(FORK); - setState(569); + setState(579); forkSubQueries(); } } @@ -4420,7 +4442,7 @@ public final ForkSubQueriesContext forkSubQueries() throws RecognitionException int _alt; enterOuterAlt(_localctx, 1); { - setState(572); + setState(582); _errHandler.sync(this); _alt = 1; do { @@ -4428,7 +4450,7 @@ public final ForkSubQueriesContext forkSubQueries() throws RecognitionException case 1: { { - setState(571); + setState(581); forkSubQuery(); } } @@ -4436,7 +4458,7 @@ public final ForkSubQueriesContext forkSubQueries() throws RecognitionException default: throw new NoViableAltException(this); } - setState(574); + setState(584); _errHandler.sync(this); _alt = getInterpreter().adaptivePredict(_input,44,_ctx); } while ( _alt!=2 && _alt!=org.antlr.v4.runtime.atn.ATN.INVALID_ALT_NUMBER ); @@ -4486,11 +4508,11 @@ public final ForkSubQueryContext forkSubQuery() throws RecognitionException { try { enterOuterAlt(_localctx, 1); { - setState(576); + setState(586); match(LP); - setState(577); + setState(587); forkSubQueryCommand(0); - setState(578); + setState(588); match(RP); } } @@ -4586,11 +4608,11 @@ private ForkSubQueryCommandContext forkSubQueryCommand(int _p) throws Recognitio _ctx = _localctx; _prevctx = _localctx; - setState(581); + setState(591); forkSubQueryProcessingCommand(); } _ctx.stop = _input.LT(-1); - setState(588); + setState(598); _errHandler.sync(this); _alt = getInterpreter().adaptivePredict(_input,45,_ctx); while ( _alt!=2 && _alt!=org.antlr.v4.runtime.atn.ATN.INVALID_ALT_NUMBER ) { @@ -4601,16 +4623,16 @@ private ForkSubQueryCommandContext forkSubQueryCommand(int _p) throws Recognitio { _localctx = new CompositeForkSubQueryContext(new ForkSubQueryCommandContext(_parentctx, _parentState)); pushNewRecursionContext(_localctx, _startState, RULE_forkSubQueryCommand); - setState(583); + setState(593); if (!(precpred(_ctx, 1))) throw new FailedPredicateException(this, "precpred(_ctx, 1)"); - setState(584); + setState(594); match(PIPE); - setState(585); + setState(595); forkSubQueryProcessingCommand(); } } } - setState(590); + setState(600); _errHandler.sync(this); _alt = getInterpreter().adaptivePredict(_input,45,_ctx); } @@ -4658,7 +4680,7 @@ public final ForkSubQueryProcessingCommandContext forkSubQueryProcessingCommand( try { enterOuterAlt(_localctx, 1); { - setState(591); + setState(601); processingCommand(); } } @@ -4718,27 +4740,27 @@ public final RerankCommandContext rerankCommand() throws RecognitionException { try { enterOuterAlt(_localctx, 1); { - setState(593); + setState(603); match(RERANK); - setState(597); + setState(607); _errHandler.sync(this); switch ( getInterpreter().adaptivePredict(_input,46,_ctx) ) { case 1: { - setState(594); + setState(604); ((RerankCommandContext)_localctx).targetField = qualifiedName(); - setState(595); + setState(605); match(ASSIGN); } break; } - setState(599); + setState(609); ((RerankCommandContext)_localctx).queryText = constant(); - setState(600); + setState(610); match(ON); - setState(601); + setState(611); rerankFields(); - setState(602); + setState(612); commandNamedParameters(); } } @@ -4794,23 +4816,23 @@ public final CompletionCommandContext completionCommand() throws RecognitionExce try { enterOuterAlt(_localctx, 1); { - setState(604); + setState(614); match(COMPLETION); - setState(608); + setState(618); _errHandler.sync(this); switch ( getInterpreter().adaptivePredict(_input,47,_ctx) ) { case 1: { - setState(605); + setState(615); ((CompletionCommandContext)_localctx).targetField = qualifiedName(); - setState(606); + setState(616); match(ASSIGN); } break; } - setState(610); + setState(620); ((CompletionCommandContext)_localctx).prompt = primaryExpression(0); - setState(611); + setState(621); commandNamedParameters(); } } @@ -4863,26 +4885,26 @@ public final InlineStatsCommandContext inlineStatsCommand() throws RecognitionEx InlineStatsCommandContext _localctx = new InlineStatsCommandContext(_ctx, getState()); enterRule(_localctx, 130, RULE_inlineStatsCommand); try { - setState(626); + setState(636); _errHandler.sync(this); switch (_input.LA(1)) { case INLINE: enterOuterAlt(_localctx, 1); { - setState(613); + setState(623); match(INLINE); - setState(614); + setState(624); match(INLINE_STATS); - setState(615); + setState(625); ((InlineStatsCommandContext)_localctx).stats = aggFields(); - setState(618); + setState(628); _errHandler.sync(this); switch ( getInterpreter().adaptivePredict(_input,48,_ctx) ) { case 1: { - setState(616); + setState(626); match(BY); - setState(617); + setState(627); ((InlineStatsCommandContext)_localctx).grouping = fields(); } break; @@ -4892,18 +4914,18 @@ public final InlineStatsCommandContext inlineStatsCommand() throws RecognitionEx case INLINESTATS: enterOuterAlt(_localctx, 2); { - setState(620); + setState(630); match(INLINESTATS); - setState(621); + setState(631); ((InlineStatsCommandContext)_localctx).stats = aggFields(); - setState(624); + setState(634); _errHandler.sync(this); switch ( getInterpreter().adaptivePredict(_input,49,_ctx) ) { case 1: { - setState(622); + setState(632); match(BY); - setState(623); + setState(633); ((InlineStatsCommandContext)_localctx).grouping = fields(); } break; @@ -4965,31 +4987,31 @@ public final FuseCommandContext fuseCommand() throws RecognitionException { int _alt; enterOuterAlt(_localctx, 1); { - setState(628); + setState(638); match(FUSE); - setState(630); + setState(640); _errHandler.sync(this); switch ( getInterpreter().adaptivePredict(_input,51,_ctx) ) { case 1: { - setState(629); + setState(639); ((FuseCommandContext)_localctx).fuseType = identifier(); } break; } - setState(635); + setState(645); _errHandler.sync(this); _alt = getInterpreter().adaptivePredict(_input,52,_ctx); while ( _alt!=2 && _alt!=org.antlr.v4.runtime.atn.ATN.INVALID_ALT_NUMBER ) { if ( _alt==1 ) { { { - setState(632); + setState(642); fuseConfiguration(); } } } - setState(637); + setState(647); _errHandler.sync(this); _alt = getInterpreter().adaptivePredict(_input,52,_ctx); } @@ -5050,48 +5072,48 @@ public final FuseConfigurationContext fuseConfiguration() throws RecognitionExce FuseConfigurationContext _localctx = new FuseConfigurationContext(_ctx, getState()); enterRule(_localctx, 134, RULE_fuseConfiguration); try { - setState(649); + setState(659); _errHandler.sync(this); switch (_input.LA(1)) { case SCORE: enterOuterAlt(_localctx, 1); { - setState(638); + setState(648); match(SCORE); - setState(639); + setState(649); match(BY); - setState(640); + setState(650); ((FuseConfigurationContext)_localctx).score = qualifiedName(); } break; case KEY: enterOuterAlt(_localctx, 2); { - setState(641); + setState(651); match(KEY); - setState(642); + setState(652); match(BY); - setState(643); + setState(653); ((FuseConfigurationContext)_localctx).key = fields(); } break; case GROUP: enterOuterAlt(_localctx, 3); { - setState(644); + setState(654); match(GROUP); - setState(645); + setState(655); match(BY); - setState(646); + setState(656); ((FuseConfigurationContext)_localctx).group = qualifiedName(); } break; case WITH: enterOuterAlt(_localctx, 4); { - setState(647); + setState(657); match(WITH); - setState(648); + setState(658); ((FuseConfigurationContext)_localctx).options = mapExpression(); } break; @@ -5148,13 +5170,13 @@ public final LookupCommandContext lookupCommand() throws RecognitionException { try { enterOuterAlt(_localctx, 1); { - setState(651); + setState(661); match(DEV_LOOKUP); - setState(652); + setState(662); ((LookupCommandContext)_localctx).tableName = indexPattern(); - setState(653); + setState(663); match(ON); - setState(654); + setState(664); ((LookupCommandContext)_localctx).matchFields = qualifiedNamePatterns(); } } @@ -5201,9 +5223,9 @@ public final InsistCommandContext insistCommand() throws RecognitionException { try { enterOuterAlt(_localctx, 1); { - setState(656); + setState(666); match(DEV_INSIST); - setState(657); + setState(667); qualifiedNamePatterns(); } } @@ -5251,11 +5273,11 @@ public final SetCommandContext setCommand() throws RecognitionException { try { enterOuterAlt(_localctx, 1); { - setState(659); + setState(669); match(SET); - setState(660); + setState(670); setField(); - setState(661); + setState(671); match(SEMICOLON); } } @@ -5305,11 +5327,11 @@ public final SetFieldContext setField() throws RecognitionException { try { enterOuterAlt(_localctx, 1); { - setState(663); + setState(673); identifier(); - setState(664); + setState(674); match(ASSIGN); - setState(665); + setState(675); constant(); } } @@ -5525,7 +5547,7 @@ private BooleanExpressionContext booleanExpression(int _p) throws RecognitionExc int _alt; enterOuterAlt(_localctx, 1); { - setState(696); + setState(706); _errHandler.sync(this); switch ( getInterpreter().adaptivePredict(_input,57,_ctx) ) { case 1: @@ -5534,9 +5556,9 @@ private BooleanExpressionContext booleanExpression(int _p) throws RecognitionExc _ctx = _localctx; _prevctx = _localctx; - setState(668); + setState(678); match(NOT); - setState(669); + setState(679); booleanExpression(8); } break; @@ -5545,7 +5567,7 @@ private BooleanExpressionContext booleanExpression(int _p) throws RecognitionExc _localctx = new BooleanDefaultContext(_localctx); _ctx = _localctx; _prevctx = _localctx; - setState(670); + setState(680); valueExpression(); } break; @@ -5554,7 +5576,7 @@ private BooleanExpressionContext booleanExpression(int _p) throws RecognitionExc _localctx = new RegexExpressionContext(_localctx); _ctx = _localctx; _prevctx = _localctx; - setState(671); + setState(681); regexBooleanExpression(); } break; @@ -5563,41 +5585,41 @@ private BooleanExpressionContext booleanExpression(int _p) throws RecognitionExc _localctx = new LogicalInContext(_localctx); _ctx = _localctx; _prevctx = _localctx; - setState(672); + setState(682); valueExpression(); - setState(674); + setState(684); _errHandler.sync(this); _la = _input.LA(1); if (_la==NOT) { { - setState(673); + setState(683); match(NOT); } } - setState(676); + setState(686); match(IN); - setState(677); + setState(687); match(LP); - setState(678); + setState(688); valueExpression(); - setState(683); + setState(693); _errHandler.sync(this); _la = _input.LA(1); while (_la==COMMA) { { { - setState(679); + setState(689); match(COMMA); - setState(680); + setState(690); valueExpression(); } } - setState(685); + setState(695); _errHandler.sync(this); _la = _input.LA(1); } - setState(686); + setState(696); match(RP); } break; @@ -5606,21 +5628,21 @@ private BooleanExpressionContext booleanExpression(int _p) throws RecognitionExc _localctx = new IsNullContext(_localctx); _ctx = _localctx; _prevctx = _localctx; - setState(688); + setState(698); valueExpression(); - setState(689); + setState(699); match(IS); - setState(691); + setState(701); _errHandler.sync(this); _la = _input.LA(1); if (_la==NOT) { { - setState(690); + setState(700); match(NOT); } } - setState(693); + setState(703); match(NULL); } break; @@ -5629,13 +5651,13 @@ private BooleanExpressionContext booleanExpression(int _p) throws RecognitionExc _localctx = new MatchExpressionContext(_localctx); _ctx = _localctx; _prevctx = _localctx; - setState(695); + setState(705); matchBooleanExpression(); } break; } _ctx.stop = _input.LT(-1); - setState(706); + setState(716); _errHandler.sync(this); _alt = getInterpreter().adaptivePredict(_input,59,_ctx); while ( _alt!=2 && _alt!=org.antlr.v4.runtime.atn.ATN.INVALID_ALT_NUMBER ) { @@ -5643,7 +5665,7 @@ private BooleanExpressionContext booleanExpression(int _p) throws RecognitionExc if ( _parseListeners!=null ) triggerExitRuleEvent(); _prevctx = _localctx; { - setState(704); + setState(714); _errHandler.sync(this); switch ( getInterpreter().adaptivePredict(_input,58,_ctx) ) { case 1: @@ -5651,11 +5673,11 @@ private BooleanExpressionContext booleanExpression(int _p) throws RecognitionExc _localctx = new LogicalBinaryContext(new BooleanExpressionContext(_parentctx, _parentState)); ((LogicalBinaryContext)_localctx).left = _prevctx; pushNewRecursionContext(_localctx, _startState, RULE_booleanExpression); - setState(698); + setState(708); if (!(precpred(_ctx, 5))) throw new FailedPredicateException(this, "precpred(_ctx, 5)"); - setState(699); + setState(709); ((LogicalBinaryContext)_localctx).operator = match(AND); - setState(700); + setState(710); ((LogicalBinaryContext)_localctx).right = booleanExpression(6); } break; @@ -5664,18 +5686,18 @@ private BooleanExpressionContext booleanExpression(int _p) throws RecognitionExc _localctx = new LogicalBinaryContext(new BooleanExpressionContext(_parentctx, _parentState)); ((LogicalBinaryContext)_localctx).left = _prevctx; pushNewRecursionContext(_localctx, _startState, RULE_booleanExpression); - setState(701); + setState(711); if (!(precpred(_ctx, 4))) throw new FailedPredicateException(this, "precpred(_ctx, 4)"); - setState(702); + setState(712); ((LogicalBinaryContext)_localctx).operator = match(OR); - setState(703); + setState(713); ((LogicalBinaryContext)_localctx).right = booleanExpression(5); } break; } } } - setState(708); + setState(718); _errHandler.sync(this); _alt = getInterpreter().adaptivePredict(_input,59,_ctx); } @@ -5834,28 +5856,28 @@ public final RegexBooleanExpressionContext regexBooleanExpression() throws Recog enterRule(_localctx, 146, RULE_regexBooleanExpression); int _la; try { - setState(755); + setState(765); _errHandler.sync(this); switch ( getInterpreter().adaptivePredict(_input,66,_ctx) ) { case 1: _localctx = new LikeExpressionContext(_localctx); enterOuterAlt(_localctx, 1); { - setState(709); + setState(719); valueExpression(); - setState(711); + setState(721); _errHandler.sync(this); _la = _input.LA(1); if (_la==NOT) { { - setState(710); + setState(720); match(NOT); } } - setState(713); + setState(723); match(LIKE); - setState(714); + setState(724); string(); } break; @@ -5863,21 +5885,21 @@ public final RegexBooleanExpressionContext regexBooleanExpression() throws Recog _localctx = new RlikeExpressionContext(_localctx); enterOuterAlt(_localctx, 2); { - setState(716); + setState(726); valueExpression(); - setState(718); + setState(728); _errHandler.sync(this); _la = _input.LA(1); if (_la==NOT) { { - setState(717); + setState(727); match(NOT); } } - setState(720); + setState(730); match(RLIKE); - setState(721); + setState(731); string(); } break; @@ -5885,41 +5907,41 @@ public final RegexBooleanExpressionContext regexBooleanExpression() throws Recog _localctx = new LikeListExpressionContext(_localctx); enterOuterAlt(_localctx, 3); { - setState(723); + setState(733); valueExpression(); - setState(725); + setState(735); _errHandler.sync(this); _la = _input.LA(1); if (_la==NOT) { { - setState(724); + setState(734); match(NOT); } } - setState(727); + setState(737); match(LIKE); - setState(728); + setState(738); match(LP); - setState(729); + setState(739); string(); - setState(734); + setState(744); _errHandler.sync(this); _la = _input.LA(1); while (_la==COMMA) { { { - setState(730); + setState(740); match(COMMA); - setState(731); + setState(741); string(); } } - setState(736); + setState(746); _errHandler.sync(this); _la = _input.LA(1); } - setState(737); + setState(747); match(RP); } break; @@ -5927,41 +5949,41 @@ public final RegexBooleanExpressionContext regexBooleanExpression() throws Recog _localctx = new RlikeListExpressionContext(_localctx); enterOuterAlt(_localctx, 4); { - setState(739); + setState(749); valueExpression(); - setState(741); + setState(751); _errHandler.sync(this); _la = _input.LA(1); if (_la==NOT) { { - setState(740); + setState(750); match(NOT); } } - setState(743); + setState(753); match(RLIKE); - setState(744); + setState(754); match(LP); - setState(745); + setState(755); string(); - setState(750); + setState(760); _errHandler.sync(this); _la = _input.LA(1); while (_la==COMMA) { { { - setState(746); + setState(756); match(COMMA); - setState(747); + setState(757); string(); } } - setState(752); + setState(762); _errHandler.sync(this); _la = _input.LA(1); } - setState(753); + setState(763); match(RP); } break; @@ -6021,23 +6043,23 @@ public final MatchBooleanExpressionContext matchBooleanExpression() throws Recog try { enterOuterAlt(_localctx, 1); { - setState(757); + setState(767); ((MatchBooleanExpressionContext)_localctx).fieldExp = qualifiedName(); - setState(760); + setState(770); _errHandler.sync(this); _la = _input.LA(1); if (_la==CAST_OP) { { - setState(758); + setState(768); match(CAST_OP); - setState(759); + setState(769); ((MatchBooleanExpressionContext)_localctx).fieldType = dataType(); } } - setState(762); + setState(772); match(COLON); - setState(763); + setState(773); ((MatchBooleanExpressionContext)_localctx).matchQuery = constant(); } } @@ -6121,14 +6143,14 @@ public final ValueExpressionContext valueExpression() throws RecognitionExceptio ValueExpressionContext _localctx = new ValueExpressionContext(_ctx, getState()); enterRule(_localctx, 150, RULE_valueExpression); try { - setState(770); + setState(780); _errHandler.sync(this); switch ( getInterpreter().adaptivePredict(_input,68,_ctx) ) { case 1: _localctx = new ValueExpressionDefaultContext(_localctx); enterOuterAlt(_localctx, 1); { - setState(765); + setState(775); operatorExpression(0); } break; @@ -6136,11 +6158,11 @@ public final ValueExpressionContext valueExpression() throws RecognitionExceptio _localctx = new ComparisonContext(_localctx); enterOuterAlt(_localctx, 2); { - setState(766); + setState(776); ((ComparisonContext)_localctx).left = operatorExpression(0); - setState(767); + setState(777); comparisonOperator(); - setState(768); + setState(778); ((ComparisonContext)_localctx).right = operatorExpression(0); } break; @@ -6265,7 +6287,7 @@ private OperatorExpressionContext operatorExpression(int _p) throws RecognitionE int _alt; enterOuterAlt(_localctx, 1); { - setState(776); + setState(786); _errHandler.sync(this); switch ( getInterpreter().adaptivePredict(_input,69,_ctx) ) { case 1: @@ -6274,7 +6296,7 @@ private OperatorExpressionContext operatorExpression(int _p) throws RecognitionE _ctx = _localctx; _prevctx = _localctx; - setState(773); + setState(783); primaryExpression(0); } break; @@ -6283,7 +6305,7 @@ private OperatorExpressionContext operatorExpression(int _p) throws RecognitionE _localctx = new ArithmeticUnaryContext(_localctx); _ctx = _localctx; _prevctx = _localctx; - setState(774); + setState(784); ((ArithmeticUnaryContext)_localctx).operator = _input.LT(1); _la = _input.LA(1); if ( !(_la==PLUS || _la==MINUS) ) { @@ -6294,13 +6316,13 @@ private OperatorExpressionContext operatorExpression(int _p) throws RecognitionE _errHandler.reportMatch(this); consume(); } - setState(775); + setState(785); operatorExpression(3); } break; } _ctx.stop = _input.LT(-1); - setState(786); + setState(796); _errHandler.sync(this); _alt = getInterpreter().adaptivePredict(_input,71,_ctx); while ( _alt!=2 && _alt!=org.antlr.v4.runtime.atn.ATN.INVALID_ALT_NUMBER ) { @@ -6308,7 +6330,7 @@ private OperatorExpressionContext operatorExpression(int _p) throws RecognitionE if ( _parseListeners!=null ) triggerExitRuleEvent(); _prevctx = _localctx; { - setState(784); + setState(794); _errHandler.sync(this); switch ( getInterpreter().adaptivePredict(_input,70,_ctx) ) { case 1: @@ -6316,12 +6338,12 @@ private OperatorExpressionContext operatorExpression(int _p) throws RecognitionE _localctx = new ArithmeticBinaryContext(new OperatorExpressionContext(_parentctx, _parentState)); ((ArithmeticBinaryContext)_localctx).left = _prevctx; pushNewRecursionContext(_localctx, _startState, RULE_operatorExpression); - setState(778); + setState(788); if (!(precpred(_ctx, 2))) throw new FailedPredicateException(this, "precpred(_ctx, 2)"); - setState(779); + setState(789); ((ArithmeticBinaryContext)_localctx).operator = _input.LT(1); _la = _input.LA(1); - if ( !(((((_la - 88)) & ~0x3f) == 0 && ((1L << (_la - 88)) & 7L) != 0)) ) { + if ( !(((((_la - 89)) & ~0x3f) == 0 && ((1L << (_la - 89)) & 7L) != 0)) ) { ((ArithmeticBinaryContext)_localctx).operator = (Token)_errHandler.recoverInline(this); } else { @@ -6329,7 +6351,7 @@ private OperatorExpressionContext operatorExpression(int _p) throws RecognitionE _errHandler.reportMatch(this); consume(); } - setState(780); + setState(790); ((ArithmeticBinaryContext)_localctx).right = operatorExpression(3); } break; @@ -6338,9 +6360,9 @@ private OperatorExpressionContext operatorExpression(int _p) throws RecognitionE _localctx = new ArithmeticBinaryContext(new OperatorExpressionContext(_parentctx, _parentState)); ((ArithmeticBinaryContext)_localctx).left = _prevctx; pushNewRecursionContext(_localctx, _startState, RULE_operatorExpression); - setState(781); + setState(791); if (!(precpred(_ctx, 1))) throw new FailedPredicateException(this, "precpred(_ctx, 1)"); - setState(782); + setState(792); ((ArithmeticBinaryContext)_localctx).operator = _input.LT(1); _la = _input.LA(1); if ( !(_la==PLUS || _la==MINUS) ) { @@ -6351,14 +6373,14 @@ private OperatorExpressionContext operatorExpression(int _p) throws RecognitionE _errHandler.reportMatch(this); consume(); } - setState(783); + setState(793); ((ArithmeticBinaryContext)_localctx).right = operatorExpression(2); } break; } } } - setState(788); + setState(798); _errHandler.sync(this); _alt = getInterpreter().adaptivePredict(_input,71,_ctx); } @@ -6516,7 +6538,7 @@ private PrimaryExpressionContext primaryExpression(int _p) throws RecognitionExc int _alt; enterOuterAlt(_localctx, 1); { - setState(797); + setState(807); _errHandler.sync(this); switch ( getInterpreter().adaptivePredict(_input,72,_ctx) ) { case 1: @@ -6525,7 +6547,7 @@ private PrimaryExpressionContext primaryExpression(int _p) throws RecognitionExc _ctx = _localctx; _prevctx = _localctx; - setState(790); + setState(800); constant(); } break; @@ -6534,7 +6556,7 @@ private PrimaryExpressionContext primaryExpression(int _p) throws RecognitionExc _localctx = new DereferenceContext(_localctx); _ctx = _localctx; _prevctx = _localctx; - setState(791); + setState(801); qualifiedName(); } break; @@ -6543,7 +6565,7 @@ private PrimaryExpressionContext primaryExpression(int _p) throws RecognitionExc _localctx = new FunctionContext(_localctx); _ctx = _localctx; _prevctx = _localctx; - setState(792); + setState(802); functionExpression(); } break; @@ -6552,17 +6574,17 @@ private PrimaryExpressionContext primaryExpression(int _p) throws RecognitionExc _localctx = new ParenthesizedExpressionContext(_localctx); _ctx = _localctx; _prevctx = _localctx; - setState(793); + setState(803); match(LP); - setState(794); + setState(804); booleanExpression(0); - setState(795); + setState(805); match(RP); } break; } _ctx.stop = _input.LT(-1); - setState(804); + setState(814); _errHandler.sync(this); _alt = getInterpreter().adaptivePredict(_input,73,_ctx); while ( _alt!=2 && _alt!=org.antlr.v4.runtime.atn.ATN.INVALID_ALT_NUMBER ) { @@ -6573,16 +6595,16 @@ private PrimaryExpressionContext primaryExpression(int _p) throws RecognitionExc { _localctx = new InlineCastContext(new PrimaryExpressionContext(_parentctx, _parentState)); pushNewRecursionContext(_localctx, _startState, RULE_primaryExpression); - setState(799); + setState(809); if (!(precpred(_ctx, 1))) throw new FailedPredicateException(this, "precpred(_ctx, 1)"); - setState(800); + setState(810); match(CAST_OP); - setState(801); + setState(811); dataType(); } } } - setState(806); + setState(816); _errHandler.sync(this); _alt = getInterpreter().adaptivePredict(_input,73,_ctx); } @@ -6648,50 +6670,50 @@ public final FunctionExpressionContext functionExpression() throws RecognitionEx int _alt; enterOuterAlt(_localctx, 1); { - setState(807); + setState(817); functionName(); - setState(808); + setState(818); match(LP); - setState(822); + setState(832); _errHandler.sync(this); switch ( getInterpreter().adaptivePredict(_input,76,_ctx) ) { case 1: { - setState(809); + setState(819); match(ASTERISK); } break; case 2: { { - setState(810); + setState(820); booleanExpression(0); - setState(815); + setState(825); _errHandler.sync(this); _alt = getInterpreter().adaptivePredict(_input,74,_ctx); while ( _alt!=2 && _alt!=org.antlr.v4.runtime.atn.ATN.INVALID_ALT_NUMBER ) { if ( _alt==1 ) { { { - setState(811); + setState(821); match(COMMA); - setState(812); + setState(822); booleanExpression(0); } } } - setState(817); + setState(827); _errHandler.sync(this); _alt = getInterpreter().adaptivePredict(_input,74,_ctx); } - setState(820); + setState(830); _errHandler.sync(this); _la = _input.LA(1); if (_la==COMMA) { { - setState(818); + setState(828); match(COMMA); - setState(819); + setState(829); mapExpression(); } } @@ -6700,7 +6722,7 @@ public final FunctionExpressionContext functionExpression() throws RecognitionEx } break; } - setState(824); + setState(834); match(RP); } } @@ -6746,7 +6768,7 @@ public final FunctionNameContext functionName() throws RecognitionException { FunctionNameContext _localctx = new FunctionNameContext(_ctx, getState()); enterRule(_localctx, 158, RULE_functionName); try { - setState(829); + setState(839); _errHandler.sync(this); switch (_input.LA(1)) { case PARAM: @@ -6757,21 +6779,21 @@ public final FunctionNameContext functionName() throws RecognitionException { case QUOTED_IDENTIFIER: enterOuterAlt(_localctx, 1); { - setState(826); + setState(836); identifierOrParameter(); } break; case FIRST: enterOuterAlt(_localctx, 2); { - setState(827); + setState(837); match(FIRST); } break; case LAST: enterOuterAlt(_localctx, 3); { - setState(828); + setState(838); match(LAST); } break; @@ -6831,35 +6853,35 @@ public final MapExpressionContext mapExpression() throws RecognitionException { try { enterOuterAlt(_localctx, 1); { - setState(831); + setState(841); match(LEFT_BRACES); - setState(840); + setState(850); _errHandler.sync(this); _la = _input.LA(1); if (_la==QUOTED_STRING) { { - setState(832); + setState(842); entryExpression(); - setState(837); + setState(847); _errHandler.sync(this); _la = _input.LA(1); while (_la==COMMA) { { { - setState(833); + setState(843); match(COMMA); - setState(834); + setState(844); entryExpression(); } } - setState(839); + setState(849); _errHandler.sync(this); _la = _input.LA(1); } } } - setState(842); + setState(852); match(RIGHT_BRACES); } } @@ -6911,11 +6933,11 @@ public final EntryExpressionContext entryExpression() throws RecognitionExceptio try { enterOuterAlt(_localctx, 1); { - setState(844); + setState(854); ((EntryExpressionContext)_localctx).key = string(); - setState(845); + setState(855); match(COLON); - setState(846); + setState(856); ((EntryExpressionContext)_localctx).value = mapValue(); } } @@ -6962,7 +6984,7 @@ public final MapValueContext mapValue() throws RecognitionException { MapValueContext _localctx = new MapValueContext(_ctx, getState()); enterRule(_localctx, 164, RULE_mapValue); try { - setState(850); + setState(860); _errHandler.sync(this); switch (_input.LA(1)) { case QUOTED_STRING: @@ -6978,14 +7000,14 @@ public final MapValueContext mapValue() throws RecognitionException { case OPENING_BRACKET: enterOuterAlt(_localctx, 1); { - setState(848); + setState(858); constant(); } break; case LEFT_BRACES: enterOuterAlt(_localctx, 2); { - setState(849); + setState(859); mapExpression(); } break; @@ -7260,14 +7282,14 @@ public final ConstantContext constant() throws RecognitionException { enterRule(_localctx, 166, RULE_constant); int _la; try { - setState(894); + setState(904); _errHandler.sync(this); switch ( getInterpreter().adaptivePredict(_input,84,_ctx) ) { case 1: _localctx = new NullLiteralContext(_localctx); enterOuterAlt(_localctx, 1); { - setState(852); + setState(862); match(NULL); } break; @@ -7275,9 +7297,9 @@ public final ConstantContext constant() throws RecognitionException { _localctx = new QualifiedIntegerLiteralContext(_localctx); enterOuterAlt(_localctx, 2); { - setState(853); + setState(863); integerValue(); - setState(854); + setState(864); match(UNQUOTED_IDENTIFIER); } break; @@ -7285,7 +7307,7 @@ public final ConstantContext constant() throws RecognitionException { _localctx = new DecimalLiteralContext(_localctx); enterOuterAlt(_localctx, 3); { - setState(856); + setState(866); decimalValue(); } break; @@ -7293,7 +7315,7 @@ public final ConstantContext constant() throws RecognitionException { _localctx = new IntegerLiteralContext(_localctx); enterOuterAlt(_localctx, 4); { - setState(857); + setState(867); integerValue(); } break; @@ -7301,7 +7323,7 @@ public final ConstantContext constant() throws RecognitionException { _localctx = new BooleanLiteralContext(_localctx); enterOuterAlt(_localctx, 5); { - setState(858); + setState(868); booleanValue(); } break; @@ -7309,7 +7331,7 @@ public final ConstantContext constant() throws RecognitionException { _localctx = new InputParameterContext(_localctx); enterOuterAlt(_localctx, 6); { - setState(859); + setState(869); parameter(); } break; @@ -7317,7 +7339,7 @@ public final ConstantContext constant() throws RecognitionException { _localctx = new StringLiteralContext(_localctx); enterOuterAlt(_localctx, 7); { - setState(860); + setState(870); string(); } break; @@ -7325,27 +7347,27 @@ public final ConstantContext constant() throws RecognitionException { _localctx = new NumericArrayLiteralContext(_localctx); enterOuterAlt(_localctx, 8); { - setState(861); + setState(871); match(OPENING_BRACKET); - setState(862); + setState(872); numericValue(); - setState(867); + setState(877); _errHandler.sync(this); _la = _input.LA(1); while (_la==COMMA) { { { - setState(863); + setState(873); match(COMMA); - setState(864); + setState(874); numericValue(); } } - setState(869); + setState(879); _errHandler.sync(this); _la = _input.LA(1); } - setState(870); + setState(880); match(CLOSING_BRACKET); } break; @@ -7353,27 +7375,27 @@ public final ConstantContext constant() throws RecognitionException { _localctx = new BooleanArrayLiteralContext(_localctx); enterOuterAlt(_localctx, 9); { - setState(872); + setState(882); match(OPENING_BRACKET); - setState(873); + setState(883); booleanValue(); - setState(878); + setState(888); _errHandler.sync(this); _la = _input.LA(1); while (_la==COMMA) { { { - setState(874); + setState(884); match(COMMA); - setState(875); + setState(885); booleanValue(); } } - setState(880); + setState(890); _errHandler.sync(this); _la = _input.LA(1); } - setState(881); + setState(891); match(CLOSING_BRACKET); } break; @@ -7381,27 +7403,27 @@ public final ConstantContext constant() throws RecognitionException { _localctx = new StringArrayLiteralContext(_localctx); enterOuterAlt(_localctx, 10); { - setState(883); + setState(893); match(OPENING_BRACKET); - setState(884); + setState(894); string(); - setState(889); + setState(899); _errHandler.sync(this); _la = _input.LA(1); while (_la==COMMA) { { { - setState(885); + setState(895); match(COMMA); - setState(886); + setState(896); string(); } } - setState(891); + setState(901); _errHandler.sync(this); _la = _input.LA(1); } - setState(892); + setState(902); match(CLOSING_BRACKET); } break; @@ -7449,7 +7471,7 @@ public final BooleanValueContext booleanValue() throws RecognitionException { try { enterOuterAlt(_localctx, 1); { - setState(896); + setState(906); _la = _input.LA(1); if ( !(_la==FALSE || _la==TRUE) ) { _errHandler.recoverInline(this); @@ -7504,20 +7526,20 @@ public final NumericValueContext numericValue() throws RecognitionException { NumericValueContext _localctx = new NumericValueContext(_ctx, getState()); enterRule(_localctx, 170, RULE_numericValue); try { - setState(900); + setState(910); _errHandler.sync(this); switch ( getInterpreter().adaptivePredict(_input,85,_ctx) ) { case 1: enterOuterAlt(_localctx, 1); { - setState(898); + setState(908); decimalValue(); } break; case 2: enterOuterAlt(_localctx, 2); { - setState(899); + setState(909); integerValue(); } break; @@ -7566,12 +7588,12 @@ public final DecimalValueContext decimalValue() throws RecognitionException { try { enterOuterAlt(_localctx, 1); { - setState(903); + setState(913); _errHandler.sync(this); _la = _input.LA(1); if (_la==PLUS || _la==MINUS) { { - setState(902); + setState(912); _la = _input.LA(1); if ( !(_la==PLUS || _la==MINUS) ) { _errHandler.recoverInline(this); @@ -7584,7 +7606,7 @@ public final DecimalValueContext decimalValue() throws RecognitionException { } } - setState(905); + setState(915); match(DECIMAL_LITERAL); } } @@ -7631,12 +7653,12 @@ public final IntegerValueContext integerValue() throws RecognitionException { try { enterOuterAlt(_localctx, 1); { - setState(908); + setState(918); _errHandler.sync(this); _la = _input.LA(1); if (_la==PLUS || _la==MINUS) { { - setState(907); + setState(917); _la = _input.LA(1); if ( !(_la==PLUS || _la==MINUS) ) { _errHandler.recoverInline(this); @@ -7649,7 +7671,7 @@ public final IntegerValueContext integerValue() throws RecognitionException { } } - setState(910); + setState(920); match(INTEGER_LITERAL); } } @@ -7693,7 +7715,7 @@ public final StringContext string() throws RecognitionException { try { enterOuterAlt(_localctx, 1); { - setState(912); + setState(922); match(QUOTED_STRING); } } @@ -7743,9 +7765,9 @@ public final ComparisonOperatorContext comparisonOperator() throws RecognitionEx try { enterOuterAlt(_localctx, 1); { - setState(914); + setState(924); _la = _input.LA(1); - if ( !(((((_la - 79)) & ~0x3f) == 0 && ((1L << (_la - 79)) & 125L) != 0)) ) { + if ( !(((((_la - 80)) & ~0x3f) == 0 && ((1L << (_la - 80)) & 125L) != 0)) ) { _errHandler.recoverInline(this); } else { @@ -7806,7 +7828,7 @@ public final JoinCommandContext joinCommand() throws RecognitionException { try { enterOuterAlt(_localctx, 1); { - setState(916); + setState(926); ((JoinCommandContext)_localctx).type = _input.LT(1); _la = _input.LA(1); if ( !((((_la) & ~0x3f) == 0 && ((1L << _la) & 218103808L) != 0)) ) { @@ -7817,11 +7839,11 @@ public final JoinCommandContext joinCommand() throws RecognitionException { _errHandler.reportMatch(this); consume(); } - setState(917); + setState(927); match(JOIN); - setState(918); + setState(928); joinTarget(); - setState(919); + setState(929); joinCondition(); } } @@ -7870,34 +7892,34 @@ public final JoinTargetContext joinTarget() throws RecognitionException { enterRule(_localctx, 182, RULE_joinTarget); int _la; try { - setState(929); + setState(939); _errHandler.sync(this); switch ( getInterpreter().adaptivePredict(_input,89,_ctx) ) { case 1: enterOuterAlt(_localctx, 1); { - setState(921); + setState(931); if (!(this.isDevVersion())) throw new FailedPredicateException(this, "this.isDevVersion()"); - setState(922); + setState(932); ((JoinTargetContext)_localctx).index = indexPattern(); - setState(924); + setState(934); _errHandler.sync(this); _la = _input.LA(1); if (_la==AS) { { - setState(923); + setState(933); match(AS); } } - setState(926); + setState(936); ((JoinTargetContext)_localctx).qualifier = match(UNQUOTED_SOURCE); } break; case 2: enterOuterAlt(_localctx, 2); { - setState(928); + setState(938); ((JoinTargetContext)_localctx).index = indexPattern(); } break; @@ -7954,25 +7976,25 @@ public final JoinConditionContext joinCondition() throws RecognitionException { int _alt; enterOuterAlt(_localctx, 1); { - setState(931); + setState(941); match(ON); - setState(932); + setState(942); booleanExpression(0); - setState(937); + setState(947); _errHandler.sync(this); _alt = getInterpreter().adaptivePredict(_input,90,_ctx); while ( _alt!=2 && _alt!=org.antlr.v4.runtime.atn.ATN.INVALID_ALT_NUMBER ) { if ( _alt==1 ) { { { - setState(933); + setState(943); match(COMMA); - setState(934); + setState(944); booleanExpression(0); } } } - setState(939); + setState(949); _errHandler.sync(this); _alt = getInterpreter().adaptivePredict(_input,90,_ctx); } @@ -7989,6 +8011,290 @@ public final JoinConditionContext joinCondition() throws RecognitionException { return _localctx; } + @SuppressWarnings("CheckReturnValue") + public static class PromqlCommandContext extends ParserRuleContext { + public TerminalNode DEV_PROMQL() { return getToken(EsqlBaseParser.DEV_PROMQL, 0); } + public TerminalNode LP() { return getToken(EsqlBaseParser.LP, 0); } + public TerminalNode RP() { return getToken(EsqlBaseParser.RP, 0); } + public List promqlParam() { + return getRuleContexts(PromqlParamContext.class); + } + public PromqlParamContext promqlParam(int i) { + return getRuleContext(PromqlParamContext.class,i); + } + public List promqlQueryPart() { + return getRuleContexts(PromqlQueryPartContext.class); + } + public PromqlQueryPartContext promqlQueryPart(int i) { + return getRuleContext(PromqlQueryPartContext.class,i); + } + @SuppressWarnings("this-escape") + public PromqlCommandContext(ParserRuleContext parent, int invokingState) { + super(parent, invokingState); + } + @Override public int getRuleIndex() { return RULE_promqlCommand; } + @Override + public void enterRule(ParseTreeListener listener) { + if ( listener instanceof EsqlBaseParserListener ) ((EsqlBaseParserListener)listener).enterPromqlCommand(this); + } + @Override + public void exitRule(ParseTreeListener listener) { + if ( listener instanceof EsqlBaseParserListener ) ((EsqlBaseParserListener)listener).exitPromqlCommand(this); + } + @Override + public T accept(ParseTreeVisitor visitor) { + if ( visitor instanceof EsqlBaseParserVisitor ) return ((EsqlBaseParserVisitor)visitor).visitPromqlCommand(this); + else return visitor.visitChildren(this); + } + } + + public final PromqlCommandContext promqlCommand() throws RecognitionException { + PromqlCommandContext _localctx = new PromqlCommandContext(_ctx, getState()); + enterRule(_localctx, 186, RULE_promqlCommand); + int _la; + try { + enterOuterAlt(_localctx, 1); + { + setState(950); + match(DEV_PROMQL); + setState(952); + _errHandler.sync(this); + _la = _input.LA(1); + do { + { + { + setState(951); + promqlParam(); + } + } + setState(954); + _errHandler.sync(this); + _la = _input.LA(1); + } while ( _la==QUOTED_STRING || ((((_la - 95)) & ~0x3f) == 0 && ((1L << (_la - 95)) & 140737488355457L) != 0) ); + setState(956); + match(LP); + setState(960); + _errHandler.sync(this); + _la = _input.LA(1); + while (_la==LP || _la==PROMQL_QUERY_TEXT) { + { + { + setState(957); + promqlQueryPart(); + } + } + setState(962); + _errHandler.sync(this); + _la = _input.LA(1); + } + setState(963); + match(RP); + } + } + catch (RecognitionException re) { + _localctx.exception = re; + _errHandler.reportError(this, re); + _errHandler.recover(this, re); + } + finally { + exitRule(); + } + return _localctx; + } + + @SuppressWarnings("CheckReturnValue") + public static class PromqlParamContext extends ParserRuleContext { + public PromqlParamContentContext name; + public PromqlParamContentContext value; + public List promqlParamContent() { + return getRuleContexts(PromqlParamContentContext.class); + } + public PromqlParamContentContext promqlParamContent(int i) { + return getRuleContext(PromqlParamContentContext.class,i); + } + @SuppressWarnings("this-escape") + public PromqlParamContext(ParserRuleContext parent, int invokingState) { + super(parent, invokingState); + } + @Override public int getRuleIndex() { return RULE_promqlParam; } + @Override + public void enterRule(ParseTreeListener listener) { + if ( listener instanceof EsqlBaseParserListener ) ((EsqlBaseParserListener)listener).enterPromqlParam(this); + } + @Override + public void exitRule(ParseTreeListener listener) { + if ( listener instanceof EsqlBaseParserListener ) ((EsqlBaseParserListener)listener).exitPromqlParam(this); + } + @Override + public T accept(ParseTreeVisitor visitor) { + if ( visitor instanceof EsqlBaseParserVisitor ) return ((EsqlBaseParserVisitor)visitor).visitPromqlParam(this); + else return visitor.visitChildren(this); + } + } + + public final PromqlParamContext promqlParam() throws RecognitionException { + PromqlParamContext _localctx = new PromqlParamContext(_ctx, getState()); + enterRule(_localctx, 188, RULE_promqlParam); + try { + enterOuterAlt(_localctx, 1); + { + setState(965); + ((PromqlParamContext)_localctx).name = promqlParamContent(); + setState(966); + ((PromqlParamContext)_localctx).value = promqlParamContent(); + } + } + catch (RecognitionException re) { + _localctx.exception = re; + _errHandler.reportError(this, re); + _errHandler.recover(this, re); + } + finally { + exitRule(); + } + return _localctx; + } + + @SuppressWarnings("CheckReturnValue") + public static class PromqlParamContentContext extends ParserRuleContext { + public TerminalNode PROMQL_UNQUOTED_IDENTIFIER() { return getToken(EsqlBaseParser.PROMQL_UNQUOTED_IDENTIFIER, 0); } + public TerminalNode QUOTED_IDENTIFIER() { return getToken(EsqlBaseParser.QUOTED_IDENTIFIER, 0); } + public TerminalNode QUOTED_STRING() { return getToken(EsqlBaseParser.QUOTED_STRING, 0); } + public TerminalNode NAMED_OR_POSITIONAL_PARAM() { return getToken(EsqlBaseParser.NAMED_OR_POSITIONAL_PARAM, 0); } + @SuppressWarnings("this-escape") + public PromqlParamContentContext(ParserRuleContext parent, int invokingState) { + super(parent, invokingState); + } + @Override public int getRuleIndex() { return RULE_promqlParamContent; } + @Override + public void enterRule(ParseTreeListener listener) { + if ( listener instanceof EsqlBaseParserListener ) ((EsqlBaseParserListener)listener).enterPromqlParamContent(this); + } + @Override + public void exitRule(ParseTreeListener listener) { + if ( listener instanceof EsqlBaseParserListener ) ((EsqlBaseParserListener)listener).exitPromqlParamContent(this); + } + @Override + public T accept(ParseTreeVisitor visitor) { + if ( visitor instanceof EsqlBaseParserVisitor ) return ((EsqlBaseParserVisitor)visitor).visitPromqlParamContent(this); + else return visitor.visitChildren(this); + } + } + + public final PromqlParamContentContext promqlParamContent() throws RecognitionException { + PromqlParamContentContext _localctx = new PromqlParamContentContext(_ctx, getState()); + enterRule(_localctx, 190, RULE_promqlParamContent); + int _la; + try { + enterOuterAlt(_localctx, 1); + { + setState(968); + _la = _input.LA(1); + if ( !(_la==QUOTED_STRING || ((((_la - 95)) & ~0x3f) == 0 && ((1L << (_la - 95)) & 140737488355457L) != 0)) ) { + _errHandler.recoverInline(this); + } + else { + if ( _input.LA(1)==Token.EOF ) matchedEOF = true; + _errHandler.reportMatch(this); + consume(); + } + } + } + catch (RecognitionException re) { + _localctx.exception = re; + _errHandler.reportError(this, re); + _errHandler.recover(this, re); + } + finally { + exitRule(); + } + return _localctx; + } + + @SuppressWarnings("CheckReturnValue") + public static class PromqlQueryPartContext extends ParserRuleContext { + public TerminalNode PROMQL_QUERY_TEXT() { return getToken(EsqlBaseParser.PROMQL_QUERY_TEXT, 0); } + public TerminalNode LP() { return getToken(EsqlBaseParser.LP, 0); } + public TerminalNode RP() { return getToken(EsqlBaseParser.RP, 0); } + public List promqlQueryPart() { + return getRuleContexts(PromqlQueryPartContext.class); + } + public PromqlQueryPartContext promqlQueryPart(int i) { + return getRuleContext(PromqlQueryPartContext.class,i); + } + @SuppressWarnings("this-escape") + public PromqlQueryPartContext(ParserRuleContext parent, int invokingState) { + super(parent, invokingState); + } + @Override public int getRuleIndex() { return RULE_promqlQueryPart; } + @Override + public void enterRule(ParseTreeListener listener) { + if ( listener instanceof EsqlBaseParserListener ) ((EsqlBaseParserListener)listener).enterPromqlQueryPart(this); + } + @Override + public void exitRule(ParseTreeListener listener) { + if ( listener instanceof EsqlBaseParserListener ) ((EsqlBaseParserListener)listener).exitPromqlQueryPart(this); + } + @Override + public T accept(ParseTreeVisitor visitor) { + if ( visitor instanceof EsqlBaseParserVisitor ) return ((EsqlBaseParserVisitor)visitor).visitPromqlQueryPart(this); + else return visitor.visitChildren(this); + } + } + + public final PromqlQueryPartContext promqlQueryPart() throws RecognitionException { + PromqlQueryPartContext _localctx = new PromqlQueryPartContext(_ctx, getState()); + enterRule(_localctx, 192, RULE_promqlQueryPart); + int _la; + try { + setState(979); + _errHandler.sync(this); + switch (_input.LA(1)) { + case PROMQL_QUERY_TEXT: + enterOuterAlt(_localctx, 1); + { + setState(970); + match(PROMQL_QUERY_TEXT); + } + break; + case LP: + enterOuterAlt(_localctx, 2); + { + setState(971); + match(LP); + setState(975); + _errHandler.sync(this); + _la = _input.LA(1); + while (_la==LP || _la==PROMQL_QUERY_TEXT) { + { + { + setState(972); + promqlQueryPart(); + } + } + setState(977); + _errHandler.sync(this); + _la = _input.LA(1); + } + setState(978); + match(RP); + } + break; + default: + throw new NoViableAltException(this); + } + } + 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 2: @@ -8036,72 +8342,74 @@ private boolean processingCommand_sempred(ProcessingCommandContext _localctx, in return this.isDevVersion(); case 3: return this.isDevVersion(); + case 4: + return this.isDevVersion(); } return true; } private boolean indexPatternOrSubquery_sempred(IndexPatternOrSubqueryContext _localctx, int predIndex) { switch (predIndex) { - case 4: + case 5: return this.isDevVersion(); } return true; } private boolean qualifiedName_sempred(QualifiedNameContext _localctx, int predIndex) { switch (predIndex) { - case 5: + case 6: return this.isDevVersion(); } return true; } private boolean qualifiedNamePattern_sempred(QualifiedNamePatternContext _localctx, int predIndex) { switch (predIndex) { - case 6: + case 7: return this.isDevVersion(); } return true; } private boolean forkSubQueryCommand_sempred(ForkSubQueryCommandContext _localctx, int predIndex) { switch (predIndex) { - case 7: + case 8: return precpred(_ctx, 1); } return true; } private boolean booleanExpression_sempred(BooleanExpressionContext _localctx, int predIndex) { switch (predIndex) { - case 8: - return precpred(_ctx, 5); case 9: + return precpred(_ctx, 5); + case 10: return precpred(_ctx, 4); } return true; } private boolean operatorExpression_sempred(OperatorExpressionContext _localctx, int predIndex) { switch (predIndex) { - case 10: - return precpred(_ctx, 2); case 11: + return precpred(_ctx, 2); + case 12: return precpred(_ctx, 1); } return true; } private boolean primaryExpression_sempred(PrimaryExpressionContext _localctx, int predIndex) { switch (predIndex) { - case 12: + case 13: return precpred(_ctx, 1); } return true; } private boolean joinTarget_sempred(JoinTargetContext _localctx, int predIndex) { switch (predIndex) { - case 13: + case 14: return this.isDevVersion(); } return true; } public static final String _serializedATN = - "\u0004\u0001\u0097\u03ad\u0002\u0000\u0007\u0000\u0002\u0001\u0007\u0001"+ + "\u0004\u0001\u00a0\u03d6\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"+ @@ -8123,567 +8431,592 @@ private boolean joinTarget_sempred(JoinTargetContext _localctx, int predIndex) { "J\u0002K\u0007K\u0002L\u0007L\u0002M\u0007M\u0002N\u0007N\u0002O\u0007"+ "O\u0002P\u0007P\u0002Q\u0007Q\u0002R\u0007R\u0002S\u0007S\u0002T\u0007"+ "T\u0002U\u0007U\u0002V\u0007V\u0002W\u0007W\u0002X\u0007X\u0002Y\u0007"+ - "Y\u0002Z\u0007Z\u0002[\u0007[\u0002\\\u0007\\\u0001\u0000\u0005\u0000"+ - "\u00bc\b\u0000\n\u0000\f\u0000\u00bf\t\u0000\u0001\u0000\u0001\u0000\u0001"+ - "\u0000\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0002\u0001\u0002\u0001"+ - "\u0002\u0001\u0002\u0001\u0002\u0001\u0002\u0005\u0002\u00cd\b\u0002\n"+ - "\u0002\f\u0002\u00d0\t\u0002\u0001\u0003\u0001\u0003\u0001\u0003\u0001"+ - "\u0003\u0001\u0003\u0001\u0003\u0003\u0003\u00d8\b\u0003\u0001\u0004\u0001"+ - "\u0004\u0001\u0004\u0001\u0004\u0001\u0004\u0001\u0004\u0001\u0004\u0001"+ - "\u0004\u0001\u0004\u0001\u0004\u0001\u0004\u0001\u0004\u0001\u0004\u0001"+ - "\u0004\u0001\u0004\u0001\u0004\u0001\u0004\u0001\u0004\u0001\u0004\u0001"+ - "\u0004\u0001\u0004\u0001\u0004\u0001\u0004\u0001\u0004\u0003\u0004\u00f2"+ - "\b\u0004\u0001\u0005\u0001\u0005\u0001\u0005\u0001\u0006\u0001\u0006\u0001"+ - "\u0007\u0001\u0007\u0001\u0007\u0001\b\u0001\b\u0001\b\u0005\b\u00ff\b"+ - "\b\n\b\f\b\u0102\t\b\u0001\t\u0001\t\u0001\t\u0003\t\u0107\b\t\u0001\t"+ - "\u0001\t\u0001\n\u0001\n\u0001\n\u0005\n\u010e\b\n\n\n\f\n\u0111\t\n\u0001"+ - "\u000b\u0001\u000b\u0001\u000b\u0003\u000b\u0116\b\u000b\u0001\f\u0001"+ - "\f\u0001\f\u0001\r\u0001\r\u0001\r\u0001\u000e\u0001\u000e\u0001\u000e"+ - "\u0005\u000e\u0121\b\u000e\n\u000e\f\u000e\u0124\t\u000e\u0001\u000e\u0003"+ - "\u000e\u0127\b\u000e\u0001\u000f\u0001\u000f\u0001\u000f\u0003\u000f\u012c"+ - "\b\u000f\u0001\u0010\u0001\u0010\u0001\u0010\u0001\u0010\u0005\u0010\u0132"+ - "\b\u0010\n\u0010\f\u0010\u0135\t\u0010\u0001\u0010\u0001\u0010\u0001\u0011"+ - "\u0001\u0011\u0001\u0011\u0001\u0011\u0001\u0011\u0001\u0011\u0001\u0011"+ - "\u0001\u0011\u0001\u0011\u0003\u0011\u0142\b\u0011\u0001\u0012\u0001\u0012"+ - "\u0001\u0013\u0001\u0013\u0001\u0014\u0001\u0014\u0001\u0015\u0001\u0015"+ - "\u0001\u0016\u0001\u0016\u0001\u0016\u0001\u0016\u0005\u0016\u0150\b\u0016"+ - "\n\u0016\f\u0016\u0153\t\u0016\u0001\u0017\u0001\u0017\u0001\u0017\u0001"+ - "\u0018\u0001\u0018\u0003\u0018\u015a\b\u0018\u0001\u0018\u0001\u0018\u0003"+ - "\u0018\u015e\b\u0018\u0001\u0019\u0001\u0019\u0001\u0019\u0005\u0019\u0163"+ - "\b\u0019\n\u0019\f\u0019\u0166\t\u0019\u0001\u001a\u0001\u001a\u0001\u001a"+ - "\u0003\u001a\u016b\b\u001a\u0001\u001b\u0001\u001b\u0001\u001b\u0003\u001b"+ - "\u0170\b\u001b\u0001\u001b\u0001\u001b\u0001\u001b\u0001\u001b\u0001\u001b"+ - "\u0001\u001b\u0001\u001b\u0003\u001b\u0179\b\u001b\u0001\u001c\u0001\u001c"+ - "\u0001\u001c\u0005\u001c\u017e\b\u001c\n\u001c\f\u001c\u0181\t\u001c\u0001"+ - "\u001d\u0001\u001d\u0001\u001d\u0003\u001d\u0186\b\u001d\u0001\u001d\u0001"+ - "\u001d\u0001\u001d\u0001\u001d\u0001\u001d\u0001\u001d\u0001\u001d\u0003"+ - "\u001d\u018f\b\u001d\u0001\u001e\u0001\u001e\u0001\u001e\u0005\u001e\u0194"+ - "\b\u001e\n\u001e\f\u001e\u0197\t\u001e\u0001\u001f\u0001\u001f\u0001\u001f"+ - "\u0005\u001f\u019c\b\u001f\n\u001f\f\u001f\u019f\t\u001f\u0001 \u0001"+ - " \u0001!\u0001!\u0001!\u0003!\u01a6\b!\u0001\"\u0001\"\u0003\"\u01aa\b"+ - "\"\u0001#\u0001#\u0003#\u01ae\b#\u0001$\u0001$\u0001$\u0003$\u01b3\b$"+ - "\u0001%\u0001%\u0001%\u0001&\u0001&\u0001&\u0001&\u0005&\u01bc\b&\n&\f"+ - "&\u01bf\t&\u0001\'\u0001\'\u0003\'\u01c3\b\'\u0001\'\u0001\'\u0003\'\u01c7"+ - "\b\'\u0001(\u0001(\u0001(\u0001)\u0001)\u0001)\u0001*\u0001*\u0001*\u0001"+ - "*\u0005*\u01d3\b*\n*\f*\u01d6\t*\u0001+\u0001+\u0001+\u0001+\u0001+\u0001"+ - "+\u0001+\u0001+\u0003+\u01e0\b+\u0001,\u0001,\u0001,\u0001,\u0003,\u01e6"+ - "\b,\u0001-\u0001-\u0001-\u0005-\u01eb\b-\n-\f-\u01ee\t-\u0001.\u0001."+ - "\u0001.\u0001.\u0001/\u0001/\u0003/\u01f6\b/\u00010\u00010\u00010\u0001"+ - "0\u00010\u00050\u01fd\b0\n0\f0\u0200\t0\u00011\u00011\u00011\u00012\u0001"+ - "2\u00012\u00013\u00013\u00013\u00013\u00014\u00014\u00014\u00015\u0001"+ - "5\u00015\u00015\u00035\u0213\b5\u00015\u00015\u00015\u00015\u00055\u0219"+ - "\b5\n5\f5\u021c\t5\u00035\u021e\b5\u00016\u00016\u00017\u00017\u00017"+ - "\u00037\u0225\b7\u00017\u00017\u00018\u00018\u00018\u00019\u00019\u0001"+ - "9\u00019\u00039\u0230\b9\u00019\u00019\u00019\u00019\u00019\u00039\u0237"+ - "\b9\u0001:\u0001:\u0001:\u0001;\u0004;\u023d\b;\u000b;\f;\u023e\u0001"+ - "<\u0001<\u0001<\u0001<\u0001=\u0001=\u0001=\u0001=\u0001=\u0001=\u0005"+ - "=\u024b\b=\n=\f=\u024e\t=\u0001>\u0001>\u0001?\u0001?\u0001?\u0001?\u0003"+ - "?\u0256\b?\u0001?\u0001?\u0001?\u0001?\u0001?\u0001@\u0001@\u0001@\u0001"+ - "@\u0003@\u0261\b@\u0001@\u0001@\u0001@\u0001A\u0001A\u0001A\u0001A\u0001"+ - "A\u0003A\u026b\bA\u0001A\u0001A\u0001A\u0001A\u0003A\u0271\bA\u0003A\u0273"+ - "\bA\u0001B\u0001B\u0003B\u0277\bB\u0001B\u0005B\u027a\bB\nB\fB\u027d\t"+ - "B\u0001C\u0001C\u0001C\u0001C\u0001C\u0001C\u0001C\u0001C\u0001C\u0001"+ - "C\u0001C\u0003C\u028a\bC\u0001D\u0001D\u0001D\u0001D\u0001D\u0001E\u0001"+ - "E\u0001E\u0001F\u0001F\u0001F\u0001F\u0001G\u0001G\u0001G\u0001G\u0001"+ - "H\u0001H\u0001H\u0001H\u0001H\u0001H\u0001H\u0003H\u02a3\bH\u0001H\u0001"+ - "H\u0001H\u0001H\u0001H\u0005H\u02aa\bH\nH\fH\u02ad\tH\u0001H\u0001H\u0001"+ - "H\u0001H\u0001H\u0003H\u02b4\bH\u0001H\u0001H\u0001H\u0003H\u02b9\bH\u0001"+ - "H\u0001H\u0001H\u0001H\u0001H\u0001H\u0005H\u02c1\bH\nH\fH\u02c4\tH\u0001"+ - "I\u0001I\u0003I\u02c8\bI\u0001I\u0001I\u0001I\u0001I\u0001I\u0003I\u02cf"+ - "\bI\u0001I\u0001I\u0001I\u0001I\u0001I\u0003I\u02d6\bI\u0001I\u0001I\u0001"+ - "I\u0001I\u0001I\u0005I\u02dd\bI\nI\fI\u02e0\tI\u0001I\u0001I\u0001I\u0001"+ - "I\u0003I\u02e6\bI\u0001I\u0001I\u0001I\u0001I\u0001I\u0005I\u02ed\bI\n"+ - "I\fI\u02f0\tI\u0001I\u0001I\u0003I\u02f4\bI\u0001J\u0001J\u0001J\u0003"+ - "J\u02f9\bJ\u0001J\u0001J\u0001J\u0001K\u0001K\u0001K\u0001K\u0001K\u0003"+ - "K\u0303\bK\u0001L\u0001L\u0001L\u0001L\u0003L\u0309\bL\u0001L\u0001L\u0001"+ - "L\u0001L\u0001L\u0001L\u0005L\u0311\bL\nL\fL\u0314\tL\u0001M\u0001M\u0001"+ - "M\u0001M\u0001M\u0001M\u0001M\u0001M\u0003M\u031e\bM\u0001M\u0001M\u0001"+ - "M\u0005M\u0323\bM\nM\fM\u0326\tM\u0001N\u0001N\u0001N\u0001N\u0001N\u0001"+ - "N\u0005N\u032e\bN\nN\fN\u0331\tN\u0001N\u0001N\u0003N\u0335\bN\u0003N"+ - "\u0337\bN\u0001N\u0001N\u0001O\u0001O\u0001O\u0003O\u033e\bO\u0001P\u0001"+ - "P\u0001P\u0001P\u0005P\u0344\bP\nP\fP\u0347\tP\u0003P\u0349\bP\u0001P"+ - "\u0001P\u0001Q\u0001Q\u0001Q\u0001Q\u0001R\u0001R\u0003R\u0353\bR\u0001"+ - "S\u0001S\u0001S\u0001S\u0001S\u0001S\u0001S\u0001S\u0001S\u0001S\u0001"+ - "S\u0001S\u0001S\u0005S\u0362\bS\nS\fS\u0365\tS\u0001S\u0001S\u0001S\u0001"+ - "S\u0001S\u0001S\u0005S\u036d\bS\nS\fS\u0370\tS\u0001S\u0001S\u0001S\u0001"+ - "S\u0001S\u0001S\u0005S\u0378\bS\nS\fS\u037b\tS\u0001S\u0001S\u0003S\u037f"+ - "\bS\u0001T\u0001T\u0001U\u0001U\u0003U\u0385\bU\u0001V\u0003V\u0388\b"+ - "V\u0001V\u0001V\u0001W\u0003W\u038d\bW\u0001W\u0001W\u0001X\u0001X\u0001"+ + "Y\u0002Z\u0007Z\u0002[\u0007[\u0002\\\u0007\\\u0002]\u0007]\u0002^\u0007"+ + "^\u0002_\u0007_\u0002`\u0007`\u0001\u0000\u0005\u0000\u00c4\b\u0000\n"+ + "\u0000\f\u0000\u00c7\t\u0000\u0001\u0000\u0001\u0000\u0001\u0000\u0001"+ + "\u0001\u0001\u0001\u0001\u0001\u0001\u0002\u0001\u0002\u0001\u0002\u0001"+ + "\u0002\u0001\u0002\u0001\u0002\u0005\u0002\u00d5\b\u0002\n\u0002\f\u0002"+ + "\u00d8\t\u0002\u0001\u0003\u0001\u0003\u0001\u0003\u0001\u0003\u0001\u0003"+ + "\u0001\u0003\u0003\u0003\u00e0\b\u0003\u0001\u0004\u0001\u0004\u0001\u0004"+ + "\u0001\u0004\u0001\u0004\u0001\u0004\u0001\u0004\u0001\u0004\u0001\u0004"+ + "\u0001\u0004\u0001\u0004\u0001\u0004\u0001\u0004\u0001\u0004\u0001\u0004"+ + "\u0001\u0004\u0001\u0004\u0001\u0004\u0001\u0004\u0001\u0004\u0001\u0004"+ + "\u0001\u0004\u0001\u0004\u0001\u0004\u0001\u0004\u0001\u0004\u0003\u0004"+ + "\u00fc\b\u0004\u0001\u0005\u0001\u0005\u0001\u0005\u0001\u0006\u0001\u0006"+ + "\u0001\u0007\u0001\u0007\u0001\u0007\u0001\b\u0001\b\u0001\b\u0005\b\u0109"+ + "\b\b\n\b\f\b\u010c\t\b\u0001\t\u0001\t\u0001\t\u0003\t\u0111\b\t\u0001"+ + "\t\u0001\t\u0001\n\u0001\n\u0001\n\u0005\n\u0118\b\n\n\n\f\n\u011b\t\n"+ + "\u0001\u000b\u0001\u000b\u0001\u000b\u0003\u000b\u0120\b\u000b\u0001\f"+ + "\u0001\f\u0001\f\u0001\r\u0001\r\u0001\r\u0001\u000e\u0001\u000e\u0001"+ + "\u000e\u0005\u000e\u012b\b\u000e\n\u000e\f\u000e\u012e\t\u000e\u0001\u000e"+ + "\u0003\u000e\u0131\b\u000e\u0001\u000f\u0001\u000f\u0001\u000f\u0003\u000f"+ + "\u0136\b\u000f\u0001\u0010\u0001\u0010\u0001\u0010\u0001\u0010\u0005\u0010"+ + "\u013c\b\u0010\n\u0010\f\u0010\u013f\t\u0010\u0001\u0010\u0001\u0010\u0001"+ + "\u0011\u0001\u0011\u0001\u0011\u0001\u0011\u0001\u0011\u0001\u0011\u0001"+ + "\u0011\u0001\u0011\u0001\u0011\u0003\u0011\u014c\b\u0011\u0001\u0012\u0001"+ + "\u0012\u0001\u0013\u0001\u0013\u0001\u0014\u0001\u0014\u0001\u0015\u0001"+ + "\u0015\u0001\u0016\u0001\u0016\u0001\u0016\u0001\u0016\u0005\u0016\u015a"+ + "\b\u0016\n\u0016\f\u0016\u015d\t\u0016\u0001\u0017\u0001\u0017\u0001\u0017"+ + "\u0001\u0018\u0001\u0018\u0003\u0018\u0164\b\u0018\u0001\u0018\u0001\u0018"+ + "\u0003\u0018\u0168\b\u0018\u0001\u0019\u0001\u0019\u0001\u0019\u0005\u0019"+ + "\u016d\b\u0019\n\u0019\f\u0019\u0170\t\u0019\u0001\u001a\u0001\u001a\u0001"+ + "\u001a\u0003\u001a\u0175\b\u001a\u0001\u001b\u0001\u001b\u0001\u001b\u0003"+ + "\u001b\u017a\b\u001b\u0001\u001b\u0001\u001b\u0001\u001b\u0001\u001b\u0001"+ + "\u001b\u0001\u001b\u0001\u001b\u0003\u001b\u0183\b\u001b\u0001\u001c\u0001"+ + "\u001c\u0001\u001c\u0005\u001c\u0188\b\u001c\n\u001c\f\u001c\u018b\t\u001c"+ + "\u0001\u001d\u0001\u001d\u0001\u001d\u0003\u001d\u0190\b\u001d\u0001\u001d"+ + "\u0001\u001d\u0001\u001d\u0001\u001d\u0001\u001d\u0001\u001d\u0001\u001d"+ + "\u0003\u001d\u0199\b\u001d\u0001\u001e\u0001\u001e\u0001\u001e\u0005\u001e"+ + "\u019e\b\u001e\n\u001e\f\u001e\u01a1\t\u001e\u0001\u001f\u0001\u001f\u0001"+ + "\u001f\u0005\u001f\u01a6\b\u001f\n\u001f\f\u001f\u01a9\t\u001f\u0001 "+ + "\u0001 \u0001!\u0001!\u0001!\u0003!\u01b0\b!\u0001\"\u0001\"\u0003\"\u01b4"+ + "\b\"\u0001#\u0001#\u0003#\u01b8\b#\u0001$\u0001$\u0001$\u0003$\u01bd\b"+ + "$\u0001%\u0001%\u0001%\u0001&\u0001&\u0001&\u0001&\u0005&\u01c6\b&\n&"+ + "\f&\u01c9\t&\u0001\'\u0001\'\u0003\'\u01cd\b\'\u0001\'\u0001\'\u0003\'"+ + "\u01d1\b\'\u0001(\u0001(\u0001(\u0001)\u0001)\u0001)\u0001*\u0001*\u0001"+ + "*\u0001*\u0005*\u01dd\b*\n*\f*\u01e0\t*\u0001+\u0001+\u0001+\u0001+\u0001"+ + "+\u0001+\u0001+\u0001+\u0003+\u01ea\b+\u0001,\u0001,\u0001,\u0001,\u0003"+ + ",\u01f0\b,\u0001-\u0001-\u0001-\u0005-\u01f5\b-\n-\f-\u01f8\t-\u0001."+ + "\u0001.\u0001.\u0001.\u0001/\u0001/\u0003/\u0200\b/\u00010\u00010\u0001"+ + "0\u00010\u00010\u00050\u0207\b0\n0\f0\u020a\t0\u00011\u00011\u00011\u0001"+ + "2\u00012\u00012\u00013\u00013\u00013\u00013\u00014\u00014\u00014\u0001"+ + "5\u00015\u00015\u00015\u00035\u021d\b5\u00015\u00015\u00015\u00015\u0005"+ + "5\u0223\b5\n5\f5\u0226\t5\u00035\u0228\b5\u00016\u00016\u00017\u00017"+ + "\u00017\u00037\u022f\b7\u00017\u00017\u00018\u00018\u00018\u00019\u0001"+ + "9\u00019\u00019\u00039\u023a\b9\u00019\u00019\u00019\u00019\u00019\u0003"+ + "9\u0241\b9\u0001:\u0001:\u0001:\u0001;\u0004;\u0247\b;\u000b;\f;\u0248"+ + "\u0001<\u0001<\u0001<\u0001<\u0001=\u0001=\u0001=\u0001=\u0001=\u0001"+ + "=\u0005=\u0255\b=\n=\f=\u0258\t=\u0001>\u0001>\u0001?\u0001?\u0001?\u0001"+ + "?\u0003?\u0260\b?\u0001?\u0001?\u0001?\u0001?\u0001?\u0001@\u0001@\u0001"+ + "@\u0001@\u0003@\u026b\b@\u0001@\u0001@\u0001@\u0001A\u0001A\u0001A\u0001"+ + "A\u0001A\u0003A\u0275\bA\u0001A\u0001A\u0001A\u0001A\u0003A\u027b\bA\u0003"+ + "A\u027d\bA\u0001B\u0001B\u0003B\u0281\bB\u0001B\u0005B\u0284\bB\nB\fB"+ + "\u0287\tB\u0001C\u0001C\u0001C\u0001C\u0001C\u0001C\u0001C\u0001C\u0001"+ + "C\u0001C\u0001C\u0003C\u0294\bC\u0001D\u0001D\u0001D\u0001D\u0001D\u0001"+ + "E\u0001E\u0001E\u0001F\u0001F\u0001F\u0001F\u0001G\u0001G\u0001G\u0001"+ + "G\u0001H\u0001H\u0001H\u0001H\u0001H\u0001H\u0001H\u0003H\u02ad\bH\u0001"+ + "H\u0001H\u0001H\u0001H\u0001H\u0005H\u02b4\bH\nH\fH\u02b7\tH\u0001H\u0001"+ + "H\u0001H\u0001H\u0001H\u0003H\u02be\bH\u0001H\u0001H\u0001H\u0003H\u02c3"+ + "\bH\u0001H\u0001H\u0001H\u0001H\u0001H\u0001H\u0005H\u02cb\bH\nH\fH\u02ce"+ + "\tH\u0001I\u0001I\u0003I\u02d2\bI\u0001I\u0001I\u0001I\u0001I\u0001I\u0003"+ + "I\u02d9\bI\u0001I\u0001I\u0001I\u0001I\u0001I\u0003I\u02e0\bI\u0001I\u0001"+ + "I\u0001I\u0001I\u0001I\u0005I\u02e7\bI\nI\fI\u02ea\tI\u0001I\u0001I\u0001"+ + "I\u0001I\u0003I\u02f0\bI\u0001I\u0001I\u0001I\u0001I\u0001I\u0005I\u02f7"+ + "\bI\nI\fI\u02fa\tI\u0001I\u0001I\u0003I\u02fe\bI\u0001J\u0001J\u0001J"+ + "\u0003J\u0303\bJ\u0001J\u0001J\u0001J\u0001K\u0001K\u0001K\u0001K\u0001"+ + "K\u0003K\u030d\bK\u0001L\u0001L\u0001L\u0001L\u0003L\u0313\bL\u0001L\u0001"+ + "L\u0001L\u0001L\u0001L\u0001L\u0005L\u031b\bL\nL\fL\u031e\tL\u0001M\u0001"+ + "M\u0001M\u0001M\u0001M\u0001M\u0001M\u0001M\u0003M\u0328\bM\u0001M\u0001"+ + "M\u0001M\u0005M\u032d\bM\nM\fM\u0330\tM\u0001N\u0001N\u0001N\u0001N\u0001"+ + "N\u0001N\u0005N\u0338\bN\nN\fN\u033b\tN\u0001N\u0001N\u0003N\u033f\bN"+ + "\u0003N\u0341\bN\u0001N\u0001N\u0001O\u0001O\u0001O\u0003O\u0348\bO\u0001"+ + "P\u0001P\u0001P\u0001P\u0005P\u034e\bP\nP\fP\u0351\tP\u0003P\u0353\bP"+ + "\u0001P\u0001P\u0001Q\u0001Q\u0001Q\u0001Q\u0001R\u0001R\u0003R\u035d"+ + "\bR\u0001S\u0001S\u0001S\u0001S\u0001S\u0001S\u0001S\u0001S\u0001S\u0001"+ + "S\u0001S\u0001S\u0001S\u0005S\u036c\bS\nS\fS\u036f\tS\u0001S\u0001S\u0001"+ + "S\u0001S\u0001S\u0001S\u0005S\u0377\bS\nS\fS\u037a\tS\u0001S\u0001S\u0001"+ + "S\u0001S\u0001S\u0001S\u0005S\u0382\bS\nS\fS\u0385\tS\u0001S\u0001S\u0003"+ + "S\u0389\bS\u0001T\u0001T\u0001U\u0001U\u0003U\u038f\bU\u0001V\u0003V\u0392"+ + "\bV\u0001V\u0001V\u0001W\u0003W\u0397\bW\u0001W\u0001W\u0001X\u0001X\u0001"+ "Y\u0001Y\u0001Z\u0001Z\u0001Z\u0001Z\u0001Z\u0001[\u0001[\u0001[\u0003"+ - "[\u039d\b[\u0001[\u0001[\u0001[\u0003[\u03a2\b[\u0001\\\u0001\\\u0001"+ - "\\\u0001\\\u0005\\\u03a8\b\\\n\\\f\\\u03ab\t\\\u0001\\\u0000\u0005\u0004"+ - "z\u0090\u0098\u009a]\u0000\u0002\u0004\u0006\b\n\f\u000e\u0010\u0012\u0014"+ + "[\u03a7\b[\u0001[\u0001[\u0001[\u0003[\u03ac\b[\u0001\\\u0001\\\u0001"+ + "\\\u0001\\\u0005\\\u03b2\b\\\n\\\f\\\u03b5\t\\\u0001]\u0001]\u0004]\u03b9"+ + "\b]\u000b]\f]\u03ba\u0001]\u0001]\u0005]\u03bf\b]\n]\f]\u03c2\t]\u0001"+ + "]\u0001]\u0001^\u0001^\u0001^\u0001_\u0001_\u0001`\u0001`\u0001`\u0005"+ + "`\u03ce\b`\n`\f`\u03d1\t`\u0001`\u0003`\u03d4\b`\u0001`\u0000\u0005\u0004"+ + "z\u0090\u0098\u009aa\u0000\u0002\u0004\u0006\b\n\f\u000e\u0010\u0012\u0014"+ "\u0016\u0018\u001a\u001c\u001e \"$&(*,.02468:<>@BDFHJLNPRTVXZ\\^`bdfh"+ "jlnprtvxz|~\u0080\u0082\u0084\u0086\u0088\u008a\u008c\u008e\u0090\u0092"+ "\u0094\u0096\u0098\u009a\u009c\u009e\u00a0\u00a2\u00a4\u00a6\u00a8\u00aa"+ - "\u00ac\u00ae\u00b0\u00b2\u00b4\u00b6\u00b8\u0000\n\u0002\u000033jj\u0001"+ - "\u0000de\u0002\u000077>>\u0002\u0000AADD\u0002\u0000((33\u0001\u0000V"+ - "W\u0001\u0000XZ\u0002\u0000@@MM\u0002\u0000OOQU\u0002\u0000\u0018\u0018"+ - "\u001a\u001b\u03d8\u0000\u00bd\u0001\u0000\u0000\u0000\u0002\u00c3\u0001"+ - "\u0000\u0000\u0000\u0004\u00c6\u0001\u0000\u0000\u0000\u0006\u00d7\u0001"+ - "\u0000\u0000\u0000\b\u00f1\u0001\u0000\u0000\u0000\n\u00f3\u0001\u0000"+ - "\u0000\u0000\f\u00f6\u0001\u0000\u0000\u0000\u000e\u00f8\u0001\u0000\u0000"+ - "\u0000\u0010\u00fb\u0001\u0000\u0000\u0000\u0012\u0106\u0001\u0000\u0000"+ - "\u0000\u0014\u010a\u0001\u0000\u0000\u0000\u0016\u0112\u0001\u0000\u0000"+ - "\u0000\u0018\u0117\u0001\u0000\u0000\u0000\u001a\u011a\u0001\u0000\u0000"+ - "\u0000\u001c\u011d\u0001\u0000\u0000\u0000\u001e\u012b\u0001\u0000\u0000"+ - "\u0000 \u012d\u0001\u0000\u0000\u0000\"\u0141\u0001\u0000\u0000\u0000"+ - "$\u0143\u0001\u0000\u0000\u0000&\u0145\u0001\u0000\u0000\u0000(\u0147"+ - "\u0001\u0000\u0000\u0000*\u0149\u0001\u0000\u0000\u0000,\u014b\u0001\u0000"+ - "\u0000\u0000.\u0154\u0001\u0000\u0000\u00000\u0157\u0001\u0000\u0000\u0000"+ - "2\u015f\u0001\u0000\u0000\u00004\u0167\u0001\u0000\u0000\u00006\u0178"+ - "\u0001\u0000\u0000\u00008\u017a\u0001\u0000\u0000\u0000:\u018e\u0001\u0000"+ - "\u0000\u0000<\u0190\u0001\u0000\u0000\u0000>\u0198\u0001\u0000\u0000\u0000"+ - "@\u01a0\u0001\u0000\u0000\u0000B\u01a5\u0001\u0000\u0000\u0000D\u01a9"+ - "\u0001\u0000\u0000\u0000F\u01ad\u0001\u0000\u0000\u0000H\u01b2\u0001\u0000"+ - "\u0000\u0000J\u01b4\u0001\u0000\u0000\u0000L\u01b7\u0001\u0000\u0000\u0000"+ - "N\u01c0\u0001\u0000\u0000\u0000P\u01c8\u0001\u0000\u0000\u0000R\u01cb"+ - "\u0001\u0000\u0000\u0000T\u01ce\u0001\u0000\u0000\u0000V\u01df\u0001\u0000"+ - "\u0000\u0000X\u01e1\u0001\u0000\u0000\u0000Z\u01e7\u0001\u0000\u0000\u0000"+ - "\\\u01ef\u0001\u0000\u0000\u0000^\u01f5\u0001\u0000\u0000\u0000`\u01f7"+ - "\u0001\u0000\u0000\u0000b\u0201\u0001\u0000\u0000\u0000d\u0204\u0001\u0000"+ - "\u0000\u0000f\u0207\u0001\u0000\u0000\u0000h\u020b\u0001\u0000\u0000\u0000"+ - "j\u020e\u0001\u0000\u0000\u0000l\u021f\u0001\u0000\u0000\u0000n\u0224"+ - "\u0001\u0000\u0000\u0000p\u0228\u0001\u0000\u0000\u0000r\u022b\u0001\u0000"+ - "\u0000\u0000t\u0238\u0001\u0000\u0000\u0000v\u023c\u0001\u0000\u0000\u0000"+ - "x\u0240\u0001\u0000\u0000\u0000z\u0244\u0001\u0000\u0000\u0000|\u024f"+ - "\u0001\u0000\u0000\u0000~\u0251\u0001\u0000\u0000\u0000\u0080\u025c\u0001"+ - "\u0000\u0000\u0000\u0082\u0272\u0001\u0000\u0000\u0000\u0084\u0274\u0001"+ - "\u0000\u0000\u0000\u0086\u0289\u0001\u0000\u0000\u0000\u0088\u028b\u0001"+ - "\u0000\u0000\u0000\u008a\u0290\u0001\u0000\u0000\u0000\u008c\u0293\u0001"+ - "\u0000\u0000\u0000\u008e\u0297\u0001\u0000\u0000\u0000\u0090\u02b8\u0001"+ - "\u0000\u0000\u0000\u0092\u02f3\u0001\u0000\u0000\u0000\u0094\u02f5\u0001"+ - "\u0000\u0000\u0000\u0096\u0302\u0001\u0000\u0000\u0000\u0098\u0308\u0001"+ - "\u0000\u0000\u0000\u009a\u031d\u0001\u0000\u0000\u0000\u009c\u0327\u0001"+ - "\u0000\u0000\u0000\u009e\u033d\u0001\u0000\u0000\u0000\u00a0\u033f\u0001"+ - "\u0000\u0000\u0000\u00a2\u034c\u0001\u0000\u0000\u0000\u00a4\u0352\u0001"+ - "\u0000\u0000\u0000\u00a6\u037e\u0001\u0000\u0000\u0000\u00a8\u0380\u0001"+ - "\u0000\u0000\u0000\u00aa\u0384\u0001\u0000\u0000\u0000\u00ac\u0387\u0001"+ - "\u0000\u0000\u0000\u00ae\u038c\u0001\u0000\u0000\u0000\u00b0\u0390\u0001"+ - "\u0000\u0000\u0000\u00b2\u0392\u0001\u0000\u0000\u0000\u00b4\u0394\u0001"+ - "\u0000\u0000\u0000\u00b6\u03a1\u0001\u0000\u0000\u0000\u00b8\u03a3\u0001"+ - "\u0000\u0000\u0000\u00ba\u00bc\u0003\u008cF\u0000\u00bb\u00ba\u0001\u0000"+ - "\u0000\u0000\u00bc\u00bf\u0001\u0000\u0000\u0000\u00bd\u00bb\u0001\u0000"+ - "\u0000\u0000\u00bd\u00be\u0001\u0000\u0000\u0000\u00be\u00c0\u0001\u0000"+ - "\u0000\u0000\u00bf\u00bd\u0001\u0000\u0000\u0000\u00c0\u00c1\u0003\u0002"+ - "\u0001\u0000\u00c1\u00c2\u0005\u0000\u0000\u0001\u00c2\u0001\u0001\u0000"+ - "\u0000\u0000\u00c3\u00c4\u0003\u0004\u0002\u0000\u00c4\u00c5\u0005\u0000"+ - "\u0000\u0001\u00c5\u0003\u0001\u0000\u0000\u0000\u00c6\u00c7\u0006\u0002"+ - "\uffff\uffff\u0000\u00c7\u00c8\u0003\u0006\u0003\u0000\u00c8\u00ce\u0001"+ - "\u0000\u0000\u0000\u00c9\u00ca\n\u0001\u0000\u0000\u00ca\u00cb\u00052"+ - "\u0000\u0000\u00cb\u00cd\u0003\b\u0004\u0000\u00cc\u00c9\u0001\u0000\u0000"+ - "\u0000\u00cd\u00d0\u0001\u0000\u0000\u0000\u00ce\u00cc\u0001\u0000\u0000"+ - "\u0000\u00ce\u00cf\u0001\u0000\u0000\u0000\u00cf\u0005\u0001\u0000\u0000"+ - "\u0000\u00d0\u00ce\u0001\u0000\u0000\u0000\u00d1\u00d8\u0003\u0018\f\u0000"+ - "\u00d2\u00d8\u0003\u000e\u0007\u0000\u00d3\u00d8\u0003h4\u0000\u00d4\u00d8"+ - "\u0003\u001a\r\u0000\u00d5\u00d6\u0004\u0003\u0001\u0000\u00d6\u00d8\u0003"+ - "d2\u0000\u00d7\u00d1\u0001\u0000\u0000\u0000\u00d7\u00d2\u0001\u0000\u0000"+ - "\u0000\u00d7\u00d3\u0001\u0000\u0000\u0000\u00d7\u00d4\u0001\u0000\u0000"+ - "\u0000\u00d7\u00d5\u0001\u0000\u0000\u0000\u00d8\u0007\u0001\u0000\u0000"+ - "\u0000\u00d9\u00f2\u0003.\u0017\u0000\u00da\u00f2\u0003\n\u0005\u0000"+ - "\u00db\u00f2\u0003P(\u0000\u00dc\u00f2\u0003J%\u0000\u00dd\u00f2\u0003"+ - "0\u0018\u0000\u00de\u00f2\u0003L&\u0000\u00df\u00f2\u0003R)\u0000\u00e0"+ - "\u00f2\u0003T*\u0000\u00e1\u00f2\u0003X,\u0000\u00e2\u00f2\u0003`0\u0000"+ - "\u00e3\u00f2\u0003j5\u0000\u00e4\u00f2\u0003b1\u0000\u00e5\u00f2\u0003"+ - "\u00b4Z\u0000\u00e6\u00f2\u0003r9\u0000\u00e7\u00f2\u0003\u0080@\u0000"+ - "\u00e8\u00f2\u0003p8\u0000\u00e9\u00f2\u0003t:\u0000\u00ea\u00f2\u0003"+ - "~?\u0000\u00eb\u00f2\u0003\u0082A\u0000\u00ec\u00f2\u0003\u0084B\u0000"+ - "\u00ed\u00ee\u0004\u0004\u0002\u0000\u00ee\u00f2\u0003\u0088D\u0000\u00ef"+ - "\u00f0\u0004\u0004\u0003\u0000\u00f0\u00f2\u0003\u008aE\u0000\u00f1\u00d9"+ - "\u0001\u0000\u0000\u0000\u00f1\u00da\u0001\u0000\u0000\u0000\u00f1\u00db"+ - "\u0001\u0000\u0000\u0000\u00f1\u00dc\u0001\u0000\u0000\u0000\u00f1\u00dd"+ - "\u0001\u0000\u0000\u0000\u00f1\u00de\u0001\u0000\u0000\u0000\u00f1\u00df"+ - "\u0001\u0000\u0000\u0000\u00f1\u00e0\u0001\u0000\u0000\u0000\u00f1\u00e1"+ - "\u0001\u0000\u0000\u0000\u00f1\u00e2\u0001\u0000\u0000\u0000\u00f1\u00e3"+ - "\u0001\u0000\u0000\u0000\u00f1\u00e4\u0001\u0000\u0000\u0000\u00f1\u00e5"+ - "\u0001\u0000\u0000\u0000\u00f1\u00e6\u0001\u0000\u0000\u0000\u00f1\u00e7"+ - "\u0001\u0000\u0000\u0000\u00f1\u00e8\u0001\u0000\u0000\u0000\u00f1\u00e9"+ - "\u0001\u0000\u0000\u0000\u00f1\u00ea\u0001\u0000\u0000\u0000\u00f1\u00eb"+ - "\u0001\u0000\u0000\u0000\u00f1\u00ec\u0001\u0000\u0000\u0000\u00f1\u00ed"+ - "\u0001\u0000\u0000\u0000\u00f1\u00ef\u0001\u0000\u0000\u0000\u00f2\t\u0001"+ - "\u0000\u0000\u0000\u00f3\u00f4\u0005\u0011\u0000\u0000\u00f4\u00f5\u0003"+ - "\u0090H\u0000\u00f5\u000b\u0001\u0000\u0000\u0000\u00f6\u00f7\u0003@ "+ - "\u0000\u00f7\r\u0001\u0000\u0000\u0000\u00f8\u00f9\u0005\r\u0000\u0000"+ - "\u00f9\u00fa\u0003\u0010\b\u0000\u00fa\u000f\u0001\u0000\u0000\u0000\u00fb"+ - "\u0100\u0003\u0012\t\u0000\u00fc\u00fd\u0005=\u0000\u0000\u00fd\u00ff"+ - "\u0003\u0012\t\u0000\u00fe\u00fc\u0001\u0000\u0000\u0000\u00ff\u0102\u0001"+ - "\u0000\u0000\u0000\u0100\u00fe\u0001\u0000\u0000\u0000\u0100\u0101\u0001"+ - "\u0000\u0000\u0000\u0101\u0011\u0001\u0000\u0000\u0000\u0102\u0100\u0001"+ - "\u0000\u0000\u0000\u0103\u0104\u00036\u001b\u0000\u0104\u0105\u00058\u0000"+ - "\u0000\u0105\u0107\u0001\u0000\u0000\u0000\u0106\u0103\u0001\u0000\u0000"+ - "\u0000\u0106\u0107\u0001\u0000\u0000\u0000\u0107\u0108\u0001\u0000\u0000"+ - "\u0000\u0108\u0109\u0003\u0090H\u0000\u0109\u0013\u0001\u0000\u0000\u0000"+ - "\u010a\u010f\u0003\u0016\u000b\u0000\u010b\u010c\u0005=\u0000\u0000\u010c"+ - "\u010e\u0003\u0016\u000b\u0000\u010d\u010b\u0001\u0000\u0000\u0000\u010e"+ - "\u0111\u0001\u0000\u0000\u0000\u010f\u010d\u0001\u0000\u0000\u0000\u010f"+ - "\u0110\u0001\u0000\u0000\u0000\u0110\u0015\u0001\u0000\u0000\u0000\u0111"+ - "\u010f\u0001\u0000\u0000\u0000\u0112\u0115\u00036\u001b\u0000\u0113\u0114"+ - "\u00058\u0000\u0000\u0114\u0116\u0003\u0090H\u0000\u0115\u0113\u0001\u0000"+ - "\u0000\u0000\u0115\u0116\u0001\u0000\u0000\u0000\u0116\u0017\u0001\u0000"+ - "\u0000\u0000\u0117\u0118\u0005\u0012\u0000\u0000\u0118\u0119\u0003\u001c"+ - "\u000e\u0000\u0119\u0019\u0001\u0000\u0000\u0000\u011a\u011b\u0005\u0013"+ - "\u0000\u0000\u011b\u011c\u0003\u001c\u000e\u0000\u011c\u001b\u0001\u0000"+ - "\u0000\u0000\u011d\u0122\u0003\u001e\u000f\u0000\u011e\u011f\u0005=\u0000"+ - "\u0000\u011f\u0121\u0003\u001e\u000f\u0000\u0120\u011e\u0001\u0000\u0000"+ - "\u0000\u0121\u0124\u0001\u0000\u0000\u0000\u0122\u0120\u0001\u0000\u0000"+ - "\u0000\u0122\u0123\u0001\u0000\u0000\u0000\u0123\u0126\u0001\u0000\u0000"+ - "\u0000\u0124\u0122\u0001\u0000\u0000\u0000\u0125\u0127\u0003,\u0016\u0000"+ - "\u0126\u0125\u0001\u0000\u0000\u0000\u0126\u0127\u0001\u0000\u0000\u0000"+ - "\u0127\u001d\u0001\u0000\u0000\u0000\u0128\u012c\u0003\"\u0011\u0000\u0129"+ - "\u012a\u0004\u000f\u0004\u0000\u012a\u012c\u0003 \u0010\u0000\u012b\u0128"+ - "\u0001\u0000\u0000\u0000\u012b\u0129\u0001\u0000\u0000\u0000\u012c\u001f"+ - "\u0001\u0000\u0000\u0000\u012d\u012e\u0005b\u0000\u0000\u012e\u0133\u0003"+ - "\u0018\f\u0000\u012f\u0130\u00052\u0000\u0000\u0130\u0132\u0003\b\u0004"+ - "\u0000\u0131\u012f\u0001\u0000\u0000\u0000\u0132\u0135\u0001\u0000\u0000"+ - "\u0000\u0133\u0131\u0001\u0000\u0000\u0000\u0133\u0134\u0001\u0000\u0000"+ - "\u0000\u0134\u0136\u0001\u0000\u0000\u0000\u0135\u0133\u0001\u0000\u0000"+ - "\u0000\u0136\u0137\u0005c\u0000\u0000\u0137!\u0001\u0000\u0000\u0000\u0138"+ - "\u0139\u0003$\u0012\u0000\u0139\u013a\u0005;\u0000\u0000\u013a\u013b\u0003"+ - "(\u0014\u0000\u013b\u0142\u0001\u0000\u0000\u0000\u013c\u013d\u0003(\u0014"+ - "\u0000\u013d\u013e\u0005:\u0000\u0000\u013e\u013f\u0003&\u0013\u0000\u013f"+ - "\u0142\u0001\u0000\u0000\u0000\u0140\u0142\u0003*\u0015\u0000\u0141\u0138"+ - "\u0001\u0000\u0000\u0000\u0141\u013c\u0001\u0000\u0000\u0000\u0141\u0140"+ - "\u0001\u0000\u0000\u0000\u0142#\u0001\u0000\u0000\u0000\u0143\u0144\u0005"+ - "j\u0000\u0000\u0144%\u0001\u0000\u0000\u0000\u0145\u0146\u0005j\u0000"+ - "\u0000\u0146\'\u0001\u0000\u0000\u0000\u0147\u0148\u0005j\u0000\u0000"+ - "\u0148)\u0001\u0000\u0000\u0000\u0149\u014a\u0007\u0000\u0000\u0000\u014a"+ - "+\u0001\u0000\u0000\u0000\u014b\u014c\u0005i\u0000\u0000\u014c\u0151\u0005"+ - "j\u0000\u0000\u014d\u014e\u0005=\u0000\u0000\u014e\u0150\u0005j\u0000"+ - "\u0000\u014f\u014d\u0001\u0000\u0000\u0000\u0150\u0153\u0001\u0000\u0000"+ - "\u0000\u0151\u014f\u0001\u0000\u0000\u0000\u0151\u0152\u0001\u0000\u0000"+ - "\u0000\u0152-\u0001\u0000\u0000\u0000\u0153\u0151\u0001\u0000\u0000\u0000"+ - "\u0154\u0155\u0005\t\u0000\u0000\u0155\u0156\u0003\u0010\b\u0000\u0156"+ - "/\u0001\u0000\u0000\u0000\u0157\u0159\u0005\u0010\u0000\u0000\u0158\u015a"+ - "\u00032\u0019\u0000\u0159\u0158\u0001\u0000\u0000\u0000\u0159\u015a\u0001"+ - "\u0000\u0000\u0000\u015a\u015d\u0001\u0000\u0000\u0000\u015b\u015c\u0005"+ - "9\u0000\u0000\u015c\u015e\u0003\u0010\b\u0000\u015d\u015b\u0001\u0000"+ - "\u0000\u0000\u015d\u015e\u0001\u0000\u0000\u0000\u015e1\u0001\u0000\u0000"+ - "\u0000\u015f\u0164\u00034\u001a\u0000\u0160\u0161\u0005=\u0000\u0000\u0161"+ - "\u0163\u00034\u001a\u0000\u0162\u0160\u0001\u0000\u0000\u0000\u0163\u0166"+ - "\u0001\u0000\u0000\u0000\u0164\u0162\u0001\u0000\u0000\u0000\u0164\u0165"+ - "\u0001\u0000\u0000\u0000\u01653\u0001\u0000\u0000\u0000\u0166\u0164\u0001"+ - "\u0000\u0000\u0000\u0167\u016a\u0003\u0012\t\u0000\u0168\u0169\u0005\u0011"+ - "\u0000\u0000\u0169\u016b\u0003\u0090H\u0000\u016a\u0168\u0001\u0000\u0000"+ - "\u0000\u016a\u016b\u0001\u0000\u0000\u0000\u016b5\u0001\u0000\u0000\u0000"+ - "\u016c\u016d\u0004\u001b\u0005\u0000\u016d\u016f\u0005`\u0000\u0000\u016e"+ - "\u0170\u0005d\u0000\u0000\u016f\u016e\u0001\u0000\u0000\u0000\u016f\u0170"+ - "\u0001\u0000\u0000\u0000\u0170\u0171\u0001\u0000\u0000\u0000\u0171\u0172"+ - "\u0005a\u0000\u0000\u0172\u0173\u0005?\u0000\u0000\u0173\u0174\u0005`"+ - "\u0000\u0000\u0174\u0175\u00038\u001c\u0000\u0175\u0176\u0005a\u0000\u0000"+ - "\u0176\u0179\u0001\u0000\u0000\u0000\u0177\u0179\u00038\u001c\u0000\u0178"+ - "\u016c\u0001\u0000\u0000\u0000\u0178\u0177\u0001\u0000\u0000\u0000\u0179"+ - "7\u0001\u0000\u0000\u0000\u017a\u017f\u0003H$\u0000\u017b\u017c\u0005"+ - "?\u0000\u0000\u017c\u017e\u0003H$\u0000\u017d\u017b\u0001\u0000\u0000"+ - "\u0000\u017e\u0181\u0001\u0000\u0000\u0000\u017f\u017d\u0001\u0000\u0000"+ - "\u0000\u017f\u0180\u0001\u0000\u0000\u0000\u01809\u0001\u0000\u0000\u0000"+ - "\u0181\u017f\u0001\u0000\u0000\u0000\u0182\u0183\u0004\u001d\u0006\u0000"+ - "\u0183\u0185\u0005`\u0000\u0000\u0184\u0186\u0005\u0089\u0000\u0000\u0185"+ - "\u0184\u0001\u0000\u0000\u0000\u0185\u0186\u0001\u0000\u0000\u0000\u0186"+ - "\u0187\u0001\u0000\u0000\u0000\u0187\u0188\u0005a\u0000\u0000\u0188\u0189"+ - "\u0005?\u0000\u0000\u0189\u018a\u0005`\u0000\u0000\u018a\u018b\u0003<"+ - "\u001e\u0000\u018b\u018c\u0005a\u0000\u0000\u018c\u018f\u0001\u0000\u0000"+ - "\u0000\u018d\u018f\u0003<\u001e\u0000\u018e\u0182\u0001\u0000\u0000\u0000"+ - "\u018e\u018d\u0001\u0000\u0000\u0000\u018f;\u0001\u0000\u0000\u0000\u0190"+ - "\u0195\u0003B!\u0000\u0191\u0192\u0005?\u0000\u0000\u0192\u0194\u0003"+ - "B!\u0000\u0193\u0191\u0001\u0000\u0000\u0000\u0194\u0197\u0001\u0000\u0000"+ - "\u0000\u0195\u0193\u0001\u0000\u0000\u0000\u0195\u0196\u0001\u0000\u0000"+ - "\u0000\u0196=\u0001\u0000\u0000\u0000\u0197\u0195\u0001\u0000\u0000\u0000"+ - "\u0198\u019d\u0003:\u001d\u0000\u0199\u019a\u0005=\u0000\u0000\u019a\u019c"+ - "\u0003:\u001d\u0000\u019b\u0199\u0001\u0000\u0000\u0000\u019c\u019f\u0001"+ - "\u0000\u0000\u0000\u019d\u019b\u0001\u0000\u0000\u0000\u019d\u019e\u0001"+ - "\u0000\u0000\u0000\u019e?\u0001\u0000\u0000\u0000\u019f\u019d\u0001\u0000"+ - "\u0000\u0000\u01a0\u01a1\u0007\u0001\u0000\u0000\u01a1A\u0001\u0000\u0000"+ - "\u0000\u01a2\u01a6\u0005\u0089\u0000\u0000\u01a3\u01a6\u0003D\"\u0000"+ - "\u01a4\u01a6\u0003F#\u0000\u01a5\u01a2\u0001\u0000\u0000\u0000\u01a5\u01a3"+ - "\u0001\u0000\u0000\u0000\u01a5\u01a4\u0001\u0000\u0000\u0000\u01a6C\u0001"+ - "\u0000\u0000\u0000\u01a7\u01aa\u0005K\u0000\u0000\u01a8\u01aa\u0005^\u0000"+ - "\u0000\u01a9\u01a7\u0001\u0000\u0000\u0000\u01a9\u01a8\u0001\u0000\u0000"+ - "\u0000\u01aaE\u0001\u0000\u0000\u0000\u01ab\u01ae\u0005]\u0000\u0000\u01ac"+ - "\u01ae\u0005_\u0000\u0000\u01ad\u01ab\u0001\u0000\u0000\u0000\u01ad\u01ac"+ - "\u0001\u0000\u0000\u0000\u01aeG\u0001\u0000\u0000\u0000\u01af\u01b3\u0003"+ - "@ \u0000\u01b0\u01b3\u0003D\"\u0000\u01b1\u01b3\u0003F#\u0000\u01b2\u01af"+ - "\u0001\u0000\u0000\u0000\u01b2\u01b0\u0001\u0000\u0000\u0000\u01b2\u01b1"+ - "\u0001\u0000\u0000\u0000\u01b3I\u0001\u0000\u0000\u0000\u01b4\u01b5\u0005"+ - "\u000b\u0000\u0000\u01b5\u01b6\u0003\u00a6S\u0000\u01b6K\u0001\u0000\u0000"+ - "\u0000\u01b7\u01b8\u0005\u000f\u0000\u0000\u01b8\u01bd\u0003N\'\u0000"+ - "\u01b9\u01ba\u0005=\u0000\u0000\u01ba\u01bc\u0003N\'\u0000\u01bb\u01b9"+ - "\u0001\u0000\u0000\u0000\u01bc\u01bf\u0001\u0000\u0000\u0000\u01bd\u01bb"+ - "\u0001\u0000\u0000\u0000\u01bd\u01be\u0001\u0000\u0000\u0000\u01beM\u0001"+ - "\u0000\u0000\u0000\u01bf\u01bd\u0001\u0000\u0000\u0000\u01c0\u01c2\u0003"+ - "\u0090H\u0000\u01c1\u01c3\u0007\u0002\u0000\u0000\u01c2\u01c1\u0001\u0000"+ - "\u0000\u0000\u01c2\u01c3\u0001\u0000\u0000\u0000\u01c3\u01c6\u0001\u0000"+ - "\u0000\u0000\u01c4\u01c5\u0005H\u0000\u0000\u01c5\u01c7\u0007\u0003\u0000"+ - "\u0000\u01c6\u01c4\u0001\u0000\u0000\u0000\u01c6\u01c7\u0001\u0000\u0000"+ - "\u0000\u01c7O\u0001\u0000\u0000\u0000\u01c8\u01c9\u0005\u001f\u0000\u0000"+ - "\u01c9\u01ca\u0003>\u001f\u0000\u01caQ\u0001\u0000\u0000\u0000\u01cb\u01cc"+ - "\u0005\u001e\u0000\u0000\u01cc\u01cd\u0003>\u001f\u0000\u01cdS\u0001\u0000"+ - "\u0000\u0000\u01ce\u01cf\u0005!\u0000\u0000\u01cf\u01d4\u0003V+\u0000"+ - "\u01d0\u01d1\u0005=\u0000\u0000\u01d1\u01d3\u0003V+\u0000\u01d2\u01d0"+ - "\u0001\u0000\u0000\u0000\u01d3\u01d6\u0001\u0000\u0000\u0000\u01d4\u01d2"+ - "\u0001\u0000\u0000\u0000\u01d4\u01d5\u0001\u0000\u0000\u0000\u01d5U\u0001"+ - "\u0000\u0000\u0000\u01d6\u01d4\u0001\u0000\u0000\u0000\u01d7\u01d8\u0003"+ - ":\u001d\u0000\u01d8\u01d9\u0005\u008d\u0000\u0000\u01d9\u01da\u0003:\u001d"+ - "\u0000\u01da\u01e0\u0001\u0000\u0000\u0000\u01db\u01dc\u0003:\u001d\u0000"+ - "\u01dc\u01dd\u00058\u0000\u0000\u01dd\u01de\u0003:\u001d\u0000\u01de\u01e0"+ - "\u0001\u0000\u0000\u0000\u01df\u01d7\u0001\u0000\u0000\u0000\u01df\u01db"+ - "\u0001\u0000\u0000\u0000\u01e0W\u0001\u0000\u0000\u0000\u01e1\u01e2\u0005"+ - "\b\u0000\u0000\u01e2\u01e3\u0003\u009aM\u0000\u01e3\u01e5\u0003\u00b0"+ - "X\u0000\u01e4\u01e6\u0003Z-\u0000\u01e5\u01e4\u0001\u0000\u0000\u0000"+ - "\u01e5\u01e6\u0001\u0000\u0000\u0000\u01e6Y\u0001\u0000\u0000\u0000\u01e7"+ - "\u01ec\u0003\\.\u0000\u01e8\u01e9\u0005=\u0000\u0000\u01e9\u01eb\u0003"+ - "\\.\u0000\u01ea\u01e8\u0001\u0000\u0000\u0000\u01eb\u01ee\u0001\u0000"+ - "\u0000\u0000\u01ec\u01ea\u0001\u0000\u0000\u0000\u01ec\u01ed\u0001\u0000"+ - "\u0000\u0000\u01ed[\u0001\u0000\u0000\u0000\u01ee\u01ec\u0001\u0000\u0000"+ - "\u0000\u01ef\u01f0\u0003@ \u0000\u01f0\u01f1\u00058\u0000\u0000\u01f1"+ - "\u01f2\u0003\u00a6S\u0000\u01f2]\u0001\u0000\u0000\u0000\u01f3\u01f4\u0005"+ - "N\u0000\u0000\u01f4\u01f6\u0003\u00a0P\u0000\u01f5\u01f3\u0001\u0000\u0000"+ - "\u0000\u01f5\u01f6\u0001\u0000\u0000\u0000\u01f6_\u0001\u0000\u0000\u0000"+ - "\u01f7\u01f8\u0005\n\u0000\u0000\u01f8\u01f9\u0003\u009aM\u0000\u01f9"+ - "\u01fe\u0003\u00b0X\u0000\u01fa\u01fb\u0005=\u0000\u0000\u01fb\u01fd\u0003"+ - "\u00b0X\u0000\u01fc\u01fa\u0001\u0000\u0000\u0000\u01fd\u0200\u0001\u0000"+ - "\u0000\u0000\u01fe\u01fc\u0001\u0000\u0000\u0000\u01fe\u01ff\u0001\u0000"+ - "\u0000\u0000\u01ffa\u0001\u0000\u0000\u0000\u0200\u01fe\u0001\u0000\u0000"+ - "\u0000\u0201\u0202\u0005\u001d\u0000\u0000\u0202\u0203\u00036\u001b\u0000"+ - "\u0203c\u0001\u0000\u0000\u0000\u0204\u0205\u0005\u0006\u0000\u0000\u0205"+ - "\u0206\u0003f3\u0000\u0206e\u0001\u0000\u0000\u0000\u0207\u0208\u0005"+ - "b\u0000\u0000\u0208\u0209\u0003\u0004\u0002\u0000\u0209\u020a\u0005c\u0000"+ - "\u0000\u020ag\u0001\u0000\u0000\u0000\u020b\u020c\u0005#\u0000\u0000\u020c"+ - "\u020d\u0005\u0094\u0000\u0000\u020di\u0001\u0000\u0000\u0000\u020e\u020f"+ - "\u0005\u0005\u0000\u0000\u020f\u0212\u0003l6\u0000\u0210\u0211\u0005I"+ - "\u0000\u0000\u0211\u0213\u0003:\u001d\u0000\u0212\u0210\u0001\u0000\u0000"+ - "\u0000\u0212\u0213\u0001\u0000\u0000\u0000\u0213\u021d\u0001\u0000\u0000"+ - "\u0000\u0214\u0215\u0005N\u0000\u0000\u0215\u021a\u0003n7\u0000\u0216"+ - "\u0217\u0005=\u0000\u0000\u0217\u0219\u0003n7\u0000\u0218\u0216\u0001"+ - "\u0000\u0000\u0000\u0219\u021c\u0001\u0000\u0000\u0000\u021a\u0218\u0001"+ - "\u0000\u0000\u0000\u021a\u021b\u0001\u0000\u0000\u0000\u021b\u021e\u0001"+ - "\u0000\u0000\u0000\u021c\u021a\u0001\u0000\u0000\u0000\u021d\u0214\u0001"+ - "\u0000\u0000\u0000\u021d\u021e\u0001\u0000\u0000\u0000\u021ek\u0001\u0000"+ - "\u0000\u0000\u021f\u0220\u0007\u0004\u0000\u0000\u0220m\u0001\u0000\u0000"+ - "\u0000\u0221\u0222\u0003:\u001d\u0000\u0222\u0223\u00058\u0000\u0000\u0223"+ - "\u0225\u0001\u0000\u0000\u0000\u0224\u0221\u0001\u0000\u0000\u0000\u0224"+ - "\u0225\u0001\u0000\u0000\u0000\u0225\u0226\u0001\u0000\u0000\u0000\u0226"+ - "\u0227\u0003:\u001d\u0000\u0227o\u0001\u0000\u0000\u0000\u0228\u0229\u0005"+ - "\u000e\u0000\u0000\u0229\u022a\u0003\u00a6S\u0000\u022aq\u0001\u0000\u0000"+ - "\u0000\u022b\u022c\u0005\u0004\u0000\u0000\u022c\u022f\u00036\u001b\u0000"+ - "\u022d\u022e\u0005I\u0000\u0000\u022e\u0230\u00036\u001b\u0000\u022f\u022d"+ - "\u0001\u0000\u0000\u0000\u022f\u0230\u0001\u0000\u0000\u0000\u0230\u0236"+ - "\u0001\u0000\u0000\u0000\u0231\u0232\u0005\u008d\u0000\u0000\u0232\u0233"+ - "\u00036\u001b\u0000\u0233\u0234\u0005=\u0000\u0000\u0234\u0235\u00036"+ - "\u001b\u0000\u0235\u0237\u0001\u0000\u0000\u0000\u0236\u0231\u0001\u0000"+ - "\u0000\u0000\u0236\u0237\u0001\u0000\u0000\u0000\u0237s\u0001\u0000\u0000"+ - "\u0000\u0238\u0239\u0005\u0014\u0000\u0000\u0239\u023a\u0003v;\u0000\u023a"+ - "u\u0001\u0000\u0000\u0000\u023b\u023d\u0003x<\u0000\u023c\u023b\u0001"+ - "\u0000\u0000\u0000\u023d\u023e\u0001\u0000\u0000\u0000\u023e\u023c\u0001"+ - "\u0000\u0000\u0000\u023e\u023f\u0001\u0000\u0000\u0000\u023fw\u0001\u0000"+ - "\u0000\u0000\u0240\u0241\u0005b\u0000\u0000\u0241\u0242\u0003z=\u0000"+ - "\u0242\u0243\u0005c\u0000\u0000\u0243y\u0001\u0000\u0000\u0000\u0244\u0245"+ - "\u0006=\uffff\uffff\u0000\u0245\u0246\u0003|>\u0000\u0246\u024c\u0001"+ - "\u0000\u0000\u0000\u0247\u0248\n\u0001\u0000\u0000\u0248\u0249\u00052"+ - "\u0000\u0000\u0249\u024b\u0003|>\u0000\u024a\u0247\u0001\u0000\u0000\u0000"+ - "\u024b\u024e\u0001\u0000\u0000\u0000\u024c\u024a\u0001\u0000\u0000\u0000"+ - "\u024c\u024d\u0001\u0000\u0000\u0000\u024d{\u0001\u0000\u0000\u0000\u024e"+ - "\u024c\u0001\u0000\u0000\u0000\u024f\u0250\u0003\b\u0004\u0000\u0250}"+ - "\u0001\u0000\u0000\u0000\u0251\u0255\u0005\f\u0000\u0000\u0252\u0253\u0003"+ - "6\u001b\u0000\u0253\u0254\u00058\u0000\u0000\u0254\u0256\u0001\u0000\u0000"+ - "\u0000\u0255\u0252\u0001\u0000\u0000\u0000\u0255\u0256\u0001\u0000\u0000"+ - "\u0000\u0256\u0257\u0001\u0000\u0000\u0000\u0257\u0258\u0003\u00a6S\u0000"+ - "\u0258\u0259\u0005I\u0000\u0000\u0259\u025a\u0003\u0014\n\u0000\u025a"+ - "\u025b\u0003^/\u0000\u025b\u007f\u0001\u0000\u0000\u0000\u025c\u0260\u0005"+ - "\u0007\u0000\u0000\u025d\u025e\u00036\u001b\u0000\u025e\u025f\u00058\u0000"+ - "\u0000\u025f\u0261\u0001\u0000\u0000\u0000\u0260\u025d\u0001\u0000\u0000"+ - "\u0000\u0260\u0261\u0001\u0000\u0000\u0000\u0261\u0262\u0001\u0000\u0000"+ - "\u0000\u0262\u0263\u0003\u009aM\u0000\u0263\u0264\u0003^/\u0000\u0264"+ - "\u0081\u0001\u0000\u0000\u0000\u0265\u0266\u0005\u0016\u0000\u0000\u0266"+ - "\u0267\u0005w\u0000\u0000\u0267\u026a\u00032\u0019\u0000\u0268\u0269\u0005"+ - "9\u0000\u0000\u0269\u026b\u0003\u0010\b\u0000\u026a\u0268\u0001\u0000"+ - "\u0000\u0000\u026a\u026b\u0001\u0000\u0000\u0000\u026b\u0273\u0001\u0000"+ - "\u0000\u0000\u026c\u026d\u0005\u0017\u0000\u0000\u026d\u0270\u00032\u0019"+ - "\u0000\u026e\u026f\u00059\u0000\u0000\u026f\u0271\u0003\u0010\b\u0000"+ - "\u0270\u026e\u0001\u0000\u0000\u0000\u0270\u0271\u0001\u0000\u0000\u0000"+ - "\u0271\u0273\u0001\u0000\u0000\u0000\u0272\u0265\u0001\u0000\u0000\u0000"+ - "\u0272\u026c\u0001\u0000\u0000\u0000\u0273\u0083\u0001\u0000\u0000\u0000"+ - "\u0274\u0276\u0005\u0015\u0000\u0000\u0275\u0277\u0003@ \u0000\u0276\u0275"+ - "\u0001\u0000\u0000\u0000\u0276\u0277\u0001\u0000\u0000\u0000\u0277\u027b"+ - "\u0001\u0000\u0000\u0000\u0278\u027a\u0003\u0086C\u0000\u0279\u0278\u0001"+ - "\u0000\u0000\u0000\u027a\u027d\u0001\u0000\u0000\u0000\u027b\u0279\u0001"+ - "\u0000\u0000\u0000\u027b\u027c\u0001\u0000\u0000\u0000\u027c\u0085\u0001"+ - "\u0000\u0000\u0000\u027d\u027b\u0001\u0000\u0000\u0000\u027e\u027f\u0005"+ - "r\u0000\u0000\u027f\u0280\u00059\u0000\u0000\u0280\u028a\u00036\u001b"+ - "\u0000\u0281\u0282\u0005s\u0000\u0000\u0282\u0283\u00059\u0000\u0000\u0283"+ - "\u028a\u0003\u0010\b\u0000\u0284\u0285\u0005q\u0000\u0000\u0285\u0286"+ - "\u00059\u0000\u0000\u0286\u028a\u00036\u001b\u0000\u0287\u0288\u0005N"+ - "\u0000\u0000\u0288\u028a\u0003\u00a0P\u0000\u0289\u027e\u0001\u0000\u0000"+ - "\u0000\u0289\u0281\u0001\u0000\u0000\u0000\u0289\u0284\u0001\u0000\u0000"+ - "\u0000\u0289\u0287\u0001\u0000\u0000\u0000\u028a\u0087\u0001\u0000\u0000"+ - "\u0000\u028b\u028c\u0005\u001c\u0000\u0000\u028c\u028d\u0003\"\u0011\u0000"+ - "\u028d\u028e\u0005I\u0000\u0000\u028e\u028f\u0003>\u001f\u0000\u028f\u0089"+ - "\u0001\u0000\u0000\u0000\u0290\u0291\u0005 \u0000\u0000\u0291\u0292\u0003"+ - ">\u001f\u0000\u0292\u008b\u0001\u0000\u0000\u0000\u0293\u0294\u0005\""+ - "\u0000\u0000\u0294\u0295\u0003\u008eG\u0000\u0295\u0296\u0005<\u0000\u0000"+ - "\u0296\u008d\u0001\u0000\u0000\u0000\u0297\u0298\u0003@ \u0000\u0298\u0299"+ - "\u00058\u0000\u0000\u0299\u029a\u0003\u00a6S\u0000\u029a\u008f\u0001\u0000"+ - "\u0000\u0000\u029b\u029c\u0006H\uffff\uffff\u0000\u029c\u029d\u0005F\u0000"+ - "\u0000\u029d\u02b9\u0003\u0090H\b\u029e\u02b9\u0003\u0096K\u0000\u029f"+ - "\u02b9\u0003\u0092I\u0000\u02a0\u02a2\u0003\u0096K\u0000\u02a1\u02a3\u0005"+ - "F\u0000\u0000\u02a2\u02a1\u0001\u0000\u0000\u0000\u02a2\u02a3\u0001\u0000"+ - "\u0000\u0000\u02a3\u02a4\u0001\u0000\u0000\u0000\u02a4\u02a5\u0005B\u0000"+ - "\u0000\u02a5\u02a6\u0005b\u0000\u0000\u02a6\u02ab\u0003\u0096K\u0000\u02a7"+ - "\u02a8\u0005=\u0000\u0000\u02a8\u02aa\u0003\u0096K\u0000\u02a9\u02a7\u0001"+ - "\u0000\u0000\u0000\u02aa\u02ad\u0001\u0000\u0000\u0000\u02ab\u02a9\u0001"+ - "\u0000\u0000\u0000\u02ab\u02ac\u0001\u0000\u0000\u0000\u02ac\u02ae\u0001"+ - "\u0000\u0000\u0000\u02ad\u02ab\u0001\u0000\u0000\u0000\u02ae\u02af\u0005"+ - "c\u0000\u0000\u02af\u02b9\u0001\u0000\u0000\u0000\u02b0\u02b1\u0003\u0096"+ - "K\u0000\u02b1\u02b3\u0005C\u0000\u0000\u02b2\u02b4\u0005F\u0000\u0000"+ - "\u02b3\u02b2\u0001\u0000\u0000\u0000\u02b3\u02b4\u0001\u0000\u0000\u0000"+ - "\u02b4\u02b5\u0001\u0000\u0000\u0000\u02b5\u02b6\u0005G\u0000\u0000\u02b6"+ - "\u02b9\u0001\u0000\u0000\u0000\u02b7\u02b9\u0003\u0094J\u0000\u02b8\u029b"+ - "\u0001\u0000\u0000\u0000\u02b8\u029e\u0001\u0000\u0000\u0000\u02b8\u029f"+ - "\u0001\u0000\u0000\u0000\u02b8\u02a0\u0001\u0000\u0000\u0000\u02b8\u02b0"+ - "\u0001\u0000\u0000\u0000\u02b8\u02b7\u0001\u0000\u0000\u0000\u02b9\u02c2"+ - "\u0001\u0000\u0000\u0000\u02ba\u02bb\n\u0005\u0000\u0000\u02bb\u02bc\u0005"+ - "6\u0000\u0000\u02bc\u02c1\u0003\u0090H\u0006\u02bd\u02be\n\u0004\u0000"+ - "\u0000\u02be\u02bf\u0005J\u0000\u0000\u02bf\u02c1\u0003\u0090H\u0005\u02c0"+ - "\u02ba\u0001\u0000\u0000\u0000\u02c0\u02bd\u0001\u0000\u0000\u0000\u02c1"+ - "\u02c4\u0001\u0000\u0000\u0000\u02c2\u02c0\u0001\u0000\u0000\u0000\u02c2"+ - "\u02c3\u0001\u0000\u0000\u0000\u02c3\u0091\u0001\u0000\u0000\u0000\u02c4"+ - "\u02c2\u0001\u0000\u0000\u0000\u02c5\u02c7\u0003\u0096K\u0000\u02c6\u02c8"+ - "\u0005F\u0000\u0000\u02c7\u02c6\u0001\u0000\u0000\u0000\u02c7\u02c8\u0001"+ - "\u0000\u0000\u0000\u02c8\u02c9\u0001\u0000\u0000\u0000\u02c9\u02ca\u0005"+ - "E\u0000\u0000\u02ca\u02cb\u0003\u00b0X\u0000\u02cb\u02f4\u0001\u0000\u0000"+ - "\u0000\u02cc\u02ce\u0003\u0096K\u0000\u02cd\u02cf\u0005F\u0000\u0000\u02ce"+ - "\u02cd\u0001\u0000\u0000\u0000\u02ce\u02cf\u0001\u0000\u0000\u0000\u02cf"+ - "\u02d0\u0001\u0000\u0000\u0000\u02d0\u02d1\u0005L\u0000\u0000\u02d1\u02d2"+ - "\u0003\u00b0X\u0000\u02d2\u02f4\u0001\u0000\u0000\u0000\u02d3\u02d5\u0003"+ - "\u0096K\u0000\u02d4\u02d6\u0005F\u0000\u0000\u02d5\u02d4\u0001\u0000\u0000"+ - "\u0000\u02d5\u02d6\u0001\u0000\u0000\u0000\u02d6\u02d7\u0001\u0000\u0000"+ - "\u0000\u02d7\u02d8\u0005E\u0000\u0000\u02d8\u02d9\u0005b\u0000\u0000\u02d9"+ - "\u02de\u0003\u00b0X\u0000\u02da\u02db\u0005=\u0000\u0000\u02db\u02dd\u0003"+ - "\u00b0X\u0000\u02dc\u02da\u0001\u0000\u0000\u0000\u02dd\u02e0\u0001\u0000"+ - "\u0000\u0000\u02de\u02dc\u0001\u0000\u0000\u0000\u02de\u02df\u0001\u0000"+ - "\u0000\u0000\u02df\u02e1\u0001\u0000\u0000\u0000\u02e0\u02de\u0001\u0000"+ - "\u0000\u0000\u02e1\u02e2\u0005c\u0000\u0000\u02e2\u02f4\u0001\u0000\u0000"+ - "\u0000\u02e3\u02e5\u0003\u0096K\u0000\u02e4\u02e6\u0005F\u0000\u0000\u02e5"+ - "\u02e4\u0001\u0000\u0000\u0000\u02e5\u02e6\u0001\u0000\u0000\u0000\u02e6"+ - "\u02e7\u0001\u0000\u0000\u0000\u02e7\u02e8\u0005L\u0000\u0000\u02e8\u02e9"+ - "\u0005b\u0000\u0000\u02e9\u02ee\u0003\u00b0X\u0000\u02ea\u02eb\u0005="+ - "\u0000\u0000\u02eb\u02ed\u0003\u00b0X\u0000\u02ec\u02ea\u0001\u0000\u0000"+ - "\u0000\u02ed\u02f0\u0001\u0000\u0000\u0000\u02ee\u02ec\u0001\u0000\u0000"+ - "\u0000\u02ee\u02ef\u0001\u0000\u0000\u0000\u02ef\u02f1\u0001\u0000\u0000"+ - "\u0000\u02f0\u02ee\u0001\u0000\u0000\u0000\u02f1\u02f2\u0005c\u0000\u0000"+ - "\u02f2\u02f4\u0001\u0000\u0000\u0000\u02f3\u02c5\u0001\u0000\u0000\u0000"+ - "\u02f3\u02cc\u0001\u0000\u0000\u0000\u02f3\u02d3\u0001\u0000\u0000\u0000"+ - "\u02f3\u02e3\u0001\u0000\u0000\u0000\u02f4\u0093\u0001\u0000\u0000\u0000"+ - "\u02f5\u02f8\u00036\u001b\u0000\u02f6\u02f7\u0005:\u0000\u0000\u02f7\u02f9"+ - "\u0003\f\u0006\u0000\u02f8\u02f6\u0001\u0000\u0000\u0000\u02f8\u02f9\u0001"+ - "\u0000\u0000\u0000\u02f9\u02fa\u0001\u0000\u0000\u0000\u02fa\u02fb\u0005"+ - ";\u0000\u0000\u02fb\u02fc\u0003\u00a6S\u0000\u02fc\u0095\u0001\u0000\u0000"+ - "\u0000\u02fd\u0303\u0003\u0098L\u0000\u02fe\u02ff\u0003\u0098L\u0000\u02ff"+ - "\u0300\u0003\u00b2Y\u0000\u0300\u0301\u0003\u0098L\u0000\u0301\u0303\u0001"+ - "\u0000\u0000\u0000\u0302\u02fd\u0001\u0000\u0000\u0000\u0302\u02fe\u0001"+ - "\u0000\u0000\u0000\u0303\u0097\u0001\u0000\u0000\u0000\u0304\u0305\u0006"+ - "L\uffff\uffff\u0000\u0305\u0309\u0003\u009aM\u0000\u0306\u0307\u0007\u0005"+ - "\u0000\u0000\u0307\u0309\u0003\u0098L\u0003\u0308\u0304\u0001\u0000\u0000"+ - "\u0000\u0308\u0306\u0001\u0000\u0000\u0000\u0309\u0312\u0001\u0000\u0000"+ - "\u0000\u030a\u030b\n\u0002\u0000\u0000\u030b\u030c\u0007\u0006\u0000\u0000"+ - "\u030c\u0311\u0003\u0098L\u0003\u030d\u030e\n\u0001\u0000\u0000\u030e"+ - "\u030f\u0007\u0005\u0000\u0000\u030f\u0311\u0003\u0098L\u0002\u0310\u030a"+ - "\u0001\u0000\u0000\u0000\u0310\u030d\u0001\u0000\u0000\u0000\u0311\u0314"+ - "\u0001\u0000\u0000\u0000\u0312\u0310\u0001\u0000\u0000\u0000\u0312\u0313"+ - "\u0001\u0000\u0000\u0000\u0313\u0099\u0001\u0000\u0000\u0000\u0314\u0312"+ - "\u0001\u0000\u0000\u0000\u0315\u0316\u0006M\uffff\uffff\u0000\u0316\u031e"+ - "\u0003\u00a6S\u0000\u0317\u031e\u00036\u001b\u0000\u0318\u031e\u0003\u009c"+ - "N\u0000\u0319\u031a\u0005b\u0000\u0000\u031a\u031b\u0003\u0090H\u0000"+ - "\u031b\u031c\u0005c\u0000\u0000\u031c\u031e\u0001\u0000\u0000\u0000\u031d"+ - "\u0315\u0001\u0000\u0000\u0000\u031d\u0317\u0001\u0000\u0000\u0000\u031d"+ - "\u0318\u0001\u0000\u0000\u0000\u031d\u0319\u0001\u0000\u0000\u0000\u031e"+ - "\u0324\u0001\u0000\u0000\u0000\u031f\u0320\n\u0001\u0000\u0000\u0320\u0321"+ - "\u0005:\u0000\u0000\u0321\u0323\u0003\f\u0006\u0000\u0322\u031f\u0001"+ - "\u0000\u0000\u0000\u0323\u0326\u0001\u0000\u0000\u0000\u0324\u0322\u0001"+ - "\u0000\u0000\u0000\u0324\u0325\u0001\u0000\u0000\u0000\u0325\u009b\u0001"+ - "\u0000\u0000\u0000\u0326\u0324\u0001\u0000\u0000\u0000\u0327\u0328\u0003"+ - "\u009eO\u0000\u0328\u0336\u0005b\u0000\u0000\u0329\u0337\u0005X\u0000"+ - "\u0000\u032a\u032f\u0003\u0090H\u0000\u032b\u032c\u0005=\u0000\u0000\u032c"+ - "\u032e\u0003\u0090H\u0000\u032d\u032b\u0001\u0000\u0000\u0000\u032e\u0331"+ - "\u0001\u0000\u0000\u0000\u032f\u032d\u0001\u0000\u0000\u0000\u032f\u0330"+ - "\u0001\u0000\u0000\u0000\u0330\u0334\u0001\u0000\u0000\u0000\u0331\u032f"+ - "\u0001\u0000\u0000\u0000\u0332\u0333\u0005=\u0000\u0000\u0333\u0335\u0003"+ - "\u00a0P\u0000\u0334\u0332\u0001\u0000\u0000\u0000\u0334\u0335\u0001\u0000"+ - "\u0000\u0000\u0335\u0337\u0001\u0000\u0000\u0000\u0336\u0329\u0001\u0000"+ - "\u0000\u0000\u0336\u032a\u0001\u0000\u0000\u0000\u0336\u0337\u0001\u0000"+ - "\u0000\u0000\u0337\u0338\u0001\u0000\u0000\u0000\u0338\u0339\u0005c\u0000"+ - "\u0000\u0339\u009d\u0001\u0000\u0000\u0000\u033a\u033e\u0003H$\u0000\u033b"+ - "\u033e\u0005A\u0000\u0000\u033c\u033e\u0005D\u0000\u0000\u033d\u033a\u0001"+ - "\u0000\u0000\u0000\u033d\u033b\u0001\u0000\u0000\u0000\u033d\u033c\u0001"+ - "\u0000\u0000\u0000\u033e\u009f\u0001\u0000\u0000\u0000\u033f\u0348\u0005"+ - "[\u0000\u0000\u0340\u0345\u0003\u00a2Q\u0000\u0341\u0342\u0005=\u0000"+ - "\u0000\u0342\u0344\u0003\u00a2Q\u0000\u0343\u0341\u0001\u0000\u0000\u0000"+ - "\u0344\u0347\u0001\u0000\u0000\u0000\u0345\u0343\u0001\u0000\u0000\u0000"+ - "\u0345\u0346\u0001\u0000\u0000\u0000\u0346\u0349\u0001\u0000\u0000\u0000"+ - "\u0347\u0345\u0001\u0000\u0000\u0000\u0348\u0340\u0001\u0000\u0000\u0000"+ - "\u0348\u0349\u0001\u0000\u0000\u0000\u0349\u034a\u0001\u0000\u0000\u0000"+ - "\u034a\u034b\u0005\\\u0000\u0000\u034b\u00a1\u0001\u0000\u0000\u0000\u034c"+ - "\u034d\u0003\u00b0X\u0000\u034d\u034e\u0005;\u0000\u0000\u034e\u034f\u0003"+ - "\u00a4R\u0000\u034f\u00a3\u0001\u0000\u0000\u0000\u0350\u0353\u0003\u00a6"+ - "S\u0000\u0351\u0353\u0003\u00a0P\u0000\u0352\u0350\u0001\u0000\u0000\u0000"+ - "\u0352\u0351\u0001\u0000\u0000\u0000\u0353\u00a5\u0001\u0000\u0000\u0000"+ - "\u0354\u037f\u0005G\u0000\u0000\u0355\u0356\u0003\u00aeW\u0000\u0356\u0357"+ - "\u0005d\u0000\u0000\u0357\u037f\u0001\u0000\u0000\u0000\u0358\u037f\u0003"+ - "\u00acV\u0000\u0359\u037f\u0003\u00aeW\u0000\u035a\u037f\u0003\u00a8T"+ - "\u0000\u035b\u037f\u0003D\"\u0000\u035c\u037f\u0003\u00b0X\u0000\u035d"+ - "\u035e\u0005`\u0000\u0000\u035e\u0363\u0003\u00aaU\u0000\u035f\u0360\u0005"+ - "=\u0000\u0000\u0360\u0362\u0003\u00aaU\u0000\u0361\u035f\u0001\u0000\u0000"+ - "\u0000\u0362\u0365\u0001\u0000\u0000\u0000\u0363\u0361\u0001\u0000\u0000"+ - "\u0000\u0363\u0364\u0001\u0000\u0000\u0000\u0364\u0366\u0001\u0000\u0000"+ - "\u0000\u0365\u0363\u0001\u0000\u0000\u0000\u0366\u0367\u0005a\u0000\u0000"+ - "\u0367\u037f\u0001\u0000\u0000\u0000\u0368\u0369\u0005`\u0000\u0000\u0369"+ - "\u036e\u0003\u00a8T\u0000\u036a\u036b\u0005=\u0000\u0000\u036b\u036d\u0003"+ - "\u00a8T\u0000\u036c\u036a\u0001\u0000\u0000\u0000\u036d\u0370\u0001\u0000"+ - "\u0000\u0000\u036e\u036c\u0001\u0000\u0000\u0000\u036e\u036f\u0001\u0000"+ - "\u0000\u0000\u036f\u0371\u0001\u0000\u0000\u0000\u0370\u036e\u0001\u0000"+ - "\u0000\u0000\u0371\u0372\u0005a\u0000\u0000\u0372\u037f\u0001\u0000\u0000"+ - "\u0000\u0373\u0374\u0005`\u0000\u0000\u0374\u0379\u0003\u00b0X\u0000\u0375"+ - "\u0376\u0005=\u0000\u0000\u0376\u0378\u0003\u00b0X\u0000\u0377\u0375\u0001"+ - "\u0000\u0000\u0000\u0378\u037b\u0001\u0000\u0000\u0000\u0379\u0377\u0001"+ - "\u0000\u0000\u0000\u0379\u037a\u0001\u0000\u0000\u0000\u037a\u037c\u0001"+ - "\u0000\u0000\u0000\u037b\u0379\u0001\u0000\u0000\u0000\u037c\u037d\u0005"+ - "a\u0000\u0000\u037d\u037f\u0001\u0000\u0000\u0000\u037e\u0354\u0001\u0000"+ - "\u0000\u0000\u037e\u0355\u0001\u0000\u0000\u0000\u037e\u0358\u0001\u0000"+ - "\u0000\u0000\u037e\u0359\u0001\u0000\u0000\u0000\u037e\u035a\u0001\u0000"+ - "\u0000\u0000\u037e\u035b\u0001\u0000\u0000\u0000\u037e\u035c\u0001\u0000"+ - "\u0000\u0000\u037e\u035d\u0001\u0000\u0000\u0000\u037e\u0368\u0001\u0000"+ - "\u0000\u0000\u037e\u0373\u0001\u0000\u0000\u0000\u037f\u00a7\u0001\u0000"+ - "\u0000\u0000\u0380\u0381\u0007\u0007\u0000\u0000\u0381\u00a9\u0001\u0000"+ - "\u0000\u0000\u0382\u0385\u0003\u00acV\u0000\u0383\u0385\u0003\u00aeW\u0000"+ - "\u0384\u0382\u0001\u0000\u0000\u0000\u0384\u0383\u0001\u0000\u0000\u0000"+ - "\u0385\u00ab\u0001\u0000\u0000\u0000\u0386\u0388\u0007\u0005\u0000\u0000"+ - "\u0387\u0386\u0001\u0000\u0000\u0000\u0387\u0388\u0001\u0000\u0000\u0000"+ - "\u0388\u0389\u0001\u0000\u0000\u0000\u0389\u038a\u00055\u0000\u0000\u038a"+ - "\u00ad\u0001\u0000\u0000\u0000\u038b\u038d\u0007\u0005\u0000\u0000\u038c"+ - "\u038b\u0001\u0000\u0000\u0000\u038c\u038d\u0001\u0000\u0000\u0000\u038d"+ - "\u038e\u0001\u0000\u0000\u0000\u038e\u038f\u00054\u0000\u0000\u038f\u00af"+ - "\u0001\u0000\u0000\u0000\u0390\u0391\u00053\u0000\u0000\u0391\u00b1\u0001"+ - "\u0000\u0000\u0000\u0392\u0393\u0007\b\u0000\u0000\u0393\u00b3\u0001\u0000"+ - "\u0000\u0000\u0394\u0395\u0007\t\u0000\u0000\u0395\u0396\u0005{\u0000"+ - "\u0000\u0396\u0397\u0003\u00b6[\u0000\u0397\u0398\u0003\u00b8\\\u0000"+ - "\u0398\u00b5\u0001\u0000\u0000\u0000\u0399\u039a\u0004[\r\u0000\u039a"+ - "\u039c\u0003\"\u0011\u0000\u039b\u039d\u0005\u008d\u0000\u0000\u039c\u039b"+ - "\u0001\u0000\u0000\u0000\u039c\u039d\u0001\u0000\u0000\u0000\u039d\u039e"+ - "\u0001\u0000\u0000\u0000\u039e\u039f\u0005j\u0000\u0000\u039f\u03a2\u0001"+ - "\u0000\u0000\u0000\u03a0\u03a2\u0003\"\u0011\u0000\u03a1\u0399\u0001\u0000"+ - "\u0000\u0000\u03a1\u03a0\u0001\u0000\u0000\u0000\u03a2\u00b7\u0001\u0000"+ - "\u0000\u0000\u03a3\u03a4\u0005I\u0000\u0000\u03a4\u03a9\u0003\u0090H\u0000"+ - "\u03a5\u03a6\u0005=\u0000\u0000\u03a6\u03a8\u0003\u0090H\u0000\u03a7\u03a5"+ - "\u0001\u0000\u0000\u0000\u03a8\u03ab\u0001\u0000\u0000\u0000\u03a9\u03a7"+ - "\u0001\u0000\u0000\u0000\u03a9\u03aa\u0001\u0000\u0000\u0000\u03aa\u00b9"+ - "\u0001\u0000\u0000\u0000\u03ab\u03a9\u0001\u0000\u0000\u0000[\u00bd\u00ce"+ - "\u00d7\u00f1\u0100\u0106\u010f\u0115\u0122\u0126\u012b\u0133\u0141\u0151"+ - "\u0159\u015d\u0164\u016a\u016f\u0178\u017f\u0185\u018e\u0195\u019d\u01a5"+ - "\u01a9\u01ad\u01b2\u01bd\u01c2\u01c6\u01d4\u01df\u01e5\u01ec\u01f5\u01fe"+ - "\u0212\u021a\u021d\u0224\u022f\u0236\u023e\u024c\u0255\u0260\u026a\u0270"+ - "\u0272\u0276\u027b\u0289\u02a2\u02ab\u02b3\u02b8\u02c0\u02c2\u02c7\u02ce"+ - "\u02d5\u02de\u02e5\u02ee\u02f3\u02f8\u0302\u0308\u0310\u0312\u031d\u0324"+ - "\u032f\u0334\u0336\u033d\u0345\u0348\u0352\u0363\u036e\u0379\u037e\u0384"+ - "\u0387\u038c\u039c\u03a1\u03a9"; + "\u00ac\u00ae\u00b0\u00b2\u00b4\u00b6\u00b8\u00ba\u00bc\u00be\u00c0\u0000"+ + "\u000b\u0002\u000044kk\u0001\u0000ef\u0002\u000088??\u0002\u0000BBEE\u0002"+ + "\u0000))44\u0001\u0000WX\u0001\u0000Y[\u0002\u0000AANN\u0002\u0000PPR"+ + "V\u0002\u0000\u0018\u0018\u001a\u001b\u0004\u000044__ff\u008e\u008e\u0402"+ + "\u0000\u00c5\u0001\u0000\u0000\u0000\u0002\u00cb\u0001\u0000\u0000\u0000"+ + "\u0004\u00ce\u0001\u0000\u0000\u0000\u0006\u00df\u0001\u0000\u0000\u0000"+ + "\b\u00fb\u0001\u0000\u0000\u0000\n\u00fd\u0001\u0000\u0000\u0000\f\u0100"+ + "\u0001\u0000\u0000\u0000\u000e\u0102\u0001\u0000\u0000\u0000\u0010\u0105"+ + "\u0001\u0000\u0000\u0000\u0012\u0110\u0001\u0000\u0000\u0000\u0014\u0114"+ + "\u0001\u0000\u0000\u0000\u0016\u011c\u0001\u0000\u0000\u0000\u0018\u0121"+ + "\u0001\u0000\u0000\u0000\u001a\u0124\u0001\u0000\u0000\u0000\u001c\u0127"+ + "\u0001\u0000\u0000\u0000\u001e\u0135\u0001\u0000\u0000\u0000 \u0137\u0001"+ + "\u0000\u0000\u0000\"\u014b\u0001\u0000\u0000\u0000$\u014d\u0001\u0000"+ + "\u0000\u0000&\u014f\u0001\u0000\u0000\u0000(\u0151\u0001\u0000\u0000\u0000"+ + "*\u0153\u0001\u0000\u0000\u0000,\u0155\u0001\u0000\u0000\u0000.\u015e"+ + "\u0001\u0000\u0000\u00000\u0161\u0001\u0000\u0000\u00002\u0169\u0001\u0000"+ + "\u0000\u00004\u0171\u0001\u0000\u0000\u00006\u0182\u0001\u0000\u0000\u0000"+ + "8\u0184\u0001\u0000\u0000\u0000:\u0198\u0001\u0000\u0000\u0000<\u019a"+ + "\u0001\u0000\u0000\u0000>\u01a2\u0001\u0000\u0000\u0000@\u01aa\u0001\u0000"+ + "\u0000\u0000B\u01af\u0001\u0000\u0000\u0000D\u01b3\u0001\u0000\u0000\u0000"+ + "F\u01b7\u0001\u0000\u0000\u0000H\u01bc\u0001\u0000\u0000\u0000J\u01be"+ + "\u0001\u0000\u0000\u0000L\u01c1\u0001\u0000\u0000\u0000N\u01ca\u0001\u0000"+ + "\u0000\u0000P\u01d2\u0001\u0000\u0000\u0000R\u01d5\u0001\u0000\u0000\u0000"+ + "T\u01d8\u0001\u0000\u0000\u0000V\u01e9\u0001\u0000\u0000\u0000X\u01eb"+ + "\u0001\u0000\u0000\u0000Z\u01f1\u0001\u0000\u0000\u0000\\\u01f9\u0001"+ + "\u0000\u0000\u0000^\u01ff\u0001\u0000\u0000\u0000`\u0201\u0001\u0000\u0000"+ + "\u0000b\u020b\u0001\u0000\u0000\u0000d\u020e\u0001\u0000\u0000\u0000f"+ + "\u0211\u0001\u0000\u0000\u0000h\u0215\u0001\u0000\u0000\u0000j\u0218\u0001"+ + "\u0000\u0000\u0000l\u0229\u0001\u0000\u0000\u0000n\u022e\u0001\u0000\u0000"+ + "\u0000p\u0232\u0001\u0000\u0000\u0000r\u0235\u0001\u0000\u0000\u0000t"+ + "\u0242\u0001\u0000\u0000\u0000v\u0246\u0001\u0000\u0000\u0000x\u024a\u0001"+ + "\u0000\u0000\u0000z\u024e\u0001\u0000\u0000\u0000|\u0259\u0001\u0000\u0000"+ + "\u0000~\u025b\u0001\u0000\u0000\u0000\u0080\u0266\u0001\u0000\u0000\u0000"+ + "\u0082\u027c\u0001\u0000\u0000\u0000\u0084\u027e\u0001\u0000\u0000\u0000"+ + "\u0086\u0293\u0001\u0000\u0000\u0000\u0088\u0295\u0001\u0000\u0000\u0000"+ + "\u008a\u029a\u0001\u0000\u0000\u0000\u008c\u029d\u0001\u0000\u0000\u0000"+ + "\u008e\u02a1\u0001\u0000\u0000\u0000\u0090\u02c2\u0001\u0000\u0000\u0000"+ + "\u0092\u02fd\u0001\u0000\u0000\u0000\u0094\u02ff\u0001\u0000\u0000\u0000"+ + "\u0096\u030c\u0001\u0000\u0000\u0000\u0098\u0312\u0001\u0000\u0000\u0000"+ + "\u009a\u0327\u0001\u0000\u0000\u0000\u009c\u0331\u0001\u0000\u0000\u0000"+ + "\u009e\u0347\u0001\u0000\u0000\u0000\u00a0\u0349\u0001\u0000\u0000\u0000"+ + "\u00a2\u0356\u0001\u0000\u0000\u0000\u00a4\u035c\u0001\u0000\u0000\u0000"+ + "\u00a6\u0388\u0001\u0000\u0000\u0000\u00a8\u038a\u0001\u0000\u0000\u0000"+ + "\u00aa\u038e\u0001\u0000\u0000\u0000\u00ac\u0391\u0001\u0000\u0000\u0000"+ + "\u00ae\u0396\u0001\u0000\u0000\u0000\u00b0\u039a\u0001\u0000\u0000\u0000"+ + "\u00b2\u039c\u0001\u0000\u0000\u0000\u00b4\u039e\u0001\u0000\u0000\u0000"+ + "\u00b6\u03ab\u0001\u0000\u0000\u0000\u00b8\u03ad\u0001\u0000\u0000\u0000"+ + "\u00ba\u03b6\u0001\u0000\u0000\u0000\u00bc\u03c5\u0001\u0000\u0000\u0000"+ + "\u00be\u03c8\u0001\u0000\u0000\u0000\u00c0\u03d3\u0001\u0000\u0000\u0000"+ + "\u00c2\u00c4\u0003\u008cF\u0000\u00c3\u00c2\u0001\u0000\u0000\u0000\u00c4"+ + "\u00c7\u0001\u0000\u0000\u0000\u00c5\u00c3\u0001\u0000\u0000\u0000\u00c5"+ + "\u00c6\u0001\u0000\u0000\u0000\u00c6\u00c8\u0001\u0000\u0000\u0000\u00c7"+ + "\u00c5\u0001\u0000\u0000\u0000\u00c8\u00c9\u0003\u0002\u0001\u0000\u00c9"+ + "\u00ca\u0005\u0000\u0000\u0001\u00ca\u0001\u0001\u0000\u0000\u0000\u00cb"+ + "\u00cc\u0003\u0004\u0002\u0000\u00cc\u00cd\u0005\u0000\u0000\u0001\u00cd"+ + "\u0003\u0001\u0000\u0000\u0000\u00ce\u00cf\u0006\u0002\uffff\uffff\u0000"+ + "\u00cf\u00d0\u0003\u0006\u0003\u0000\u00d0\u00d6\u0001\u0000\u0000\u0000"+ + "\u00d1\u00d2\n\u0001\u0000\u0000\u00d2\u00d3\u00053\u0000\u0000\u00d3"+ + "\u00d5\u0003\b\u0004\u0000\u00d4\u00d1\u0001\u0000\u0000\u0000\u00d5\u00d8"+ + "\u0001\u0000\u0000\u0000\u00d6\u00d4\u0001\u0000\u0000\u0000\u00d6\u00d7"+ + "\u0001\u0000\u0000\u0000\u00d7\u0005\u0001\u0000\u0000\u0000\u00d8\u00d6"+ + "\u0001\u0000\u0000\u0000\u00d9\u00e0\u0003\u0018\f\u0000\u00da\u00e0\u0003"+ + "\u000e\u0007\u0000\u00db\u00e0\u0003h4\u0000\u00dc\u00e0\u0003\u001a\r"+ + "\u0000\u00dd\u00de\u0004\u0003\u0001\u0000\u00de\u00e0\u0003d2\u0000\u00df"+ + "\u00d9\u0001\u0000\u0000\u0000\u00df\u00da\u0001\u0000\u0000\u0000\u00df"+ + "\u00db\u0001\u0000\u0000\u0000\u00df\u00dc\u0001\u0000\u0000\u0000\u00df"+ + "\u00dd\u0001\u0000\u0000\u0000\u00e0\u0007\u0001\u0000\u0000\u0000\u00e1"+ + "\u00fc\u0003.\u0017\u0000\u00e2\u00fc\u0003\n\u0005\u0000\u00e3\u00fc"+ + "\u0003P(\u0000\u00e4\u00fc\u0003J%\u0000\u00e5\u00fc\u00030\u0018\u0000"+ + "\u00e6\u00fc\u0003L&\u0000\u00e7\u00fc\u0003R)\u0000\u00e8\u00fc\u0003"+ + "T*\u0000\u00e9\u00fc\u0003X,\u0000\u00ea\u00fc\u0003`0\u0000\u00eb\u00fc"+ + "\u0003j5\u0000\u00ec\u00fc\u0003b1\u0000\u00ed\u00fc\u0003\u00b4Z\u0000"+ + "\u00ee\u00fc\u0003r9\u0000\u00ef\u00fc\u0003\u0080@\u0000\u00f0\u00fc"+ + "\u0003p8\u0000\u00f1\u00fc\u0003t:\u0000\u00f2\u00fc\u0003~?\u0000\u00f3"+ + "\u00fc\u0003\u0082A\u0000\u00f4\u00fc\u0003\u0084B\u0000\u00f5\u00f6\u0004"+ + "\u0004\u0002\u0000\u00f6\u00fc\u0003\u0088D\u0000\u00f7\u00f8\u0004\u0004"+ + "\u0003\u0000\u00f8\u00fc\u0003\u008aE\u0000\u00f9\u00fa\u0004\u0004\u0004"+ + "\u0000\u00fa\u00fc\u0003\u00ba]\u0000\u00fb\u00e1\u0001\u0000\u0000\u0000"+ + "\u00fb\u00e2\u0001\u0000\u0000\u0000\u00fb\u00e3\u0001\u0000\u0000\u0000"+ + "\u00fb\u00e4\u0001\u0000\u0000\u0000\u00fb\u00e5\u0001\u0000\u0000\u0000"+ + "\u00fb\u00e6\u0001\u0000\u0000\u0000\u00fb\u00e7\u0001\u0000\u0000\u0000"+ + "\u00fb\u00e8\u0001\u0000\u0000\u0000\u00fb\u00e9\u0001\u0000\u0000\u0000"+ + "\u00fb\u00ea\u0001\u0000\u0000\u0000\u00fb\u00eb\u0001\u0000\u0000\u0000"+ + "\u00fb\u00ec\u0001\u0000\u0000\u0000\u00fb\u00ed\u0001\u0000\u0000\u0000"+ + "\u00fb\u00ee\u0001\u0000\u0000\u0000\u00fb\u00ef\u0001\u0000\u0000\u0000"+ + "\u00fb\u00f0\u0001\u0000\u0000\u0000\u00fb\u00f1\u0001\u0000\u0000\u0000"+ + "\u00fb\u00f2\u0001\u0000\u0000\u0000\u00fb\u00f3\u0001\u0000\u0000\u0000"+ + "\u00fb\u00f4\u0001\u0000\u0000\u0000\u00fb\u00f5\u0001\u0000\u0000\u0000"+ + "\u00fb\u00f7\u0001\u0000\u0000\u0000\u00fb\u00f9\u0001\u0000\u0000\u0000"+ + "\u00fc\t\u0001\u0000\u0000\u0000\u00fd\u00fe\u0005\u0011\u0000\u0000\u00fe"+ + "\u00ff\u0003\u0090H\u0000\u00ff\u000b\u0001\u0000\u0000\u0000\u0100\u0101"+ + "\u0003@ \u0000\u0101\r\u0001\u0000\u0000\u0000\u0102\u0103\u0005\r\u0000"+ + "\u0000\u0103\u0104\u0003\u0010\b\u0000\u0104\u000f\u0001\u0000\u0000\u0000"+ + "\u0105\u010a\u0003\u0012\t\u0000\u0106\u0107\u0005>\u0000\u0000\u0107"+ + "\u0109\u0003\u0012\t\u0000\u0108\u0106\u0001\u0000\u0000\u0000\u0109\u010c"+ + "\u0001\u0000\u0000\u0000\u010a\u0108\u0001\u0000\u0000\u0000\u010a\u010b"+ + "\u0001\u0000\u0000\u0000\u010b\u0011\u0001\u0000\u0000\u0000\u010c\u010a"+ + "\u0001\u0000\u0000\u0000\u010d\u010e\u00036\u001b\u0000\u010e\u010f\u0005"+ + "9\u0000\u0000\u010f\u0111\u0001\u0000\u0000\u0000\u0110\u010d\u0001\u0000"+ + "\u0000\u0000\u0110\u0111\u0001\u0000\u0000\u0000\u0111\u0112\u0001\u0000"+ + "\u0000\u0000\u0112\u0113\u0003\u0090H\u0000\u0113\u0013\u0001\u0000\u0000"+ + "\u0000\u0114\u0119\u0003\u0016\u000b\u0000\u0115\u0116\u0005>\u0000\u0000"+ + "\u0116\u0118\u0003\u0016\u000b\u0000\u0117\u0115\u0001\u0000\u0000\u0000"+ + "\u0118\u011b\u0001\u0000\u0000\u0000\u0119\u0117\u0001\u0000\u0000\u0000"+ + "\u0119\u011a\u0001\u0000\u0000\u0000\u011a\u0015\u0001\u0000\u0000\u0000"+ + "\u011b\u0119\u0001\u0000\u0000\u0000\u011c\u011f\u00036\u001b\u0000\u011d"+ + "\u011e\u00059\u0000\u0000\u011e\u0120\u0003\u0090H\u0000\u011f\u011d\u0001"+ + "\u0000\u0000\u0000\u011f\u0120\u0001\u0000\u0000\u0000\u0120\u0017\u0001"+ + "\u0000\u0000\u0000\u0121\u0122\u0005\u0012\u0000\u0000\u0122\u0123\u0003"+ + "\u001c\u000e\u0000\u0123\u0019\u0001\u0000\u0000\u0000\u0124\u0125\u0005"+ + "\u0013\u0000\u0000\u0125\u0126\u0003\u001c\u000e\u0000\u0126\u001b\u0001"+ + "\u0000\u0000\u0000\u0127\u012c\u0003\u001e\u000f\u0000\u0128\u0129\u0005"+ + ">\u0000\u0000\u0129\u012b\u0003\u001e\u000f\u0000\u012a\u0128\u0001\u0000"+ + "\u0000\u0000\u012b\u012e\u0001\u0000\u0000\u0000\u012c\u012a\u0001\u0000"+ + "\u0000\u0000\u012c\u012d\u0001\u0000\u0000\u0000\u012d\u0130\u0001\u0000"+ + "\u0000\u0000\u012e\u012c\u0001\u0000\u0000\u0000\u012f\u0131\u0003,\u0016"+ + "\u0000\u0130\u012f\u0001\u0000\u0000\u0000\u0130\u0131\u0001\u0000\u0000"+ + "\u0000\u0131\u001d\u0001\u0000\u0000\u0000\u0132\u0136\u0003\"\u0011\u0000"+ + "\u0133\u0134\u0004\u000f\u0005\u0000\u0134\u0136\u0003 \u0010\u0000\u0135"+ + "\u0132\u0001\u0000\u0000\u0000\u0135\u0133\u0001\u0000\u0000\u0000\u0136"+ + "\u001f\u0001\u0000\u0000\u0000\u0137\u0138\u0005c\u0000\u0000\u0138\u013d"+ + "\u0003\u0018\f\u0000\u0139\u013a\u00053\u0000\u0000\u013a\u013c\u0003"+ + "\b\u0004\u0000\u013b\u0139\u0001\u0000\u0000\u0000\u013c\u013f\u0001\u0000"+ + "\u0000\u0000\u013d\u013b\u0001\u0000\u0000\u0000\u013d\u013e\u0001\u0000"+ + "\u0000\u0000\u013e\u0140\u0001\u0000\u0000\u0000\u013f\u013d\u0001\u0000"+ + "\u0000\u0000\u0140\u0141\u0005d\u0000\u0000\u0141!\u0001\u0000\u0000\u0000"+ + "\u0142\u0143\u0003$\u0012\u0000\u0143\u0144\u0005<\u0000\u0000\u0144\u0145"+ + "\u0003(\u0014\u0000\u0145\u014c\u0001\u0000\u0000\u0000\u0146\u0147\u0003"+ + "(\u0014\u0000\u0147\u0148\u0005;\u0000\u0000\u0148\u0149\u0003&\u0013"+ + "\u0000\u0149\u014c\u0001\u0000\u0000\u0000\u014a\u014c\u0003*\u0015\u0000"+ + "\u014b\u0142\u0001\u0000\u0000\u0000\u014b\u0146\u0001\u0000\u0000\u0000"+ + "\u014b\u014a\u0001\u0000\u0000\u0000\u014c#\u0001\u0000\u0000\u0000\u014d"+ + "\u014e\u0005k\u0000\u0000\u014e%\u0001\u0000\u0000\u0000\u014f\u0150\u0005"+ + "k\u0000\u0000\u0150\'\u0001\u0000\u0000\u0000\u0151\u0152\u0005k\u0000"+ + "\u0000\u0152)\u0001\u0000\u0000\u0000\u0153\u0154\u0007\u0000\u0000\u0000"+ + "\u0154+\u0001\u0000\u0000\u0000\u0155\u0156\u0005j\u0000\u0000\u0156\u015b"+ + "\u0005k\u0000\u0000\u0157\u0158\u0005>\u0000\u0000\u0158\u015a\u0005k"+ + "\u0000\u0000\u0159\u0157\u0001\u0000\u0000\u0000\u015a\u015d\u0001\u0000"+ + "\u0000\u0000\u015b\u0159\u0001\u0000\u0000\u0000\u015b\u015c\u0001\u0000"+ + "\u0000\u0000\u015c-\u0001\u0000\u0000\u0000\u015d\u015b\u0001\u0000\u0000"+ + "\u0000\u015e\u015f\u0005\t\u0000\u0000\u015f\u0160\u0003\u0010\b\u0000"+ + "\u0160/\u0001\u0000\u0000\u0000\u0161\u0163\u0005\u0010\u0000\u0000\u0162"+ + "\u0164\u00032\u0019\u0000\u0163\u0162\u0001\u0000\u0000\u0000\u0163\u0164"+ + "\u0001\u0000\u0000\u0000\u0164\u0167\u0001\u0000\u0000\u0000\u0165\u0166"+ + "\u0005:\u0000\u0000\u0166\u0168\u0003\u0010\b\u0000\u0167\u0165\u0001"+ + "\u0000\u0000\u0000\u0167\u0168\u0001\u0000\u0000\u0000\u01681\u0001\u0000"+ + "\u0000\u0000\u0169\u016e\u00034\u001a\u0000\u016a\u016b\u0005>\u0000\u0000"+ + "\u016b\u016d\u00034\u001a\u0000\u016c\u016a\u0001\u0000\u0000\u0000\u016d"+ + "\u0170\u0001\u0000\u0000\u0000\u016e\u016c\u0001\u0000\u0000\u0000\u016e"+ + "\u016f\u0001\u0000\u0000\u0000\u016f3\u0001\u0000\u0000\u0000\u0170\u016e"+ + "\u0001\u0000\u0000\u0000\u0171\u0174\u0003\u0012\t\u0000\u0172\u0173\u0005"+ + "\u0011\u0000\u0000\u0173\u0175\u0003\u0090H\u0000\u0174\u0172\u0001\u0000"+ + "\u0000\u0000\u0174\u0175\u0001\u0000\u0000\u0000\u01755\u0001\u0000\u0000"+ + "\u0000\u0176\u0177\u0004\u001b\u0006\u0000\u0177\u0179\u0005a\u0000\u0000"+ + "\u0178\u017a\u0005e\u0000\u0000\u0179\u0178\u0001\u0000\u0000\u0000\u0179"+ + "\u017a\u0001\u0000\u0000\u0000\u017a\u017b\u0001\u0000\u0000\u0000\u017b"+ + "\u017c\u0005b\u0000\u0000\u017c\u017d\u0005@\u0000\u0000\u017d\u017e\u0005"+ + "a\u0000\u0000\u017e\u017f\u00038\u001c\u0000\u017f\u0180\u0005b\u0000"+ + "\u0000\u0180\u0183\u0001\u0000\u0000\u0000\u0181\u0183\u00038\u001c\u0000"+ + "\u0182\u0176\u0001\u0000\u0000\u0000\u0182\u0181\u0001\u0000\u0000\u0000"+ + "\u01837\u0001\u0000\u0000\u0000\u0184\u0189\u0003H$\u0000\u0185\u0186"+ + "\u0005@\u0000\u0000\u0186\u0188\u0003H$\u0000\u0187\u0185\u0001\u0000"+ + "\u0000\u0000\u0188\u018b\u0001\u0000\u0000\u0000\u0189\u0187\u0001\u0000"+ + "\u0000\u0000\u0189\u018a\u0001\u0000\u0000\u0000\u018a9\u0001\u0000\u0000"+ + "\u0000\u018b\u0189\u0001\u0000\u0000\u0000\u018c\u018d\u0004\u001d\u0007"+ + "\u0000\u018d\u018f\u0005a\u0000\u0000\u018e\u0190\u0005\u008a\u0000\u0000"+ + "\u018f\u018e\u0001\u0000\u0000\u0000\u018f\u0190\u0001\u0000\u0000\u0000"+ + "\u0190\u0191\u0001\u0000\u0000\u0000\u0191\u0192\u0005b\u0000\u0000\u0192"+ + "\u0193\u0005@\u0000\u0000\u0193\u0194\u0005a\u0000\u0000\u0194\u0195\u0003"+ + "<\u001e\u0000\u0195\u0196\u0005b\u0000\u0000\u0196\u0199\u0001\u0000\u0000"+ + "\u0000\u0197\u0199\u0003<\u001e\u0000\u0198\u018c\u0001\u0000\u0000\u0000"+ + "\u0198\u0197\u0001\u0000\u0000\u0000\u0199;\u0001\u0000\u0000\u0000\u019a"+ + "\u019f\u0003B!\u0000\u019b\u019c\u0005@\u0000\u0000\u019c\u019e\u0003"+ + "B!\u0000\u019d\u019b\u0001\u0000\u0000\u0000\u019e\u01a1\u0001\u0000\u0000"+ + "\u0000\u019f\u019d\u0001\u0000\u0000\u0000\u019f\u01a0\u0001\u0000\u0000"+ + "\u0000\u01a0=\u0001\u0000\u0000\u0000\u01a1\u019f\u0001\u0000\u0000\u0000"+ + "\u01a2\u01a7\u0003:\u001d\u0000\u01a3\u01a4\u0005>\u0000\u0000\u01a4\u01a6"+ + "\u0003:\u001d\u0000\u01a5\u01a3\u0001\u0000\u0000\u0000\u01a6\u01a9\u0001"+ + "\u0000\u0000\u0000\u01a7\u01a5\u0001\u0000\u0000\u0000\u01a7\u01a8\u0001"+ + "\u0000\u0000\u0000\u01a8?\u0001\u0000\u0000\u0000\u01a9\u01a7\u0001\u0000"+ + "\u0000\u0000\u01aa\u01ab\u0007\u0001\u0000\u0000\u01abA\u0001\u0000\u0000"+ + "\u0000\u01ac\u01b0\u0005\u008a\u0000\u0000\u01ad\u01b0\u0003D\"\u0000"+ + "\u01ae\u01b0\u0003F#\u0000\u01af\u01ac\u0001\u0000\u0000\u0000\u01af\u01ad"+ + "\u0001\u0000\u0000\u0000\u01af\u01ae\u0001\u0000\u0000\u0000\u01b0C\u0001"+ + "\u0000\u0000\u0000\u01b1\u01b4\u0005L\u0000\u0000\u01b2\u01b4\u0005_\u0000"+ + "\u0000\u01b3\u01b1\u0001\u0000\u0000\u0000\u01b3\u01b2\u0001\u0000\u0000"+ + "\u0000\u01b4E\u0001\u0000\u0000\u0000\u01b5\u01b8\u0005^\u0000\u0000\u01b6"+ + "\u01b8\u0005`\u0000\u0000\u01b7\u01b5\u0001\u0000\u0000\u0000\u01b7\u01b6"+ + "\u0001\u0000\u0000\u0000\u01b8G\u0001\u0000\u0000\u0000\u01b9\u01bd\u0003"+ + "@ \u0000\u01ba\u01bd\u0003D\"\u0000\u01bb\u01bd\u0003F#\u0000\u01bc\u01b9"+ + "\u0001\u0000\u0000\u0000\u01bc\u01ba\u0001\u0000\u0000\u0000\u01bc\u01bb"+ + "\u0001\u0000\u0000\u0000\u01bdI\u0001\u0000\u0000\u0000\u01be\u01bf\u0005"+ + "\u000b\u0000\u0000\u01bf\u01c0\u0003\u00a6S\u0000\u01c0K\u0001\u0000\u0000"+ + "\u0000\u01c1\u01c2\u0005\u000f\u0000\u0000\u01c2\u01c7\u0003N\'\u0000"+ + "\u01c3\u01c4\u0005>\u0000\u0000\u01c4\u01c6\u0003N\'\u0000\u01c5\u01c3"+ + "\u0001\u0000\u0000\u0000\u01c6\u01c9\u0001\u0000\u0000\u0000\u01c7\u01c5"+ + "\u0001\u0000\u0000\u0000\u01c7\u01c8\u0001\u0000\u0000\u0000\u01c8M\u0001"+ + "\u0000\u0000\u0000\u01c9\u01c7\u0001\u0000\u0000\u0000\u01ca\u01cc\u0003"+ + "\u0090H\u0000\u01cb\u01cd\u0007\u0002\u0000\u0000\u01cc\u01cb\u0001\u0000"+ + "\u0000\u0000\u01cc\u01cd\u0001\u0000\u0000\u0000\u01cd\u01d0\u0001\u0000"+ + "\u0000\u0000\u01ce\u01cf\u0005I\u0000\u0000\u01cf\u01d1\u0007\u0003\u0000"+ + "\u0000\u01d0\u01ce\u0001\u0000\u0000\u0000\u01d0\u01d1\u0001\u0000\u0000"+ + "\u0000\u01d1O\u0001\u0000\u0000\u0000\u01d2\u01d3\u0005\u001f\u0000\u0000"+ + "\u01d3\u01d4\u0003>\u001f\u0000\u01d4Q\u0001\u0000\u0000\u0000\u01d5\u01d6"+ + "\u0005\u001e\u0000\u0000\u01d6\u01d7\u0003>\u001f\u0000\u01d7S\u0001\u0000"+ + "\u0000\u0000\u01d8\u01d9\u0005\"\u0000\u0000\u01d9\u01de\u0003V+\u0000"+ + "\u01da\u01db\u0005>\u0000\u0000\u01db\u01dd\u0003V+\u0000\u01dc\u01da"+ + "\u0001\u0000\u0000\u0000\u01dd\u01e0\u0001\u0000\u0000\u0000\u01de\u01dc"+ + "\u0001\u0000\u0000\u0000\u01de\u01df\u0001\u0000\u0000\u0000\u01dfU\u0001"+ + "\u0000\u0000\u0000\u01e0\u01de\u0001\u0000\u0000\u0000\u01e1\u01e2\u0003"+ + ":\u001d\u0000\u01e2\u01e3\u0005\u0096\u0000\u0000\u01e3\u01e4\u0003:\u001d"+ + "\u0000\u01e4\u01ea\u0001\u0000\u0000\u0000\u01e5\u01e6\u0003:\u001d\u0000"+ + "\u01e6\u01e7\u00059\u0000\u0000\u01e7\u01e8\u0003:\u001d\u0000\u01e8\u01ea"+ + "\u0001\u0000\u0000\u0000\u01e9\u01e1\u0001\u0000\u0000\u0000\u01e9\u01e5"+ + "\u0001\u0000\u0000\u0000\u01eaW\u0001\u0000\u0000\u0000\u01eb\u01ec\u0005"+ + "\b\u0000\u0000\u01ec\u01ed\u0003\u009aM\u0000\u01ed\u01ef\u0003\u00b0"+ + "X\u0000\u01ee\u01f0\u0003Z-\u0000\u01ef\u01ee\u0001\u0000\u0000\u0000"+ + "\u01ef\u01f0\u0001\u0000\u0000\u0000\u01f0Y\u0001\u0000\u0000\u0000\u01f1"+ + "\u01f6\u0003\\.\u0000\u01f2\u01f3\u0005>\u0000\u0000\u01f3\u01f5\u0003"+ + "\\.\u0000\u01f4\u01f2\u0001\u0000\u0000\u0000\u01f5\u01f8\u0001\u0000"+ + "\u0000\u0000\u01f6\u01f4\u0001\u0000\u0000\u0000\u01f6\u01f7\u0001\u0000"+ + "\u0000\u0000\u01f7[\u0001\u0000\u0000\u0000\u01f8\u01f6\u0001\u0000\u0000"+ + "\u0000\u01f9\u01fa\u0003@ \u0000\u01fa\u01fb\u00059\u0000\u0000\u01fb"+ + "\u01fc\u0003\u00a6S\u0000\u01fc]\u0001\u0000\u0000\u0000\u01fd\u01fe\u0005"+ + "O\u0000\u0000\u01fe\u0200\u0003\u00a0P\u0000\u01ff\u01fd\u0001\u0000\u0000"+ + "\u0000\u01ff\u0200\u0001\u0000\u0000\u0000\u0200_\u0001\u0000\u0000\u0000"+ + "\u0201\u0202\u0005\n\u0000\u0000\u0202\u0203\u0003\u009aM\u0000\u0203"+ + "\u0208\u0003\u00b0X\u0000\u0204\u0205\u0005>\u0000\u0000\u0205\u0207\u0003"+ + "\u00b0X\u0000\u0206\u0204\u0001\u0000\u0000\u0000\u0207\u020a\u0001\u0000"+ + "\u0000\u0000\u0208\u0206\u0001\u0000\u0000\u0000\u0208\u0209\u0001\u0000"+ + "\u0000\u0000\u0209a\u0001\u0000\u0000\u0000\u020a\u0208\u0001\u0000\u0000"+ + "\u0000\u020b\u020c\u0005\u001d\u0000\u0000\u020c\u020d\u00036\u001b\u0000"+ + "\u020dc\u0001\u0000\u0000\u0000\u020e\u020f\u0005\u0006\u0000\u0000\u020f"+ + "\u0210\u0003f3\u0000\u0210e\u0001\u0000\u0000\u0000\u0211\u0212\u0005"+ + "c\u0000\u0000\u0212\u0213\u0003\u0004\u0002\u0000\u0213\u0214\u0005d\u0000"+ + "\u0000\u0214g\u0001\u0000\u0000\u0000\u0215\u0216\u0005$\u0000\u0000\u0216"+ + "\u0217\u0005\u009d\u0000\u0000\u0217i\u0001\u0000\u0000\u0000\u0218\u0219"+ + "\u0005\u0005\u0000\u0000\u0219\u021c\u0003l6\u0000\u021a\u021b\u0005J"+ + "\u0000\u0000\u021b\u021d\u0003:\u001d\u0000\u021c\u021a\u0001\u0000\u0000"+ + "\u0000\u021c\u021d\u0001\u0000\u0000\u0000\u021d\u0227\u0001\u0000\u0000"+ + "\u0000\u021e\u021f\u0005O\u0000\u0000\u021f\u0224\u0003n7\u0000\u0220"+ + "\u0221\u0005>\u0000\u0000\u0221\u0223\u0003n7\u0000\u0222\u0220\u0001"+ + "\u0000\u0000\u0000\u0223\u0226\u0001\u0000\u0000\u0000\u0224\u0222\u0001"+ + "\u0000\u0000\u0000\u0224\u0225\u0001\u0000\u0000\u0000\u0225\u0228\u0001"+ + "\u0000\u0000\u0000\u0226\u0224\u0001\u0000\u0000\u0000\u0227\u021e\u0001"+ + "\u0000\u0000\u0000\u0227\u0228\u0001\u0000\u0000\u0000\u0228k\u0001\u0000"+ + "\u0000\u0000\u0229\u022a\u0007\u0004\u0000\u0000\u022am\u0001\u0000\u0000"+ + "\u0000\u022b\u022c\u0003:\u001d\u0000\u022c\u022d\u00059\u0000\u0000\u022d"+ + "\u022f\u0001\u0000\u0000\u0000\u022e\u022b\u0001\u0000\u0000\u0000\u022e"+ + "\u022f\u0001\u0000\u0000\u0000\u022f\u0230\u0001\u0000\u0000\u0000\u0230"+ + "\u0231\u0003:\u001d\u0000\u0231o\u0001\u0000\u0000\u0000\u0232\u0233\u0005"+ + "\u000e\u0000\u0000\u0233\u0234\u0003\u00a6S\u0000\u0234q\u0001\u0000\u0000"+ + "\u0000\u0235\u0236\u0005\u0004\u0000\u0000\u0236\u0239\u00036\u001b\u0000"+ + "\u0237\u0238\u0005J\u0000\u0000\u0238\u023a\u00036\u001b\u0000\u0239\u0237"+ + "\u0001\u0000\u0000\u0000\u0239\u023a\u0001\u0000\u0000\u0000\u023a\u0240"+ + "\u0001\u0000\u0000\u0000\u023b\u023c\u0005\u0096\u0000\u0000\u023c\u023d"+ + "\u00036\u001b\u0000\u023d\u023e\u0005>\u0000\u0000\u023e\u023f\u00036"+ + "\u001b\u0000\u023f\u0241\u0001\u0000\u0000\u0000\u0240\u023b\u0001\u0000"+ + "\u0000\u0000\u0240\u0241\u0001\u0000\u0000\u0000\u0241s\u0001\u0000\u0000"+ + "\u0000\u0242\u0243\u0005\u0014\u0000\u0000\u0243\u0244\u0003v;\u0000\u0244"+ + "u\u0001\u0000\u0000\u0000\u0245\u0247\u0003x<\u0000\u0246\u0245\u0001"+ + "\u0000\u0000\u0000\u0247\u0248\u0001\u0000\u0000\u0000\u0248\u0246\u0001"+ + "\u0000\u0000\u0000\u0248\u0249\u0001\u0000\u0000\u0000\u0249w\u0001\u0000"+ + "\u0000\u0000\u024a\u024b\u0005c\u0000\u0000\u024b\u024c\u0003z=\u0000"+ + "\u024c\u024d\u0005d\u0000\u0000\u024dy\u0001\u0000\u0000\u0000\u024e\u024f"+ + "\u0006=\uffff\uffff\u0000\u024f\u0250\u0003|>\u0000\u0250\u0256\u0001"+ + "\u0000\u0000\u0000\u0251\u0252\n\u0001\u0000\u0000\u0252\u0253\u00053"+ + "\u0000\u0000\u0253\u0255\u0003|>\u0000\u0254\u0251\u0001\u0000\u0000\u0000"+ + "\u0255\u0258\u0001\u0000\u0000\u0000\u0256\u0254\u0001\u0000\u0000\u0000"+ + "\u0256\u0257\u0001\u0000\u0000\u0000\u0257{\u0001\u0000\u0000\u0000\u0258"+ + "\u0256\u0001\u0000\u0000\u0000\u0259\u025a\u0003\b\u0004\u0000\u025a}"+ + "\u0001\u0000\u0000\u0000\u025b\u025f\u0005\f\u0000\u0000\u025c\u025d\u0003"+ + "6\u001b\u0000\u025d\u025e\u00059\u0000\u0000\u025e\u0260\u0001\u0000\u0000"+ + "\u0000\u025f\u025c\u0001\u0000\u0000\u0000\u025f\u0260\u0001\u0000\u0000"+ + "\u0000\u0260\u0261\u0001\u0000\u0000\u0000\u0261\u0262\u0003\u00a6S\u0000"+ + "\u0262\u0263\u0005J\u0000\u0000\u0263\u0264\u0003\u0014\n\u0000\u0264"+ + "\u0265\u0003^/\u0000\u0265\u007f\u0001\u0000\u0000\u0000\u0266\u026a\u0005"+ + "\u0007\u0000\u0000\u0267\u0268\u00036\u001b\u0000\u0268\u0269\u00059\u0000"+ + "\u0000\u0269\u026b\u0001\u0000\u0000\u0000\u026a\u0267\u0001\u0000\u0000"+ + "\u0000\u026a\u026b\u0001\u0000\u0000\u0000\u026b\u026c\u0001\u0000\u0000"+ + "\u0000\u026c\u026d\u0003\u009aM\u0000\u026d\u026e\u0003^/\u0000\u026e"+ + "\u0081\u0001\u0000\u0000\u0000\u026f\u0270\u0005\u0016\u0000\u0000\u0270"+ + "\u0271\u0005x\u0000\u0000\u0271\u0274\u00032\u0019\u0000\u0272\u0273\u0005"+ + ":\u0000\u0000\u0273\u0275\u0003\u0010\b\u0000\u0274\u0272\u0001\u0000"+ + "\u0000\u0000\u0274\u0275\u0001\u0000\u0000\u0000\u0275\u027d\u0001\u0000"+ + "\u0000\u0000\u0276\u0277\u0005\u0017\u0000\u0000\u0277\u027a\u00032\u0019"+ + "\u0000\u0278\u0279\u0005:\u0000\u0000\u0279\u027b\u0003\u0010\b\u0000"+ + "\u027a\u0278\u0001\u0000\u0000\u0000\u027a\u027b\u0001\u0000\u0000\u0000"+ + "\u027b\u027d\u0001\u0000\u0000\u0000\u027c\u026f\u0001\u0000\u0000\u0000"+ + "\u027c\u0276\u0001\u0000\u0000\u0000\u027d\u0083\u0001\u0000\u0000\u0000"+ + "\u027e\u0280\u0005\u0015\u0000\u0000\u027f\u0281\u0003@ \u0000\u0280\u027f"+ + "\u0001\u0000\u0000\u0000\u0280\u0281\u0001\u0000\u0000\u0000\u0281\u0285"+ + "\u0001\u0000\u0000\u0000\u0282\u0284\u0003\u0086C\u0000\u0283\u0282\u0001"+ + "\u0000\u0000\u0000\u0284\u0287\u0001\u0000\u0000\u0000\u0285\u0283\u0001"+ + "\u0000\u0000\u0000\u0285\u0286\u0001\u0000\u0000\u0000\u0286\u0085\u0001"+ + "\u0000\u0000\u0000\u0287\u0285\u0001\u0000\u0000\u0000\u0288\u0289\u0005"+ + "s\u0000\u0000\u0289\u028a\u0005:\u0000\u0000\u028a\u0294\u00036\u001b"+ + "\u0000\u028b\u028c\u0005t\u0000\u0000\u028c\u028d\u0005:\u0000\u0000\u028d"+ + "\u0294\u0003\u0010\b\u0000\u028e\u028f\u0005r\u0000\u0000\u028f\u0290"+ + "\u0005:\u0000\u0000\u0290\u0294\u00036\u001b\u0000\u0291\u0292\u0005O"+ + "\u0000\u0000\u0292\u0294\u0003\u00a0P\u0000\u0293\u0288\u0001\u0000\u0000"+ + "\u0000\u0293\u028b\u0001\u0000\u0000\u0000\u0293\u028e\u0001\u0000\u0000"+ + "\u0000\u0293\u0291\u0001\u0000\u0000\u0000\u0294\u0087\u0001\u0000\u0000"+ + "\u0000\u0295\u0296\u0005\u001c\u0000\u0000\u0296\u0297\u0003\"\u0011\u0000"+ + "\u0297\u0298\u0005J\u0000\u0000\u0298\u0299\u0003>\u001f\u0000\u0299\u0089"+ + "\u0001\u0000\u0000\u0000\u029a\u029b\u0005 \u0000\u0000\u029b\u029c\u0003"+ + ">\u001f\u0000\u029c\u008b\u0001\u0000\u0000\u0000\u029d\u029e\u0005#\u0000"+ + "\u0000\u029e\u029f\u0003\u008eG\u0000\u029f\u02a0\u0005=\u0000\u0000\u02a0"+ + "\u008d\u0001\u0000\u0000\u0000\u02a1\u02a2\u0003@ \u0000\u02a2\u02a3\u0005"+ + "9\u0000\u0000\u02a3\u02a4\u0003\u00a6S\u0000\u02a4\u008f\u0001\u0000\u0000"+ + "\u0000\u02a5\u02a6\u0006H\uffff\uffff\u0000\u02a6\u02a7\u0005G\u0000\u0000"+ + "\u02a7\u02c3\u0003\u0090H\b\u02a8\u02c3\u0003\u0096K\u0000\u02a9\u02c3"+ + "\u0003\u0092I\u0000\u02aa\u02ac\u0003\u0096K\u0000\u02ab\u02ad\u0005G"+ + "\u0000\u0000\u02ac\u02ab\u0001\u0000\u0000\u0000\u02ac\u02ad\u0001\u0000"+ + "\u0000\u0000\u02ad\u02ae\u0001\u0000\u0000\u0000\u02ae\u02af\u0005C\u0000"+ + "\u0000\u02af\u02b0\u0005c\u0000\u0000\u02b0\u02b5\u0003\u0096K\u0000\u02b1"+ + "\u02b2\u0005>\u0000\u0000\u02b2\u02b4\u0003\u0096K\u0000\u02b3\u02b1\u0001"+ + "\u0000\u0000\u0000\u02b4\u02b7\u0001\u0000\u0000\u0000\u02b5\u02b3\u0001"+ + "\u0000\u0000\u0000\u02b5\u02b6\u0001\u0000\u0000\u0000\u02b6\u02b8\u0001"+ + "\u0000\u0000\u0000\u02b7\u02b5\u0001\u0000\u0000\u0000\u02b8\u02b9\u0005"+ + "d\u0000\u0000\u02b9\u02c3\u0001\u0000\u0000\u0000\u02ba\u02bb\u0003\u0096"+ + "K\u0000\u02bb\u02bd\u0005D\u0000\u0000\u02bc\u02be\u0005G\u0000\u0000"+ + "\u02bd\u02bc\u0001\u0000\u0000\u0000\u02bd\u02be\u0001\u0000\u0000\u0000"+ + "\u02be\u02bf\u0001\u0000\u0000\u0000\u02bf\u02c0\u0005H\u0000\u0000\u02c0"+ + "\u02c3\u0001\u0000\u0000\u0000\u02c1\u02c3\u0003\u0094J\u0000\u02c2\u02a5"+ + "\u0001\u0000\u0000\u0000\u02c2\u02a8\u0001\u0000\u0000\u0000\u02c2\u02a9"+ + "\u0001\u0000\u0000\u0000\u02c2\u02aa\u0001\u0000\u0000\u0000\u02c2\u02ba"+ + "\u0001\u0000\u0000\u0000\u02c2\u02c1\u0001\u0000\u0000\u0000\u02c3\u02cc"+ + "\u0001\u0000\u0000\u0000\u02c4\u02c5\n\u0005\u0000\u0000\u02c5\u02c6\u0005"+ + "7\u0000\u0000\u02c6\u02cb\u0003\u0090H\u0006\u02c7\u02c8\n\u0004\u0000"+ + "\u0000\u02c8\u02c9\u0005K\u0000\u0000\u02c9\u02cb\u0003\u0090H\u0005\u02ca"+ + "\u02c4\u0001\u0000\u0000\u0000\u02ca\u02c7\u0001\u0000\u0000\u0000\u02cb"+ + "\u02ce\u0001\u0000\u0000\u0000\u02cc\u02ca\u0001\u0000\u0000\u0000\u02cc"+ + "\u02cd\u0001\u0000\u0000\u0000\u02cd\u0091\u0001\u0000\u0000\u0000\u02ce"+ + "\u02cc\u0001\u0000\u0000\u0000\u02cf\u02d1\u0003\u0096K\u0000\u02d0\u02d2"+ + "\u0005G\u0000\u0000\u02d1\u02d0\u0001\u0000\u0000\u0000\u02d1\u02d2\u0001"+ + "\u0000\u0000\u0000\u02d2\u02d3\u0001\u0000\u0000\u0000\u02d3\u02d4\u0005"+ + "F\u0000\u0000\u02d4\u02d5\u0003\u00b0X\u0000\u02d5\u02fe\u0001\u0000\u0000"+ + "\u0000\u02d6\u02d8\u0003\u0096K\u0000\u02d7\u02d9\u0005G\u0000\u0000\u02d8"+ + "\u02d7\u0001\u0000\u0000\u0000\u02d8\u02d9\u0001\u0000\u0000\u0000\u02d9"+ + "\u02da\u0001\u0000\u0000\u0000\u02da\u02db\u0005M\u0000\u0000\u02db\u02dc"+ + "\u0003\u00b0X\u0000\u02dc\u02fe\u0001\u0000\u0000\u0000\u02dd\u02df\u0003"+ + "\u0096K\u0000\u02de\u02e0\u0005G\u0000\u0000\u02df\u02de\u0001\u0000\u0000"+ + "\u0000\u02df\u02e0\u0001\u0000\u0000\u0000\u02e0\u02e1\u0001\u0000\u0000"+ + "\u0000\u02e1\u02e2\u0005F\u0000\u0000\u02e2\u02e3\u0005c\u0000\u0000\u02e3"+ + "\u02e8\u0003\u00b0X\u0000\u02e4\u02e5\u0005>\u0000\u0000\u02e5\u02e7\u0003"+ + "\u00b0X\u0000\u02e6\u02e4\u0001\u0000\u0000\u0000\u02e7\u02ea\u0001\u0000"+ + "\u0000\u0000\u02e8\u02e6\u0001\u0000\u0000\u0000\u02e8\u02e9\u0001\u0000"+ + "\u0000\u0000\u02e9\u02eb\u0001\u0000\u0000\u0000\u02ea\u02e8\u0001\u0000"+ + "\u0000\u0000\u02eb\u02ec\u0005d\u0000\u0000\u02ec\u02fe\u0001\u0000\u0000"+ + "\u0000\u02ed\u02ef\u0003\u0096K\u0000\u02ee\u02f0\u0005G\u0000\u0000\u02ef"+ + "\u02ee\u0001\u0000\u0000\u0000\u02ef\u02f0\u0001\u0000\u0000\u0000\u02f0"+ + "\u02f1\u0001\u0000\u0000\u0000\u02f1\u02f2\u0005M\u0000\u0000\u02f2\u02f3"+ + "\u0005c\u0000\u0000\u02f3\u02f8\u0003\u00b0X\u0000\u02f4\u02f5\u0005>"+ + "\u0000\u0000\u02f5\u02f7\u0003\u00b0X\u0000\u02f6\u02f4\u0001\u0000\u0000"+ + "\u0000\u02f7\u02fa\u0001\u0000\u0000\u0000\u02f8\u02f6\u0001\u0000\u0000"+ + "\u0000\u02f8\u02f9\u0001\u0000\u0000\u0000\u02f9\u02fb\u0001\u0000\u0000"+ + "\u0000\u02fa\u02f8\u0001\u0000\u0000\u0000\u02fb\u02fc\u0005d\u0000\u0000"+ + "\u02fc\u02fe\u0001\u0000\u0000\u0000\u02fd\u02cf\u0001\u0000\u0000\u0000"+ + "\u02fd\u02d6\u0001\u0000\u0000\u0000\u02fd\u02dd\u0001\u0000\u0000\u0000"+ + "\u02fd\u02ed\u0001\u0000\u0000\u0000\u02fe\u0093\u0001\u0000\u0000\u0000"+ + "\u02ff\u0302\u00036\u001b\u0000\u0300\u0301\u0005;\u0000\u0000\u0301\u0303"+ + "\u0003\f\u0006\u0000\u0302\u0300\u0001\u0000\u0000\u0000\u0302\u0303\u0001"+ + "\u0000\u0000\u0000\u0303\u0304\u0001\u0000\u0000\u0000\u0304\u0305\u0005"+ + "<\u0000\u0000\u0305\u0306\u0003\u00a6S\u0000\u0306\u0095\u0001\u0000\u0000"+ + "\u0000\u0307\u030d\u0003\u0098L\u0000\u0308\u0309\u0003\u0098L\u0000\u0309"+ + "\u030a\u0003\u00b2Y\u0000\u030a\u030b\u0003\u0098L\u0000\u030b\u030d\u0001"+ + "\u0000\u0000\u0000\u030c\u0307\u0001\u0000\u0000\u0000\u030c\u0308\u0001"+ + "\u0000\u0000\u0000\u030d\u0097\u0001\u0000\u0000\u0000\u030e\u030f\u0006"+ + "L\uffff\uffff\u0000\u030f\u0313\u0003\u009aM\u0000\u0310\u0311\u0007\u0005"+ + "\u0000\u0000\u0311\u0313\u0003\u0098L\u0003\u0312\u030e\u0001\u0000\u0000"+ + "\u0000\u0312\u0310\u0001\u0000\u0000\u0000\u0313\u031c\u0001\u0000\u0000"+ + "\u0000\u0314\u0315\n\u0002\u0000\u0000\u0315\u0316\u0007\u0006\u0000\u0000"+ + "\u0316\u031b\u0003\u0098L\u0003\u0317\u0318\n\u0001\u0000\u0000\u0318"+ + "\u0319\u0007\u0005\u0000\u0000\u0319\u031b\u0003\u0098L\u0002\u031a\u0314"+ + "\u0001\u0000\u0000\u0000\u031a\u0317\u0001\u0000\u0000\u0000\u031b\u031e"+ + "\u0001\u0000\u0000\u0000\u031c\u031a\u0001\u0000\u0000\u0000\u031c\u031d"+ + "\u0001\u0000\u0000\u0000\u031d\u0099\u0001\u0000\u0000\u0000\u031e\u031c"+ + "\u0001\u0000\u0000\u0000\u031f\u0320\u0006M\uffff\uffff\u0000\u0320\u0328"+ + "\u0003\u00a6S\u0000\u0321\u0328\u00036\u001b\u0000\u0322\u0328\u0003\u009c"+ + "N\u0000\u0323\u0324\u0005c\u0000\u0000\u0324\u0325\u0003\u0090H\u0000"+ + "\u0325\u0326\u0005d\u0000\u0000\u0326\u0328\u0001\u0000\u0000\u0000\u0327"+ + "\u031f\u0001\u0000\u0000\u0000\u0327\u0321\u0001\u0000\u0000\u0000\u0327"+ + "\u0322\u0001\u0000\u0000\u0000\u0327\u0323\u0001\u0000\u0000\u0000\u0328"+ + "\u032e\u0001\u0000\u0000\u0000\u0329\u032a\n\u0001\u0000\u0000\u032a\u032b"+ + "\u0005;\u0000\u0000\u032b\u032d\u0003\f\u0006\u0000\u032c\u0329\u0001"+ + "\u0000\u0000\u0000\u032d\u0330\u0001\u0000\u0000\u0000\u032e\u032c\u0001"+ + "\u0000\u0000\u0000\u032e\u032f\u0001\u0000\u0000\u0000\u032f\u009b\u0001"+ + "\u0000\u0000\u0000\u0330\u032e\u0001\u0000\u0000\u0000\u0331\u0332\u0003"+ + "\u009eO\u0000\u0332\u0340\u0005c\u0000\u0000\u0333\u0341\u0005Y\u0000"+ + "\u0000\u0334\u0339\u0003\u0090H\u0000\u0335\u0336\u0005>\u0000\u0000\u0336"+ + "\u0338\u0003\u0090H\u0000\u0337\u0335\u0001\u0000\u0000\u0000\u0338\u033b"+ + "\u0001\u0000\u0000\u0000\u0339\u0337\u0001\u0000\u0000\u0000\u0339\u033a"+ + "\u0001\u0000\u0000\u0000\u033a\u033e\u0001\u0000\u0000\u0000\u033b\u0339"+ + "\u0001\u0000\u0000\u0000\u033c\u033d\u0005>\u0000\u0000\u033d\u033f\u0003"+ + "\u00a0P\u0000\u033e\u033c\u0001\u0000\u0000\u0000\u033e\u033f\u0001\u0000"+ + "\u0000\u0000\u033f\u0341\u0001\u0000\u0000\u0000\u0340\u0333\u0001\u0000"+ + "\u0000\u0000\u0340\u0334\u0001\u0000\u0000\u0000\u0340\u0341\u0001\u0000"+ + "\u0000\u0000\u0341\u0342\u0001\u0000\u0000\u0000\u0342\u0343\u0005d\u0000"+ + "\u0000\u0343\u009d\u0001\u0000\u0000\u0000\u0344\u0348\u0003H$\u0000\u0345"+ + "\u0348\u0005B\u0000\u0000\u0346\u0348\u0005E\u0000\u0000\u0347\u0344\u0001"+ + "\u0000\u0000\u0000\u0347\u0345\u0001\u0000\u0000\u0000\u0347\u0346\u0001"+ + "\u0000\u0000\u0000\u0348\u009f\u0001\u0000\u0000\u0000\u0349\u0352\u0005"+ + "\\\u0000\u0000\u034a\u034f\u0003\u00a2Q\u0000\u034b\u034c\u0005>\u0000"+ + "\u0000\u034c\u034e\u0003\u00a2Q\u0000\u034d\u034b\u0001\u0000\u0000\u0000"+ + "\u034e\u0351\u0001\u0000\u0000\u0000\u034f\u034d\u0001\u0000\u0000\u0000"+ + "\u034f\u0350\u0001\u0000\u0000\u0000\u0350\u0353\u0001\u0000\u0000\u0000"+ + "\u0351\u034f\u0001\u0000\u0000\u0000\u0352\u034a\u0001\u0000\u0000\u0000"+ + "\u0352\u0353\u0001\u0000\u0000\u0000\u0353\u0354\u0001\u0000\u0000\u0000"+ + "\u0354\u0355\u0005]\u0000\u0000\u0355\u00a1\u0001\u0000\u0000\u0000\u0356"+ + "\u0357\u0003\u00b0X\u0000\u0357\u0358\u0005<\u0000\u0000\u0358\u0359\u0003"+ + "\u00a4R\u0000\u0359\u00a3\u0001\u0000\u0000\u0000\u035a\u035d\u0003\u00a6"+ + "S\u0000\u035b\u035d\u0003\u00a0P\u0000\u035c\u035a\u0001\u0000\u0000\u0000"+ + "\u035c\u035b\u0001\u0000\u0000\u0000\u035d\u00a5\u0001\u0000\u0000\u0000"+ + "\u035e\u0389\u0005H\u0000\u0000\u035f\u0360\u0003\u00aeW\u0000\u0360\u0361"+ + "\u0005e\u0000\u0000\u0361\u0389\u0001\u0000\u0000\u0000\u0362\u0389\u0003"+ + "\u00acV\u0000\u0363\u0389\u0003\u00aeW\u0000\u0364\u0389\u0003\u00a8T"+ + "\u0000\u0365\u0389\u0003D\"\u0000\u0366\u0389\u0003\u00b0X\u0000\u0367"+ + "\u0368\u0005a\u0000\u0000\u0368\u036d\u0003\u00aaU\u0000\u0369\u036a\u0005"+ + ">\u0000\u0000\u036a\u036c\u0003\u00aaU\u0000\u036b\u0369\u0001\u0000\u0000"+ + "\u0000\u036c\u036f\u0001\u0000\u0000\u0000\u036d\u036b\u0001\u0000\u0000"+ + "\u0000\u036d\u036e\u0001\u0000\u0000\u0000\u036e\u0370\u0001\u0000\u0000"+ + "\u0000\u036f\u036d\u0001\u0000\u0000\u0000\u0370\u0371\u0005b\u0000\u0000"+ + "\u0371\u0389\u0001\u0000\u0000\u0000\u0372\u0373\u0005a\u0000\u0000\u0373"+ + "\u0378\u0003\u00a8T\u0000\u0374\u0375\u0005>\u0000\u0000\u0375\u0377\u0003"+ + "\u00a8T\u0000\u0376\u0374\u0001\u0000\u0000\u0000\u0377\u037a\u0001\u0000"+ + "\u0000\u0000\u0378\u0376\u0001\u0000\u0000\u0000\u0378\u0379\u0001\u0000"+ + "\u0000\u0000\u0379\u037b\u0001\u0000\u0000\u0000\u037a\u0378\u0001\u0000"+ + "\u0000\u0000\u037b\u037c\u0005b\u0000\u0000\u037c\u0389\u0001\u0000\u0000"+ + "\u0000\u037d\u037e\u0005a\u0000\u0000\u037e\u0383\u0003\u00b0X\u0000\u037f"+ + "\u0380\u0005>\u0000\u0000\u0380\u0382\u0003\u00b0X\u0000\u0381\u037f\u0001"+ + "\u0000\u0000\u0000\u0382\u0385\u0001\u0000\u0000\u0000\u0383\u0381\u0001"+ + "\u0000\u0000\u0000\u0383\u0384\u0001\u0000\u0000\u0000\u0384\u0386\u0001"+ + "\u0000\u0000\u0000\u0385\u0383\u0001\u0000\u0000\u0000\u0386\u0387\u0005"+ + "b\u0000\u0000\u0387\u0389\u0001\u0000\u0000\u0000\u0388\u035e\u0001\u0000"+ + "\u0000\u0000\u0388\u035f\u0001\u0000\u0000\u0000\u0388\u0362\u0001\u0000"+ + "\u0000\u0000\u0388\u0363\u0001\u0000\u0000\u0000\u0388\u0364\u0001\u0000"+ + "\u0000\u0000\u0388\u0365\u0001\u0000\u0000\u0000\u0388\u0366\u0001\u0000"+ + "\u0000\u0000\u0388\u0367\u0001\u0000\u0000\u0000\u0388\u0372\u0001\u0000"+ + "\u0000\u0000\u0388\u037d\u0001\u0000\u0000\u0000\u0389\u00a7\u0001\u0000"+ + "\u0000\u0000\u038a\u038b\u0007\u0007\u0000\u0000\u038b\u00a9\u0001\u0000"+ + "\u0000\u0000\u038c\u038f\u0003\u00acV\u0000\u038d\u038f\u0003\u00aeW\u0000"+ + "\u038e\u038c\u0001\u0000\u0000\u0000\u038e\u038d\u0001\u0000\u0000\u0000"+ + "\u038f\u00ab\u0001\u0000\u0000\u0000\u0390\u0392\u0007\u0005\u0000\u0000"+ + "\u0391\u0390\u0001\u0000\u0000\u0000\u0391\u0392\u0001\u0000\u0000\u0000"+ + "\u0392\u0393\u0001\u0000\u0000\u0000\u0393\u0394\u00056\u0000\u0000\u0394"+ + "\u00ad\u0001\u0000\u0000\u0000\u0395\u0397\u0007\u0005\u0000\u0000\u0396"+ + "\u0395\u0001\u0000\u0000\u0000\u0396\u0397\u0001\u0000\u0000\u0000\u0397"+ + "\u0398\u0001\u0000\u0000\u0000\u0398\u0399\u00055\u0000\u0000\u0399\u00af"+ + "\u0001\u0000\u0000\u0000\u039a\u039b\u00054\u0000\u0000\u039b\u00b1\u0001"+ + "\u0000\u0000\u0000\u039c\u039d\u0007\b\u0000\u0000\u039d\u00b3\u0001\u0000"+ + "\u0000\u0000\u039e\u039f\u0007\t\u0000\u0000\u039f\u03a0\u0005|\u0000"+ + "\u0000\u03a0\u03a1\u0003\u00b6[\u0000\u03a1\u03a2\u0003\u00b8\\\u0000"+ + "\u03a2\u00b5\u0001\u0000\u0000\u0000\u03a3\u03a4\u0004[\u000e\u0000\u03a4"+ + "\u03a6\u0003\"\u0011\u0000\u03a5\u03a7\u0005\u0096\u0000\u0000\u03a6\u03a5"+ + "\u0001\u0000\u0000\u0000\u03a6\u03a7\u0001\u0000\u0000\u0000\u03a7\u03a8"+ + "\u0001\u0000\u0000\u0000\u03a8\u03a9\u0005k\u0000\u0000\u03a9\u03ac\u0001"+ + "\u0000\u0000\u0000\u03aa\u03ac\u0003\"\u0011\u0000\u03ab\u03a3\u0001\u0000"+ + "\u0000\u0000\u03ab\u03aa\u0001\u0000\u0000\u0000\u03ac\u00b7\u0001\u0000"+ + "\u0000\u0000\u03ad\u03ae\u0005J\u0000\u0000\u03ae\u03b3\u0003\u0090H\u0000"+ + "\u03af\u03b0\u0005>\u0000\u0000\u03b0\u03b2\u0003\u0090H\u0000\u03b1\u03af"+ + "\u0001\u0000\u0000\u0000\u03b2\u03b5\u0001\u0000\u0000\u0000\u03b3\u03b1"+ + "\u0001\u0000\u0000\u0000\u03b3\u03b4\u0001\u0000\u0000\u0000\u03b4\u00b9"+ + "\u0001\u0000\u0000\u0000\u03b5\u03b3\u0001\u0000\u0000\u0000\u03b6\u03b8"+ + "\u0005!\u0000\u0000\u03b7\u03b9\u0003\u00bc^\u0000\u03b8\u03b7\u0001\u0000"+ + "\u0000\u0000\u03b9\u03ba\u0001\u0000\u0000\u0000\u03ba\u03b8\u0001\u0000"+ + "\u0000\u0000\u03ba\u03bb\u0001\u0000\u0000\u0000\u03bb\u03bc\u0001\u0000"+ + "\u0000\u0000\u03bc\u03c0\u0005c\u0000\u0000\u03bd\u03bf\u0003\u00c0`\u0000"+ + "\u03be\u03bd\u0001\u0000\u0000\u0000\u03bf\u03c2\u0001\u0000\u0000\u0000"+ + "\u03c0\u03be\u0001\u0000\u0000\u0000\u03c0\u03c1\u0001\u0000\u0000\u0000"+ + "\u03c1\u03c3\u0001\u0000\u0000\u0000\u03c2\u03c0\u0001\u0000\u0000\u0000"+ + "\u03c3\u03c4\u0005d\u0000\u0000\u03c4\u00bb\u0001\u0000\u0000\u0000\u03c5"+ + "\u03c6\u0003\u00be_\u0000\u03c6\u03c7\u0003\u00be_\u0000\u03c7\u00bd\u0001"+ + "\u0000\u0000\u0000\u03c8\u03c9\u0007\n\u0000\u0000\u03c9\u00bf\u0001\u0000"+ + "\u0000\u0000\u03ca\u03d4\u0005\u0092\u0000\u0000\u03cb\u03cf\u0005c\u0000"+ + "\u0000\u03cc\u03ce\u0003\u00c0`\u0000\u03cd\u03cc\u0001\u0000\u0000\u0000"+ + "\u03ce\u03d1\u0001\u0000\u0000\u0000\u03cf\u03cd\u0001\u0000\u0000\u0000"+ + "\u03cf\u03d0\u0001\u0000\u0000\u0000\u03d0\u03d2\u0001\u0000\u0000\u0000"+ + "\u03d1\u03cf\u0001\u0000\u0000\u0000\u03d2\u03d4\u0005d\u0000\u0000\u03d3"+ + "\u03ca\u0001\u0000\u0000\u0000\u03d3\u03cb\u0001\u0000\u0000\u0000\u03d4"+ + "\u00c1\u0001\u0000\u0000\u0000_\u00c5\u00d6\u00df\u00fb\u010a\u0110\u0119"+ + "\u011f\u012c\u0130\u0135\u013d\u014b\u015b\u0163\u0167\u016e\u0174\u0179"+ + "\u0182\u0189\u018f\u0198\u019f\u01a7\u01af\u01b3\u01b7\u01bc\u01c7\u01cc"+ + "\u01d0\u01de\u01e9\u01ef\u01f6\u01ff\u0208\u021c\u0224\u0227\u022e\u0239"+ + "\u0240\u0248\u0256\u025f\u026a\u0274\u027a\u027c\u0280\u0285\u0293\u02ac"+ + "\u02b5\u02bd\u02c2\u02ca\u02cc\u02d1\u02d8\u02df\u02e8\u02ef\u02f8\u02fd"+ + "\u0302\u030c\u0312\u031a\u031c\u0327\u032e\u0339\u033e\u0340\u0347\u034f"+ + "\u0352\u035c\u036d\u0378\u0383\u0388\u038e\u0391\u0396\u03a6\u03ab\u03b3"+ + "\u03ba\u03c0\u03cf\u03d3"; public static final ATN _ATN = new ATNDeserializer().deserialize(_serializedATN.toCharArray()); static { diff --git a/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/parser/EsqlBaseParserBaseListener.java b/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/parser/EsqlBaseParserBaseListener.java index c73b06ccc9d63..714d8e8a16530 100644 --- a/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/parser/EsqlBaseParserBaseListener.java +++ b/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/parser/EsqlBaseParserBaseListener.java @@ -1484,6 +1484,54 @@ public class EsqlBaseParserBaseListener implements EsqlBaseParserListener { *

The default implementation does nothing.

*/ @Override public void exitJoinCondition(EsqlBaseParser.JoinConditionContext ctx) { } + /** + * {@inheritDoc} + * + *

The default implementation does nothing.

+ */ + @Override public void enterPromqlCommand(EsqlBaseParser.PromqlCommandContext ctx) { } + /** + * {@inheritDoc} + * + *

The default implementation does nothing.

+ */ + @Override public void exitPromqlCommand(EsqlBaseParser.PromqlCommandContext ctx) { } + /** + * {@inheritDoc} + * + *

The default implementation does nothing.

+ */ + @Override public void enterPromqlParam(EsqlBaseParser.PromqlParamContext ctx) { } + /** + * {@inheritDoc} + * + *

The default implementation does nothing.

+ */ + @Override public void exitPromqlParam(EsqlBaseParser.PromqlParamContext ctx) { } + /** + * {@inheritDoc} + * + *

The default implementation does nothing.

+ */ + @Override public void enterPromqlParamContent(EsqlBaseParser.PromqlParamContentContext ctx) { } + /** + * {@inheritDoc} + * + *

The default implementation does nothing.

+ */ + @Override public void exitPromqlParamContent(EsqlBaseParser.PromqlParamContentContext ctx) { } + /** + * {@inheritDoc} + * + *

The default implementation does nothing.

+ */ + @Override public void enterPromqlQueryPart(EsqlBaseParser.PromqlQueryPartContext ctx) { } + /** + * {@inheritDoc} + * + *

The default implementation does nothing.

+ */ + @Override public void exitPromqlQueryPart(EsqlBaseParser.PromqlQueryPartContext ctx) { } /** * {@inheritDoc} diff --git a/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/parser/EsqlBaseParserBaseVisitor.java b/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/parser/EsqlBaseParserBaseVisitor.java index 208f89842d6cd..41030f98d6e0f 100644 --- a/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/parser/EsqlBaseParserBaseVisitor.java +++ b/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/parser/EsqlBaseParserBaseVisitor.java @@ -874,4 +874,32 @@ public class EsqlBaseParserBaseVisitor extends AbstractParseTreeVisitor im * {@link #visitChildren} on {@code ctx}.

*/ @Override public T visitJoinCondition(EsqlBaseParser.JoinConditionContext ctx) { return visitChildren(ctx); } + /** + * {@inheritDoc} + * + *

The default implementation returns the result of calling + * {@link #visitChildren} on {@code ctx}.

+ */ + @Override public T visitPromqlCommand(EsqlBaseParser.PromqlCommandContext ctx) { return visitChildren(ctx); } + /** + * {@inheritDoc} + * + *

The default implementation returns the result of calling + * {@link #visitChildren} on {@code ctx}.

+ */ + @Override public T visitPromqlParam(EsqlBaseParser.PromqlParamContext ctx) { return visitChildren(ctx); } + /** + * {@inheritDoc} + * + *

The default implementation returns the result of calling + * {@link #visitChildren} on {@code ctx}.

+ */ + @Override public T visitPromqlParamContent(EsqlBaseParser.PromqlParamContentContext ctx) { return visitChildren(ctx); } + /** + * {@inheritDoc} + * + *

The default implementation returns the result of calling + * {@link #visitChildren} on {@code ctx}.

+ */ + @Override public T visitPromqlQueryPart(EsqlBaseParser.PromqlQueryPartContext ctx) { return visitChildren(ctx); } } diff --git a/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/parser/EsqlBaseParserListener.java b/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/parser/EsqlBaseParserListener.java index 04fc908e1ac90..8056b7429623d 100644 --- a/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/parser/EsqlBaseParserListener.java +++ b/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/parser/EsqlBaseParserListener.java @@ -1317,4 +1317,44 @@ public interface EsqlBaseParserListener extends ParseTreeListener { * @param ctx the parse tree */ void exitJoinCondition(EsqlBaseParser.JoinConditionContext ctx); + /** + * Enter a parse tree produced by {@link EsqlBaseParser#promqlCommand}. + * @param ctx the parse tree + */ + void enterPromqlCommand(EsqlBaseParser.PromqlCommandContext ctx); + /** + * Exit a parse tree produced by {@link EsqlBaseParser#promqlCommand}. + * @param ctx the parse tree + */ + void exitPromqlCommand(EsqlBaseParser.PromqlCommandContext ctx); + /** + * Enter a parse tree produced by {@link EsqlBaseParser#promqlParam}. + * @param ctx the parse tree + */ + void enterPromqlParam(EsqlBaseParser.PromqlParamContext ctx); + /** + * Exit a parse tree produced by {@link EsqlBaseParser#promqlParam}. + * @param ctx the parse tree + */ + void exitPromqlParam(EsqlBaseParser.PromqlParamContext ctx); + /** + * Enter a parse tree produced by {@link EsqlBaseParser#promqlParamContent}. + * @param ctx the parse tree + */ + void enterPromqlParamContent(EsqlBaseParser.PromqlParamContentContext ctx); + /** + * Exit a parse tree produced by {@link EsqlBaseParser#promqlParamContent}. + * @param ctx the parse tree + */ + void exitPromqlParamContent(EsqlBaseParser.PromqlParamContentContext ctx); + /** + * Enter a parse tree produced by {@link EsqlBaseParser#promqlQueryPart}. + * @param ctx the parse tree + */ + void enterPromqlQueryPart(EsqlBaseParser.PromqlQueryPartContext ctx); + /** + * Exit a parse tree produced by {@link EsqlBaseParser#promqlQueryPart}. + * @param ctx the parse tree + */ + void exitPromqlQueryPart(EsqlBaseParser.PromqlQueryPartContext ctx); } diff --git a/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/parser/EsqlBaseParserVisitor.java b/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/parser/EsqlBaseParserVisitor.java index 09484d88bf6c8..74b7d607ecdb5 100644 --- a/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/parser/EsqlBaseParserVisitor.java +++ b/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/parser/EsqlBaseParserVisitor.java @@ -791,4 +791,28 @@ public interface EsqlBaseParserVisitor extends ParseTreeVisitor { * @return the visitor result */ T visitJoinCondition(EsqlBaseParser.JoinConditionContext ctx); + /** + * Visit a parse tree produced by {@link EsqlBaseParser#promqlCommand}. + * @param ctx the parse tree + * @return the visitor result + */ + T visitPromqlCommand(EsqlBaseParser.PromqlCommandContext ctx); + /** + * Visit a parse tree produced by {@link EsqlBaseParser#promqlParam}. + * @param ctx the parse tree + * @return the visitor result + */ + T visitPromqlParam(EsqlBaseParser.PromqlParamContext ctx); + /** + * Visit a parse tree produced by {@link EsqlBaseParser#promqlParamContent}. + * @param ctx the parse tree + * @return the visitor result + */ + T visitPromqlParamContent(EsqlBaseParser.PromqlParamContentContext ctx); + /** + * Visit a parse tree produced by {@link EsqlBaseParser#promqlQueryPart}. + * @param ctx the parse tree + * @return the visitor result + */ + T visitPromqlQueryPart(EsqlBaseParser.PromqlQueryPartContext ctx); } diff --git a/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/parser/LexerConfig.java b/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/parser/LexerConfig.java index adcdba2f2eb4d..c7a869de8ee2a 100644 --- a/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/parser/LexerConfig.java +++ b/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/parser/LexerConfig.java @@ -17,6 +17,7 @@ public abstract class LexerConfig extends Lexer { // is null when running inside the IDEA plugin EsqlConfig config; + private int promqlDepth = 0; public LexerConfig() {} @@ -31,4 +32,30 @@ boolean isDevVersion() { void setEsqlConfig(EsqlConfig config) { this.config = config; } + + // Needed by the Promql command + void incPromqlDepth() { + promqlDepth++; + } + + void decPromqlDepth() { + if (promqlDepth == 0) { + throw new ParsingException("Invalid PromQL command, unexpected '('"); + } + promqlDepth--; + } + + void resetPromqlDepth() { + if (promqlDepth != 0) { + throw new ParsingException( + "Invalid PromQL declaration, missing [{}] [{}] parenthesis", + Math.absExact(promqlDepth), + promqlDepth > 0 ? '(' : ')' + ); + } + } + + boolean isPromqlQuery() { + return promqlDepth > 0; + } } diff --git a/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/parser/LogicalPlanBuilder.java b/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/parser/LogicalPlanBuilder.java index c1046741e2175..fa0a8752cbf1f 100644 --- a/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/parser/LogicalPlanBuilder.java +++ b/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/parser/LogicalPlanBuilder.java @@ -8,6 +8,7 @@ package org.elasticsearch.xpack.esql.parser; import org.antlr.v4.runtime.ParserRuleContext; +import org.antlr.v4.runtime.Token; import org.antlr.v4.runtime.tree.ParseTree; import org.apache.lucene.util.BytesRef; import org.elasticsearch.Build; @@ -23,6 +24,7 @@ import org.elasticsearch.transport.RemoteClusterAware; import org.elasticsearch.xpack.esql.VerificationException; import org.elasticsearch.xpack.esql.action.EsqlCapabilities; +import org.elasticsearch.xpack.esql.action.PromqlFeatures; import org.elasticsearch.xpack.esql.capabilities.TelemetryAware; import org.elasticsearch.xpack.esql.common.Failure; import org.elasticsearch.xpack.esql.core.expression.Alias; @@ -39,9 +41,12 @@ import org.elasticsearch.xpack.esql.core.expression.ReferenceAttribute; import org.elasticsearch.xpack.esql.core.expression.UnresolvedAttribute; import org.elasticsearch.xpack.esql.core.expression.UnresolvedStar; +import org.elasticsearch.xpack.esql.core.expression.UnresolvedTimestamp; import org.elasticsearch.xpack.esql.core.tree.Source; import org.elasticsearch.xpack.esql.core.type.DataType; +import org.elasticsearch.xpack.esql.core.util.CollectionUtils; import org.elasticsearch.xpack.esql.core.util.Holder; +import org.elasticsearch.xpack.esql.core.util.StringUtils; import org.elasticsearch.xpack.esql.expression.Order; import org.elasticsearch.xpack.esql.expression.UnresolvedNamePattern; import org.elasticsearch.xpack.esql.expression.function.UnresolvedFunction; @@ -50,6 +55,7 @@ import org.elasticsearch.xpack.esql.expression.predicate.logical.Not; import org.elasticsearch.xpack.esql.expression.predicate.operator.comparison.Equals; import org.elasticsearch.xpack.esql.expression.predicate.operator.comparison.EsqlBinaryComparison; +import org.elasticsearch.xpack.esql.parser.promql.PromqlParserUtils; import org.elasticsearch.xpack.esql.plan.EsqlStatement; import org.elasticsearch.xpack.esql.plan.IndexPattern; import org.elasticsearch.xpack.esql.plan.QuerySetting; @@ -83,20 +89,23 @@ import org.elasticsearch.xpack.esql.plan.logical.inference.InferencePlan; import org.elasticsearch.xpack.esql.plan.logical.inference.Rerank; import org.elasticsearch.xpack.esql.plan.logical.join.LookupJoin; +import org.elasticsearch.xpack.esql.plan.logical.promql.PromqlCommand; import org.elasticsearch.xpack.esql.plan.logical.show.ShowInfo; import org.joni.exception.SyntaxException; +import java.time.Duration; +import java.time.Instant; import java.util.ArrayList; import java.util.Arrays; import java.util.Collections; import java.util.HashMap; +import java.util.HashSet; import java.util.LinkedHashMap; import java.util.LinkedHashSet; import java.util.List; import java.util.Locale; import java.util.Map; import java.util.Set; -import java.util.function.Function; import static java.util.Collections.emptyList; import static org.elasticsearch.xpack.esql.action.EsqlCapabilities.Cap.LOOKUP_JOIN_ON_BOOLEAN_EXPRESSION; @@ -113,7 +122,8 @@ */ public class LogicalPlanBuilder extends ExpressionBuilder { - interface PlanFactory extends Function {} + private static final String TIME = "time", START = "start", END = "end", STEP = "step"; + private static final Set PROMQL_ALLOWED_PARAMS = Set.of(TIME, START, END, STEP); /** * Maximum number of commands allowed per query @@ -1213,4 +1223,212 @@ public PlanFactory visitSampleCommand(EsqlBaseParser.SampleCommandContext ctx) { ); } } + + @Override + public PlanFactory visitPromqlCommand(EsqlBaseParser.PromqlCommandContext ctx) { + Source source = source(ctx); + + // Check if PromQL functionality is enabled + if (PromqlFeatures.isEnabled() == false) { + throw new ParsingException( + source, + "PROMQL command is not available. Requires snapshot build with capability [promql_vX] enabled" + ); + } + + PromqlParams params = parsePromqlParams(ctx, source); + + // TODO: Perform type and value validation + var queryCtx = ctx.promqlQueryPart(); + if (queryCtx == null || queryCtx.isEmpty()) { + throw new ParsingException(source, "PromQL expression cannot be empty"); + } + + Token startToken = queryCtx.getFirst().start; + Token stopToken = queryCtx.getLast().stop; + // copy the query verbatim to avoid missing tokens interpreted by the enclosing lexer + String promqlQuery = source(startToken, stopToken).text(); + if (promqlQuery.isBlank()) { + throw new ParsingException(source, "PromQL expression cannot be empty"); + } + + int promqlStartLine = startToken.getLine(); + int promqlStartColumn = startToken.getCharPositionInLine(); + + PromqlParser promqlParser = new PromqlParser(); + LogicalPlan promqlPlan; + try { + // The existing PromqlParser is used to parse the inner query + promqlPlan = promqlParser.createStatement( + promqlQuery, + params.startLiteral(), + params.endLiteral(), + promqlStartLine, + promqlStartColumn + ); + } catch (ParsingException pe) { + throw PromqlParserUtils.adjustParsingException(pe, promqlStartLine, promqlStartColumn); + } + + return plan -> new PromqlCommand( + source, + plan, + promqlPlan, + params.startLiteral(), + params.endLiteral(), + params.stepLiteral(), + new UnresolvedTimestamp(source) + ); + } + + private PromqlParams parsePromqlParams(EsqlBaseParser.PromqlCommandContext ctx, Source source) { + Instant time = null; + Instant start = null; + Instant end = null; + Duration step = null; + + Set paramsSeen = new HashSet<>(); + for (EsqlBaseParser.PromqlParamContext paramCtx : ctx.promqlParam()) { + var paramNameCtx = paramCtx.name; + String name = parseParamName(paramCtx.name); + if (paramsSeen.add(name) == false) { + throw new ParsingException(source(paramNameCtx), "[{}] already specified", name); + } + Source valueSource = source(paramCtx.value); + String valueString = parseParamValue(paramCtx.value); + switch (name) { + case TIME -> time = PromqlParserUtils.parseDate(valueSource, valueString); + case START -> start = PromqlParserUtils.parseDate(valueSource, valueString); + case END -> end = PromqlParserUtils.parseDate(valueSource, valueString); + case STEP -> { + try { + step = Duration.ofSeconds(Integer.parseInt(valueString)); + } catch (NumberFormatException ignore) { + step = PromqlParserUtils.parseDuration(valueSource, valueString); + } + } + default -> { + String message = "Unknown parameter [{}]"; + List similar = StringUtils.findSimilar(name, PROMQL_ALLOWED_PARAMS); + if (CollectionUtils.isEmpty(similar) == false) { + message += ", did you mean " + (similar.size() == 1 ? "[" + similar.get(0) + "]" : "any of " + similar) + "?"; + } + throw new ParsingException(source(paramNameCtx), message, name); + } + } + } + + // Validation logic for time parameters + if (time != null) { + if (start != null || end != null || step != null) { + throw new ParsingException( + source, + "Specify either [{}] for instant query or [{}], [{}] or [{}] for a range query", + TIME, + STEP, + START, + END + ); + } + start = time; + end = time; + } else if (step != null) { + if (start != null || end != null) { + if (start == null || end == null) { + throw new ParsingException( + source, + "Parameters [{}] and [{}] must either both be specified or both be omitted for a range query", + START, + END + ); + } + if (end.isBefore(start)) { + throw new ParsingException( + source, + "invalid parameter \"end\": end timestamp must not be before start time", + end, + start + ); + } + } + if (step.isPositive() == false) { + throw new ParsingException( + source, + "invalid parameter \"step\": zero or negative query resolution step widths are not accepted. " + + "Try a positive integer", + step + ); + } + } else { + throw new ParsingException(source, "Parameter [{}] or [{}] is required", STEP, TIME); + } + return new PromqlParams(source, start, end, step); + } + + private String parseParamName(EsqlBaseParser.PromqlParamContentContext ctx) { + if (ctx.PROMQL_UNQUOTED_IDENTIFIER() != null) { + return ctx.PROMQL_UNQUOTED_IDENTIFIER().getText(); + } else if (ctx.QUOTED_IDENTIFIER() != null) { + return AbstractBuilder.unquote(ctx.QUOTED_IDENTIFIER().getText()); + } else { + throw new ParsingException(source(ctx), "Parameter name [{}] must be an identifier", ctx.getText()); + } + } + + private String parseParamValue(EsqlBaseParser.PromqlParamContentContext ctx) { + if (ctx.PROMQL_UNQUOTED_IDENTIFIER() != null) { + return ctx.PROMQL_UNQUOTED_IDENTIFIER().getText(); + } else if (ctx.QUOTED_STRING() != null) { + return AbstractBuilder.unquote(ctx.QUOTED_STRING().getText()); + } else if (ctx.NAMED_OR_POSITIONAL_PARAM() != null) { + QueryParam param = paramByNameOrPosition(ctx.NAMED_OR_POSITIONAL_PARAM()); + return param.value().toString(); + } else if (ctx.QUOTED_IDENTIFIER() != null) { + throw new ParsingException(source(ctx), "Parameter value [{}] must not be a quoted identifier", ctx.getText()); + } else { + throw new ParsingException(source(ctx), "Invalid parameter value [{}]", ctx.getText()); + } + } + + /** + * Container for PromQL command parameters: + *
    + *
  • time for instant queries
  • + *
  • start, end, step for range queries
  • + *
+ * These can be specified in the {@linkplain PromqlCommand PROMQL command} like so: + *
+     *     # instant query
+     *     PROMQL time "2025-10-31T00:00:00Z" (avg(foo))
+     *     # range query with explicit start and end
+     *     PROMQL start "2025-10-31T00:00:00Z" end "2025-10-31T01:00:00Z" step 1m (avg(foo))
+     *     # range query with implicit time bounds, doesn't support calling {@code start()} or {@code end()} functions
+     *     PROMQL step 5m (avg(foo))
+     * 
+ * + * @see PromQL API documentation + */ + public record PromqlParams(Source source, Instant start, Instant end, Duration step) { + + public Literal startLiteral() { + if (start == null) { + return Literal.NULL; + } + return Literal.dateTime(source, start); + } + + public Literal endLiteral() { + if (end == null) { + return Literal.NULL; + } + return Literal.dateTime(source, end); + } + + public Literal stepLiteral() { + if (step == null) { + return Literal.NULL; + } + return Literal.timeDuration(source, step); + } + } } diff --git a/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/parser/PlanFactory.java b/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/parser/PlanFactory.java new file mode 100644 index 0000000000000..8dabcefdde220 --- /dev/null +++ b/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/parser/PlanFactory.java @@ -0,0 +1,18 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +package org.elasticsearch.xpack.esql.parser; + +import org.elasticsearch.xpack.esql.plan.logical.LogicalPlan; + +import java.util.function.Function; + +/** + * A factory that takes a {@link LogicalPlan} and returns another {@link LogicalPlan}. + * This is used to chaining sub-plans after they've been created by the parser. + */ +public interface PlanFactory extends Function {} diff --git a/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/parser/PromqlBaseLexer.interp b/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/parser/PromqlBaseLexer.interp new file mode 100644 index 0000000000000..4d58dcfae38bd --- /dev/null +++ b/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/parser/PromqlBaseLexer.interp @@ -0,0 +1,164 @@ +token literal names: +null +'+' +'-' +'*' +'/' +'%' +'^' +'==' +'!=' +'>' +'>=' +'<' +'<=' +'=' +'=~' +'!~' +'and' +'or' +'unless' +'by' +'without' +'on' +'ignoring' +'group_left' +'group_right' +'bool' +null +'@' +'start()' +'end()' +'{' +'}' +'[' +']' +'(' +')' +':' +',' +null +null +null +null +null +null +null +null +null +null + +token symbolic names: +null +PLUS +MINUS +ASTERISK +SLASH +PERCENT +CARET +EQ +NEQ +GT +GTE +LT +LTE +LABEL_EQ +LABEL_RGX +LABEL_RGX_NEQ +AND +OR +UNLESS +BY +WITHOUT +ON +IGNORING +GROUP_LEFT +GROUP_RIGHT +BOOL +OFFSET +AT +AT_START +AT_END +LCB +RCB +LSB +RSB +LP +RP +COLON +COMMA +STRING +INTEGER_VALUE +DECIMAL_VALUE +HEXADECIMAL +TIME_VALUE_WITH_COLON +TIME_VALUE +IDENTIFIER +COMMENT +WS +UNRECOGNIZED + +rule names: +PLUS +MINUS +ASTERISK +SLASH +PERCENT +CARET +EQ +NEQ +GT +GTE +LT +LTE +LABEL_EQ +LABEL_RGX +LABEL_RGX_NEQ +AND +OR +UNLESS +BY +WITHOUT +ON +IGNORING +GROUP_LEFT +GROUP_RIGHT +BOOL +OFFSET +AT +AT_START +AT_END +LCB +RCB +LSB +RSB +LP +RP +COLON +COMMA +STRING +ESC_CHARS +INTEGER_VALUE +DECIMAL_VALUE +HEXADECIMAL +TIME_VALUE_WITH_COLON +TIME_VALUE +IDENTIFIER +COMMENT +WS +UNRECOGNIZED +SQ +DQ +EXPONENT +DIGIT +DOT + +channel names: +DEFAULT_TOKEN_CHANNEL +HIDDEN + +mode names: +DEFAULT_MODE + +atn: +[4, 0, 47, 428, 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, 2, 26, 7, 26, 2, 27, 7, 27, 2, 28, 7, 28, 2, 29, 7, 29, 2, 30, 7, 30, 2, 31, 7, 31, 2, 32, 7, 32, 2, 33, 7, 33, 2, 34, 7, 34, 2, 35, 7, 35, 2, 36, 7, 36, 2, 37, 7, 37, 2, 38, 7, 38, 2, 39, 7, 39, 2, 40, 7, 40, 2, 41, 7, 41, 2, 42, 7, 42, 2, 43, 7, 43, 2, 44, 7, 44, 2, 45, 7, 45, 2, 46, 7, 46, 2, 47, 7, 47, 2, 48, 7, 48, 2, 49, 7, 49, 2, 50, 7, 50, 2, 51, 7, 51, 2, 52, 7, 52, 1, 0, 1, 0, 1, 1, 1, 1, 1, 2, 1, 2, 1, 3, 1, 3, 1, 4, 1, 4, 1, 5, 1, 5, 1, 6, 1, 6, 1, 6, 1, 7, 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, 12, 1, 12, 1, 13, 1, 13, 1, 13, 1, 14, 1, 14, 1, 14, 1, 15, 1, 15, 1, 15, 1, 15, 1, 16, 1, 16, 1, 16, 1, 17, 1, 17, 1, 17, 1, 17, 1, 17, 1, 17, 1, 17, 1, 18, 1, 18, 1, 18, 1, 19, 1, 19, 1, 19, 1, 19, 1, 19, 1, 19, 1, 19, 1, 19, 1, 20, 1, 20, 1, 20, 1, 21, 1, 21, 1, 21, 1, 21, 1, 21, 1, 21, 1, 21, 1, 21, 1, 21, 1, 22, 1, 22, 1, 22, 1, 22, 1, 22, 1, 22, 1, 22, 1, 22, 1, 22, 1, 22, 1, 22, 1, 23, 1, 23, 1, 23, 1, 23, 1, 23, 1, 23, 1, 23, 1, 23, 1, 23, 1, 23, 1, 23, 1, 23, 1, 24, 1, 24, 1, 24, 1, 24, 1, 24, 1, 25, 1, 25, 1, 25, 1, 25, 1, 25, 1, 25, 1, 25, 1, 25, 1, 25, 1, 25, 1, 25, 1, 25, 3, 25, 221, 8, 25, 1, 26, 1, 26, 1, 27, 1, 27, 1, 27, 1, 27, 1, 27, 1, 27, 1, 27, 1, 27, 1, 28, 1, 28, 1, 28, 1, 28, 1, 28, 1, 28, 1, 29, 1, 29, 1, 30, 1, 30, 1, 31, 1, 31, 1, 32, 1, 32, 1, 33, 1, 33, 1, 34, 1, 34, 1, 35, 1, 35, 1, 36, 1, 36, 1, 37, 1, 37, 1, 37, 1, 37, 5, 37, 259, 8, 37, 10, 37, 12, 37, 262, 9, 37, 1, 37, 1, 37, 1, 37, 1, 37, 1, 37, 1, 37, 5, 37, 270, 8, 37, 10, 37, 12, 37, 273, 9, 37, 1, 37, 1, 37, 1, 37, 1, 37, 5, 37, 279, 8, 37, 10, 37, 12, 37, 282, 9, 37, 1, 37, 3, 37, 285, 8, 37, 1, 38, 1, 38, 1, 39, 4, 39, 290, 8, 39, 11, 39, 12, 39, 291, 1, 40, 4, 40, 295, 8, 40, 11, 40, 12, 40, 296, 1, 40, 1, 40, 5, 40, 301, 8, 40, 10, 40, 12, 40, 304, 9, 40, 1, 40, 1, 40, 4, 40, 308, 8, 40, 11, 40, 12, 40, 309, 1, 40, 4, 40, 313, 8, 40, 11, 40, 12, 40, 314, 1, 40, 1, 40, 5, 40, 319, 8, 40, 10, 40, 12, 40, 322, 9, 40, 3, 40, 324, 8, 40, 1, 40, 1, 40, 1, 40, 1, 40, 4, 40, 330, 8, 40, 11, 40, 12, 40, 331, 1, 40, 1, 40, 1, 40, 1, 40, 1, 40, 1, 40, 1, 40, 1, 40, 3, 40, 342, 8, 40, 1, 41, 1, 41, 1, 41, 1, 41, 4, 41, 348, 8, 41, 11, 41, 12, 41, 349, 1, 42, 1, 42, 4, 42, 354, 8, 42, 11, 42, 12, 42, 355, 1, 42, 4, 42, 359, 8, 42, 11, 42, 12, 42, 360, 4, 42, 363, 8, 42, 11, 42, 12, 42, 364, 1, 43, 4, 43, 368, 8, 43, 11, 43, 12, 43, 369, 1, 43, 4, 43, 373, 8, 43, 11, 43, 12, 43, 374, 4, 43, 377, 8, 43, 11, 43, 12, 43, 378, 1, 44, 1, 44, 5, 44, 383, 8, 44, 10, 44, 12, 44, 386, 9, 44, 1, 45, 1, 45, 5, 45, 390, 8, 45, 10, 45, 12, 45, 393, 9, 45, 1, 45, 3, 45, 396, 8, 45, 1, 45, 3, 45, 399, 8, 45, 1, 45, 1, 45, 1, 46, 4, 46, 404, 8, 46, 11, 46, 12, 46, 405, 1, 46, 1, 46, 1, 47, 1, 47, 1, 48, 1, 48, 1, 49, 1, 49, 1, 50, 1, 50, 3, 50, 418, 8, 50, 1, 50, 4, 50, 421, 8, 50, 11, 50, 12, 50, 422, 1, 51, 1, 51, 1, 52, 1, 52, 0, 0, 53, 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, 16, 33, 17, 35, 18, 37, 19, 39, 20, 41, 21, 43, 22, 45, 23, 47, 24, 49, 25, 51, 26, 53, 27, 55, 28, 57, 29, 59, 30, 61, 31, 63, 32, 65, 33, 67, 34, 69, 35, 71, 36, 73, 37, 75, 38, 77, 0, 79, 39, 81, 40, 83, 41, 85, 42, 87, 43, 89, 44, 91, 45, 93, 46, 95, 47, 97, 0, 99, 0, 101, 0, 103, 0, 105, 0, 1, 0, 19, 8, 0, 39, 39, 92, 92, 97, 98, 102, 102, 110, 110, 114, 114, 116, 116, 118, 118, 1, 0, 39, 39, 8, 0, 34, 34, 92, 92, 97, 98, 102, 102, 110, 110, 114, 114, 116, 116, 118, 118, 1, 0, 34, 34, 1, 0, 96, 96, 7, 0, 92, 92, 97, 98, 102, 102, 110, 110, 114, 114, 116, 116, 118, 118, 2, 0, 73, 73, 105, 105, 2, 0, 78, 78, 110, 110, 2, 0, 70, 70, 102, 102, 2, 0, 65, 65, 97, 97, 3, 0, 48, 57, 65, 70, 97, 102, 2, 0, 65, 90, 97, 122, 4, 0, 58, 58, 65, 90, 95, 95, 97, 122, 5, 0, 46, 46, 48, 58, 65, 90, 95, 95, 97, 122, 2, 0, 10, 10, 13, 13, 3, 0, 9, 10, 13, 13, 32, 32, 2, 0, 69, 69, 101, 101, 2, 0, 43, 43, 45, 45, 1, 0, 48, 57, 456, 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, 31, 1, 0, 0, 0, 0, 33, 1, 0, 0, 0, 0, 35, 1, 0, 0, 0, 0, 37, 1, 0, 0, 0, 0, 39, 1, 0, 0, 0, 0, 41, 1, 0, 0, 0, 0, 43, 1, 0, 0, 0, 0, 45, 1, 0, 0, 0, 0, 47, 1, 0, 0, 0, 0, 49, 1, 0, 0, 0, 0, 51, 1, 0, 0, 0, 0, 53, 1, 0, 0, 0, 0, 55, 1, 0, 0, 0, 0, 57, 1, 0, 0, 0, 0, 59, 1, 0, 0, 0, 0, 61, 1, 0, 0, 0, 0, 63, 1, 0, 0, 0, 0, 65, 1, 0, 0, 0, 0, 67, 1, 0, 0, 0, 0, 69, 1, 0, 0, 0, 0, 71, 1, 0, 0, 0, 0, 73, 1, 0, 0, 0, 0, 75, 1, 0, 0, 0, 0, 79, 1, 0, 0, 0, 0, 81, 1, 0, 0, 0, 0, 83, 1, 0, 0, 0, 0, 85, 1, 0, 0, 0, 0, 87, 1, 0, 0, 0, 0, 89, 1, 0, 0, 0, 0, 91, 1, 0, 0, 0, 0, 93, 1, 0, 0, 0, 0, 95, 1, 0, 0, 0, 1, 107, 1, 0, 0, 0, 3, 109, 1, 0, 0, 0, 5, 111, 1, 0, 0, 0, 7, 113, 1, 0, 0, 0, 9, 115, 1, 0, 0, 0, 11, 117, 1, 0, 0, 0, 13, 119, 1, 0, 0, 0, 15, 122, 1, 0, 0, 0, 17, 125, 1, 0, 0, 0, 19, 127, 1, 0, 0, 0, 21, 130, 1, 0, 0, 0, 23, 132, 1, 0, 0, 0, 25, 135, 1, 0, 0, 0, 27, 137, 1, 0, 0, 0, 29, 140, 1, 0, 0, 0, 31, 143, 1, 0, 0, 0, 33, 147, 1, 0, 0, 0, 35, 150, 1, 0, 0, 0, 37, 157, 1, 0, 0, 0, 39, 160, 1, 0, 0, 0, 41, 168, 1, 0, 0, 0, 43, 171, 1, 0, 0, 0, 45, 180, 1, 0, 0, 0, 47, 191, 1, 0, 0, 0, 49, 203, 1, 0, 0, 0, 51, 220, 1, 0, 0, 0, 53, 222, 1, 0, 0, 0, 55, 224, 1, 0, 0, 0, 57, 232, 1, 0, 0, 0, 59, 238, 1, 0, 0, 0, 61, 240, 1, 0, 0, 0, 63, 242, 1, 0, 0, 0, 65, 244, 1, 0, 0, 0, 67, 246, 1, 0, 0, 0, 69, 248, 1, 0, 0, 0, 71, 250, 1, 0, 0, 0, 73, 252, 1, 0, 0, 0, 75, 284, 1, 0, 0, 0, 77, 286, 1, 0, 0, 0, 79, 289, 1, 0, 0, 0, 81, 341, 1, 0, 0, 0, 83, 343, 1, 0, 0, 0, 85, 351, 1, 0, 0, 0, 87, 376, 1, 0, 0, 0, 89, 380, 1, 0, 0, 0, 91, 387, 1, 0, 0, 0, 93, 403, 1, 0, 0, 0, 95, 409, 1, 0, 0, 0, 97, 411, 1, 0, 0, 0, 99, 413, 1, 0, 0, 0, 101, 415, 1, 0, 0, 0, 103, 424, 1, 0, 0, 0, 105, 426, 1, 0, 0, 0, 107, 108, 5, 43, 0, 0, 108, 2, 1, 0, 0, 0, 109, 110, 5, 45, 0, 0, 110, 4, 1, 0, 0, 0, 111, 112, 5, 42, 0, 0, 112, 6, 1, 0, 0, 0, 113, 114, 5, 47, 0, 0, 114, 8, 1, 0, 0, 0, 115, 116, 5, 37, 0, 0, 116, 10, 1, 0, 0, 0, 117, 118, 5, 94, 0, 0, 118, 12, 1, 0, 0, 0, 119, 120, 5, 61, 0, 0, 120, 121, 5, 61, 0, 0, 121, 14, 1, 0, 0, 0, 122, 123, 5, 33, 0, 0, 123, 124, 5, 61, 0, 0, 124, 16, 1, 0, 0, 0, 125, 126, 5, 62, 0, 0, 126, 18, 1, 0, 0, 0, 127, 128, 5, 62, 0, 0, 128, 129, 5, 61, 0, 0, 129, 20, 1, 0, 0, 0, 130, 131, 5, 60, 0, 0, 131, 22, 1, 0, 0, 0, 132, 133, 5, 60, 0, 0, 133, 134, 5, 61, 0, 0, 134, 24, 1, 0, 0, 0, 135, 136, 5, 61, 0, 0, 136, 26, 1, 0, 0, 0, 137, 138, 5, 61, 0, 0, 138, 139, 5, 126, 0, 0, 139, 28, 1, 0, 0, 0, 140, 141, 5, 33, 0, 0, 141, 142, 5, 126, 0, 0, 142, 30, 1, 0, 0, 0, 143, 144, 5, 97, 0, 0, 144, 145, 5, 110, 0, 0, 145, 146, 5, 100, 0, 0, 146, 32, 1, 0, 0, 0, 147, 148, 5, 111, 0, 0, 148, 149, 5, 114, 0, 0, 149, 34, 1, 0, 0, 0, 150, 151, 5, 117, 0, 0, 151, 152, 5, 110, 0, 0, 152, 153, 5, 108, 0, 0, 153, 154, 5, 101, 0, 0, 154, 155, 5, 115, 0, 0, 155, 156, 5, 115, 0, 0, 156, 36, 1, 0, 0, 0, 157, 158, 5, 98, 0, 0, 158, 159, 5, 121, 0, 0, 159, 38, 1, 0, 0, 0, 160, 161, 5, 119, 0, 0, 161, 162, 5, 105, 0, 0, 162, 163, 5, 116, 0, 0, 163, 164, 5, 104, 0, 0, 164, 165, 5, 111, 0, 0, 165, 166, 5, 117, 0, 0, 166, 167, 5, 116, 0, 0, 167, 40, 1, 0, 0, 0, 168, 169, 5, 111, 0, 0, 169, 170, 5, 110, 0, 0, 170, 42, 1, 0, 0, 0, 171, 172, 5, 105, 0, 0, 172, 173, 5, 103, 0, 0, 173, 174, 5, 110, 0, 0, 174, 175, 5, 111, 0, 0, 175, 176, 5, 114, 0, 0, 176, 177, 5, 105, 0, 0, 177, 178, 5, 110, 0, 0, 178, 179, 5, 103, 0, 0, 179, 44, 1, 0, 0, 0, 180, 181, 5, 103, 0, 0, 181, 182, 5, 114, 0, 0, 182, 183, 5, 111, 0, 0, 183, 184, 5, 117, 0, 0, 184, 185, 5, 112, 0, 0, 185, 186, 5, 95, 0, 0, 186, 187, 5, 108, 0, 0, 187, 188, 5, 101, 0, 0, 188, 189, 5, 102, 0, 0, 189, 190, 5, 116, 0, 0, 190, 46, 1, 0, 0, 0, 191, 192, 5, 103, 0, 0, 192, 193, 5, 114, 0, 0, 193, 194, 5, 111, 0, 0, 194, 195, 5, 117, 0, 0, 195, 196, 5, 112, 0, 0, 196, 197, 5, 95, 0, 0, 197, 198, 5, 114, 0, 0, 198, 199, 5, 105, 0, 0, 199, 200, 5, 103, 0, 0, 200, 201, 5, 104, 0, 0, 201, 202, 5, 116, 0, 0, 202, 48, 1, 0, 0, 0, 203, 204, 5, 98, 0, 0, 204, 205, 5, 111, 0, 0, 205, 206, 5, 111, 0, 0, 206, 207, 5, 108, 0, 0, 207, 50, 1, 0, 0, 0, 208, 209, 5, 111, 0, 0, 209, 210, 5, 102, 0, 0, 210, 211, 5, 102, 0, 0, 211, 212, 5, 115, 0, 0, 212, 213, 5, 101, 0, 0, 213, 221, 5, 116, 0, 0, 214, 215, 5, 79, 0, 0, 215, 216, 5, 70, 0, 0, 216, 217, 5, 70, 0, 0, 217, 218, 5, 83, 0, 0, 218, 219, 5, 69, 0, 0, 219, 221, 5, 84, 0, 0, 220, 208, 1, 0, 0, 0, 220, 214, 1, 0, 0, 0, 221, 52, 1, 0, 0, 0, 222, 223, 5, 64, 0, 0, 223, 54, 1, 0, 0, 0, 224, 225, 5, 115, 0, 0, 225, 226, 5, 116, 0, 0, 226, 227, 5, 97, 0, 0, 227, 228, 5, 114, 0, 0, 228, 229, 5, 116, 0, 0, 229, 230, 5, 40, 0, 0, 230, 231, 5, 41, 0, 0, 231, 56, 1, 0, 0, 0, 232, 233, 5, 101, 0, 0, 233, 234, 5, 110, 0, 0, 234, 235, 5, 100, 0, 0, 235, 236, 5, 40, 0, 0, 236, 237, 5, 41, 0, 0, 237, 58, 1, 0, 0, 0, 238, 239, 5, 123, 0, 0, 239, 60, 1, 0, 0, 0, 240, 241, 5, 125, 0, 0, 241, 62, 1, 0, 0, 0, 242, 243, 5, 91, 0, 0, 243, 64, 1, 0, 0, 0, 244, 245, 5, 93, 0, 0, 245, 66, 1, 0, 0, 0, 246, 247, 5, 40, 0, 0, 247, 68, 1, 0, 0, 0, 248, 249, 5, 41, 0, 0, 249, 70, 1, 0, 0, 0, 250, 251, 5, 58, 0, 0, 251, 72, 1, 0, 0, 0, 252, 253, 5, 44, 0, 0, 253, 74, 1, 0, 0, 0, 254, 260, 3, 97, 48, 0, 255, 256, 5, 92, 0, 0, 256, 259, 7, 0, 0, 0, 257, 259, 8, 1, 0, 0, 258, 255, 1, 0, 0, 0, 258, 257, 1, 0, 0, 0, 259, 262, 1, 0, 0, 0, 260, 258, 1, 0, 0, 0, 260, 261, 1, 0, 0, 0, 261, 263, 1, 0, 0, 0, 262, 260, 1, 0, 0, 0, 263, 264, 3, 97, 48, 0, 264, 285, 1, 0, 0, 0, 265, 271, 3, 99, 49, 0, 266, 267, 5, 92, 0, 0, 267, 270, 7, 2, 0, 0, 268, 270, 8, 3, 0, 0, 269, 266, 1, 0, 0, 0, 269, 268, 1, 0, 0, 0, 270, 273, 1, 0, 0, 0, 271, 269, 1, 0, 0, 0, 271, 272, 1, 0, 0, 0, 272, 274, 1, 0, 0, 0, 273, 271, 1, 0, 0, 0, 274, 275, 3, 99, 49, 0, 275, 285, 1, 0, 0, 0, 276, 280, 5, 96, 0, 0, 277, 279, 8, 4, 0, 0, 278, 277, 1, 0, 0, 0, 279, 282, 1, 0, 0, 0, 280, 278, 1, 0, 0, 0, 280, 281, 1, 0, 0, 0, 281, 283, 1, 0, 0, 0, 282, 280, 1, 0, 0, 0, 283, 285, 5, 96, 0, 0, 284, 254, 1, 0, 0, 0, 284, 265, 1, 0, 0, 0, 284, 276, 1, 0, 0, 0, 285, 76, 1, 0, 0, 0, 286, 287, 7, 5, 0, 0, 287, 78, 1, 0, 0, 0, 288, 290, 3, 103, 51, 0, 289, 288, 1, 0, 0, 0, 290, 291, 1, 0, 0, 0, 291, 289, 1, 0, 0, 0, 291, 292, 1, 0, 0, 0, 292, 80, 1, 0, 0, 0, 293, 295, 3, 103, 51, 0, 294, 293, 1, 0, 0, 0, 295, 296, 1, 0, 0, 0, 296, 294, 1, 0, 0, 0, 296, 297, 1, 0, 0, 0, 297, 298, 1, 0, 0, 0, 298, 302, 3, 105, 52, 0, 299, 301, 3, 103, 51, 0, 300, 299, 1, 0, 0, 0, 301, 304, 1, 0, 0, 0, 302, 300, 1, 0, 0, 0, 302, 303, 1, 0, 0, 0, 303, 342, 1, 0, 0, 0, 304, 302, 1, 0, 0, 0, 305, 307, 3, 105, 52, 0, 306, 308, 3, 103, 51, 0, 307, 306, 1, 0, 0, 0, 308, 309, 1, 0, 0, 0, 309, 307, 1, 0, 0, 0, 309, 310, 1, 0, 0, 0, 310, 342, 1, 0, 0, 0, 311, 313, 3, 103, 51, 0, 312, 311, 1, 0, 0, 0, 313, 314, 1, 0, 0, 0, 314, 312, 1, 0, 0, 0, 314, 315, 1, 0, 0, 0, 315, 323, 1, 0, 0, 0, 316, 320, 3, 105, 52, 0, 317, 319, 3, 103, 51, 0, 318, 317, 1, 0, 0, 0, 319, 322, 1, 0, 0, 0, 320, 318, 1, 0, 0, 0, 320, 321, 1, 0, 0, 0, 321, 324, 1, 0, 0, 0, 322, 320, 1, 0, 0, 0, 323, 316, 1, 0, 0, 0, 323, 324, 1, 0, 0, 0, 324, 325, 1, 0, 0, 0, 325, 326, 3, 101, 50, 0, 326, 342, 1, 0, 0, 0, 327, 329, 3, 105, 52, 0, 328, 330, 3, 103, 51, 0, 329, 328, 1, 0, 0, 0, 330, 331, 1, 0, 0, 0, 331, 329, 1, 0, 0, 0, 331, 332, 1, 0, 0, 0, 332, 333, 1, 0, 0, 0, 333, 334, 3, 101, 50, 0, 334, 342, 1, 0, 0, 0, 335, 336, 7, 6, 0, 0, 336, 337, 7, 7, 0, 0, 337, 342, 7, 8, 0, 0, 338, 339, 7, 7, 0, 0, 339, 340, 7, 9, 0, 0, 340, 342, 7, 7, 0, 0, 341, 294, 1, 0, 0, 0, 341, 305, 1, 0, 0, 0, 341, 312, 1, 0, 0, 0, 341, 327, 1, 0, 0, 0, 341, 335, 1, 0, 0, 0, 341, 338, 1, 0, 0, 0, 342, 82, 1, 0, 0, 0, 343, 344, 5, 48, 0, 0, 344, 345, 5, 120, 0, 0, 345, 347, 1, 0, 0, 0, 346, 348, 7, 10, 0, 0, 347, 346, 1, 0, 0, 0, 348, 349, 1, 0, 0, 0, 349, 347, 1, 0, 0, 0, 349, 350, 1, 0, 0, 0, 350, 84, 1, 0, 0, 0, 351, 362, 3, 71, 35, 0, 352, 354, 3, 103, 51, 0, 353, 352, 1, 0, 0, 0, 354, 355, 1, 0, 0, 0, 355, 353, 1, 0, 0, 0, 355, 356, 1, 0, 0, 0, 356, 358, 1, 0, 0, 0, 357, 359, 7, 11, 0, 0, 358, 357, 1, 0, 0, 0, 359, 360, 1, 0, 0, 0, 360, 358, 1, 0, 0, 0, 360, 361, 1, 0, 0, 0, 361, 363, 1, 0, 0, 0, 362, 353, 1, 0, 0, 0, 363, 364, 1, 0, 0, 0, 364, 362, 1, 0, 0, 0, 364, 365, 1, 0, 0, 0, 365, 86, 1, 0, 0, 0, 366, 368, 3, 103, 51, 0, 367, 366, 1, 0, 0, 0, 368, 369, 1, 0, 0, 0, 369, 367, 1, 0, 0, 0, 369, 370, 1, 0, 0, 0, 370, 372, 1, 0, 0, 0, 371, 373, 7, 11, 0, 0, 372, 371, 1, 0, 0, 0, 373, 374, 1, 0, 0, 0, 374, 372, 1, 0, 0, 0, 374, 375, 1, 0, 0, 0, 375, 377, 1, 0, 0, 0, 376, 367, 1, 0, 0, 0, 377, 378, 1, 0, 0, 0, 378, 376, 1, 0, 0, 0, 378, 379, 1, 0, 0, 0, 379, 88, 1, 0, 0, 0, 380, 384, 7, 12, 0, 0, 381, 383, 7, 13, 0, 0, 382, 381, 1, 0, 0, 0, 383, 386, 1, 0, 0, 0, 384, 382, 1, 0, 0, 0, 384, 385, 1, 0, 0, 0, 385, 90, 1, 0, 0, 0, 386, 384, 1, 0, 0, 0, 387, 391, 5, 35, 0, 0, 388, 390, 8, 14, 0, 0, 389, 388, 1, 0, 0, 0, 390, 393, 1, 0, 0, 0, 391, 389, 1, 0, 0, 0, 391, 392, 1, 0, 0, 0, 392, 395, 1, 0, 0, 0, 393, 391, 1, 0, 0, 0, 394, 396, 5, 13, 0, 0, 395, 394, 1, 0, 0, 0, 395, 396, 1, 0, 0, 0, 396, 398, 1, 0, 0, 0, 397, 399, 5, 10, 0, 0, 398, 397, 1, 0, 0, 0, 398, 399, 1, 0, 0, 0, 399, 400, 1, 0, 0, 0, 400, 401, 6, 45, 0, 0, 401, 92, 1, 0, 0, 0, 402, 404, 7, 15, 0, 0, 403, 402, 1, 0, 0, 0, 404, 405, 1, 0, 0, 0, 405, 403, 1, 0, 0, 0, 405, 406, 1, 0, 0, 0, 406, 407, 1, 0, 0, 0, 407, 408, 6, 46, 0, 0, 408, 94, 1, 0, 0, 0, 409, 410, 9, 0, 0, 0, 410, 96, 1, 0, 0, 0, 411, 412, 5, 39, 0, 0, 412, 98, 1, 0, 0, 0, 413, 414, 5, 34, 0, 0, 414, 100, 1, 0, 0, 0, 415, 417, 7, 16, 0, 0, 416, 418, 7, 17, 0, 0, 417, 416, 1, 0, 0, 0, 417, 418, 1, 0, 0, 0, 418, 420, 1, 0, 0, 0, 419, 421, 3, 103, 51, 0, 420, 419, 1, 0, 0, 0, 421, 422, 1, 0, 0, 0, 422, 420, 1, 0, 0, 0, 422, 423, 1, 0, 0, 0, 423, 102, 1, 0, 0, 0, 424, 425, 7, 18, 0, 0, 425, 104, 1, 0, 0, 0, 426, 427, 5, 46, 0, 0, 427, 106, 1, 0, 0, 0, 31, 0, 220, 258, 260, 269, 271, 280, 284, 291, 296, 302, 309, 314, 320, 323, 331, 341, 349, 355, 360, 364, 369, 374, 378, 384, 391, 395, 398, 405, 417, 422, 1, 0, 1, 0] \ No newline at end of file diff --git a/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/parser/PromqlBaseLexer.java b/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/parser/PromqlBaseLexer.java new file mode 100644 index 0000000000000..7aa7c95e3916b --- /dev/null +++ b/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/parser/PromqlBaseLexer.java @@ -0,0 +1,421 @@ +// ANTLR GENERATED CODE: DO NOT EDIT +package org.elasticsearch.xpack.esql.parser; + +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +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 PromqlBaseLexer extends LexerConfig { + static { RuntimeMetaData.checkVersion("4.13.1", RuntimeMetaData.VERSION); } + + protected static final DFA[] _decisionToDFA; + protected static final PredictionContextCache _sharedContextCache = + new PredictionContextCache(); + public static final int + PLUS=1, MINUS=2, ASTERISK=3, SLASH=4, PERCENT=5, CARET=6, EQ=7, NEQ=8, + GT=9, GTE=10, LT=11, LTE=12, LABEL_EQ=13, LABEL_RGX=14, LABEL_RGX_NEQ=15, + AND=16, OR=17, UNLESS=18, BY=19, WITHOUT=20, ON=21, IGNORING=22, GROUP_LEFT=23, + GROUP_RIGHT=24, BOOL=25, OFFSET=26, AT=27, AT_START=28, AT_END=29, LCB=30, + RCB=31, LSB=32, RSB=33, LP=34, RP=35, COLON=36, COMMA=37, STRING=38, INTEGER_VALUE=39, + DECIMAL_VALUE=40, HEXADECIMAL=41, TIME_VALUE_WITH_COLON=42, TIME_VALUE=43, + IDENTIFIER=44, COMMENT=45, WS=46, UNRECOGNIZED=47; + public static String[] channelNames = { + "DEFAULT_TOKEN_CHANNEL", "HIDDEN" + }; + + public static String[] modeNames = { + "DEFAULT_MODE" + }; + + private static String[] makeRuleNames() { + return new String[] { + "PLUS", "MINUS", "ASTERISK", "SLASH", "PERCENT", "CARET", "EQ", "NEQ", + "GT", "GTE", "LT", "LTE", "LABEL_EQ", "LABEL_RGX", "LABEL_RGX_NEQ", "AND", + "OR", "UNLESS", "BY", "WITHOUT", "ON", "IGNORING", "GROUP_LEFT", "GROUP_RIGHT", + "BOOL", "OFFSET", "AT", "AT_START", "AT_END", "LCB", "RCB", "LSB", "RSB", + "LP", "RP", "COLON", "COMMA", "STRING", "ESC_CHARS", "INTEGER_VALUE", + "DECIMAL_VALUE", "HEXADECIMAL", "TIME_VALUE_WITH_COLON", "TIME_VALUE", + "IDENTIFIER", "COMMENT", "WS", "UNRECOGNIZED", "SQ", "DQ", "EXPONENT", + "DIGIT", "DOT" + }; + } + public static final String[] ruleNames = makeRuleNames(); + + private static String[] makeLiteralNames() { + return new String[] { + null, "'+'", "'-'", "'*'", "'/'", "'%'", "'^'", "'=='", "'!='", "'>'", + "'>='", "'<'", "'<='", "'='", "'=~'", "'!~'", "'and'", "'or'", "'unless'", + "'by'", "'without'", "'on'", "'ignoring'", "'group_left'", "'group_right'", + "'bool'", null, "'@'", "'start()'", "'end()'", "'{'", "'}'", "'['", "']'", + "'('", "')'", "':'", "','" + }; + } + private static final String[] _LITERAL_NAMES = makeLiteralNames(); + private static String[] makeSymbolicNames() { + return new String[] { + null, "PLUS", "MINUS", "ASTERISK", "SLASH", "PERCENT", "CARET", "EQ", + "NEQ", "GT", "GTE", "LT", "LTE", "LABEL_EQ", "LABEL_RGX", "LABEL_RGX_NEQ", + "AND", "OR", "UNLESS", "BY", "WITHOUT", "ON", "IGNORING", "GROUP_LEFT", + "GROUP_RIGHT", "BOOL", "OFFSET", "AT", "AT_START", "AT_END", "LCB", "RCB", + "LSB", "RSB", "LP", "RP", "COLON", "COMMA", "STRING", "INTEGER_VALUE", + "DECIMAL_VALUE", "HEXADECIMAL", "TIME_VALUE_WITH_COLON", "TIME_VALUE", + "IDENTIFIER", "COMMENT", "WS", "UNRECOGNIZED" + }; + } + 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; + } + + + @SuppressWarnings("this-escape") + public PromqlBaseLexer(CharStream input) { + super(input); + _interp = new LexerATNSimulator(this,_ATN,_decisionToDFA,_sharedContextCache); + } + + @Override + public String getGrammarFileName() { return "PromqlBaseLexer.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/\u01ac\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\u0007\n\u0002\u000b"+ + "\u0007\u000b\u0002\f\u0007\f\u0002\r\u0007\r\u0002\u000e\u0007\u000e\u0002"+ + "\u000f\u0007\u000f\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\u0002"+ + "\u001b\u0007\u001b\u0002\u001c\u0007\u001c\u0002\u001d\u0007\u001d\u0002"+ + "\u001e\u0007\u001e\u0002\u001f\u0007\u001f\u0002 \u0007 \u0002!\u0007"+ + "!\u0002\"\u0007\"\u0002#\u0007#\u0002$\u0007$\u0002%\u0007%\u0002&\u0007"+ + "&\u0002\'\u0007\'\u0002(\u0007(\u0002)\u0007)\u0002*\u0007*\u0002+\u0007"+ + "+\u0002,\u0007,\u0002-\u0007-\u0002.\u0007.\u0002/\u0007/\u00020\u0007"+ + "0\u00021\u00071\u00022\u00072\u00023\u00073\u00024\u00074\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"+ + "\u0001\u0006\u0001\u0006\u0001\u0007\u0001\u0007\u0001\u0007\u0001\b\u0001"+ + "\b\u0001\t\u0001\t\u0001\t\u0001\n\u0001\n\u0001\u000b\u0001\u000b\u0001"+ + "\u000b\u0001\f\u0001\f\u0001\r\u0001\r\u0001\r\u0001\u000e\u0001\u000e"+ + "\u0001\u000e\u0001\u000f\u0001\u000f\u0001\u000f\u0001\u000f\u0001\u0010"+ + "\u0001\u0010\u0001\u0010\u0001\u0011\u0001\u0011\u0001\u0011\u0001\u0011"+ + "\u0001\u0011\u0001\u0011\u0001\u0011\u0001\u0012\u0001\u0012\u0001\u0012"+ + "\u0001\u0013\u0001\u0013\u0001\u0013\u0001\u0013\u0001\u0013\u0001\u0013"+ + "\u0001\u0013\u0001\u0013\u0001\u0014\u0001\u0014\u0001\u0014\u0001\u0015"+ + "\u0001\u0015\u0001\u0015\u0001\u0015\u0001\u0015\u0001\u0015\u0001\u0015"+ + "\u0001\u0015\u0001\u0015\u0001\u0016\u0001\u0016\u0001\u0016\u0001\u0016"+ + "\u0001\u0016\u0001\u0016\u0001\u0016\u0001\u0016\u0001\u0016\u0001\u0016"+ + "\u0001\u0016\u0001\u0017\u0001\u0017\u0001\u0017\u0001\u0017\u0001\u0017"+ + "\u0001\u0017\u0001\u0017\u0001\u0017\u0001\u0017\u0001\u0017\u0001\u0017"+ + "\u0001\u0017\u0001\u0018\u0001\u0018\u0001\u0018\u0001\u0018\u0001\u0018"+ + "\u0001\u0019\u0001\u0019\u0001\u0019\u0001\u0019\u0001\u0019\u0001\u0019"+ + "\u0001\u0019\u0001\u0019\u0001\u0019\u0001\u0019\u0001\u0019\u0001\u0019"+ + "\u0003\u0019\u00dd\b\u0019\u0001\u001a\u0001\u001a\u0001\u001b\u0001\u001b"+ + "\u0001\u001b\u0001\u001b\u0001\u001b\u0001\u001b\u0001\u001b\u0001\u001b"+ + "\u0001\u001c\u0001\u001c\u0001\u001c\u0001\u001c\u0001\u001c\u0001\u001c"+ + "\u0001\u001d\u0001\u001d\u0001\u001e\u0001\u001e\u0001\u001f\u0001\u001f"+ + "\u0001 \u0001 \u0001!\u0001!\u0001\"\u0001\"\u0001#\u0001#\u0001$\u0001"+ + "$\u0001%\u0001%\u0001%\u0001%\u0005%\u0103\b%\n%\f%\u0106\t%\u0001%\u0001"+ + "%\u0001%\u0001%\u0001%\u0001%\u0005%\u010e\b%\n%\f%\u0111\t%\u0001%\u0001"+ + "%\u0001%\u0001%\u0005%\u0117\b%\n%\f%\u011a\t%\u0001%\u0003%\u011d\b%"+ + "\u0001&\u0001&\u0001\'\u0004\'\u0122\b\'\u000b\'\f\'\u0123\u0001(\u0004"+ + "(\u0127\b(\u000b(\f(\u0128\u0001(\u0001(\u0005(\u012d\b(\n(\f(\u0130\t"+ + "(\u0001(\u0001(\u0004(\u0134\b(\u000b(\f(\u0135\u0001(\u0004(\u0139\b"+ + "(\u000b(\f(\u013a\u0001(\u0001(\u0005(\u013f\b(\n(\f(\u0142\t(\u0003("+ + "\u0144\b(\u0001(\u0001(\u0001(\u0001(\u0004(\u014a\b(\u000b(\f(\u014b"+ + "\u0001(\u0001(\u0001(\u0001(\u0001(\u0001(\u0001(\u0001(\u0003(\u0156"+ + "\b(\u0001)\u0001)\u0001)\u0001)\u0004)\u015c\b)\u000b)\f)\u015d\u0001"+ + "*\u0001*\u0004*\u0162\b*\u000b*\f*\u0163\u0001*\u0004*\u0167\b*\u000b"+ + "*\f*\u0168\u0004*\u016b\b*\u000b*\f*\u016c\u0001+\u0004+\u0170\b+\u000b"+ + "+\f+\u0171\u0001+\u0004+\u0175\b+\u000b+\f+\u0176\u0004+\u0179\b+\u000b"+ + "+\f+\u017a\u0001,\u0001,\u0005,\u017f\b,\n,\f,\u0182\t,\u0001-\u0001-"+ + "\u0005-\u0186\b-\n-\f-\u0189\t-\u0001-\u0003-\u018c\b-\u0001-\u0003-\u018f"+ + "\b-\u0001-\u0001-\u0001.\u0004.\u0194\b.\u000b.\f.\u0195\u0001.\u0001"+ + ".\u0001/\u0001/\u00010\u00010\u00011\u00011\u00012\u00012\u00032\u01a2"+ + "\b2\u00012\u00042\u01a5\b2\u000b2\f2\u01a6\u00013\u00013\u00014\u0001"+ + "4\u0000\u00005\u0001\u0001\u0003\u0002\u0005\u0003\u0007\u0004\t\u0005"+ + "\u000b\u0006\r\u0007\u000f\b\u0011\t\u0013\n\u0015\u000b\u0017\f\u0019"+ + "\r\u001b\u000e\u001d\u000f\u001f\u0010!\u0011#\u0012%\u0013\'\u0014)\u0015"+ + "+\u0016-\u0017/\u00181\u00193\u001a5\u001b7\u001c9\u001d;\u001e=\u001f"+ + "? A!C\"E#G$I%K&M\u0000O\'Q(S)U*W+Y,[-]._/a\u0000c\u0000e\u0000g\u0000"+ + "i\u0000\u0001\u0000\u0013\b\u0000\'\'\\\\abffnnrrttvv\u0001\u0000\'\'"+ + "\b\u0000\"\"\\\\abffnnrrttvv\u0001\u0000\"\"\u0001\u0000``\u0007\u0000"+ + "\\\\abffnnrrttvv\u0002\u0000IIii\u0002\u0000NNnn\u0002\u0000FFff\u0002"+ + "\u0000AAaa\u0003\u000009AFaf\u0002\u0000AZaz\u0004\u0000::AZ__az\u0005"+ + "\u0000..0:AZ__az\u0002\u0000\n\n\r\r\u0003\u0000\t\n\r\r \u0002\u0000"+ + "EEee\u0002\u0000++--\u0001\u000009\u01c8\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\u0000"+ + "\u0013\u0001\u0000\u0000\u0000\u0000\u0015\u0001\u0000\u0000\u0000\u0000"+ + "\u0017\u0001\u0000\u0000\u0000\u0000\u0019\u0001\u0000\u0000\u0000\u0000"+ + "\u001b\u0001\u0000\u0000\u0000\u0000\u001d\u0001\u0000\u0000\u0000\u0000"+ + "\u001f\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\u00001"+ + "\u0001\u0000\u0000\u0000\u00003\u0001\u0000\u0000\u0000\u00005\u0001\u0000"+ + "\u0000\u0000\u00007\u0001\u0000\u0000\u0000\u00009\u0001\u0000\u0000\u0000"+ + "\u0000;\u0001\u0000\u0000\u0000\u0000=\u0001\u0000\u0000\u0000\u0000?"+ + "\u0001\u0000\u0000\u0000\u0000A\u0001\u0000\u0000\u0000\u0000C\u0001\u0000"+ + "\u0000\u0000\u0000E\u0001\u0000\u0000\u0000\u0000G\u0001\u0000\u0000\u0000"+ + "\u0000I\u0001\u0000\u0000\u0000\u0000K\u0001\u0000\u0000\u0000\u0000O"+ + "\u0001\u0000\u0000\u0000\u0000Q\u0001\u0000\u0000\u0000\u0000S\u0001\u0000"+ + "\u0000\u0000\u0000U\u0001\u0000\u0000\u0000\u0000W\u0001\u0000\u0000\u0000"+ + "\u0000Y\u0001\u0000\u0000\u0000\u0000[\u0001\u0000\u0000\u0000\u0000]"+ + "\u0001\u0000\u0000\u0000\u0000_\u0001\u0000\u0000\u0000\u0001k\u0001\u0000"+ + "\u0000\u0000\u0003m\u0001\u0000\u0000\u0000\u0005o\u0001\u0000\u0000\u0000"+ + "\u0007q\u0001\u0000\u0000\u0000\ts\u0001\u0000\u0000\u0000\u000bu\u0001"+ + "\u0000\u0000\u0000\rw\u0001\u0000\u0000\u0000\u000fz\u0001\u0000\u0000"+ + "\u0000\u0011}\u0001\u0000\u0000\u0000\u0013\u007f\u0001\u0000\u0000\u0000"+ + "\u0015\u0082\u0001\u0000\u0000\u0000\u0017\u0084\u0001\u0000\u0000\u0000"+ + "\u0019\u0087\u0001\u0000\u0000\u0000\u001b\u0089\u0001\u0000\u0000\u0000"+ + "\u001d\u008c\u0001\u0000\u0000\u0000\u001f\u008f\u0001\u0000\u0000\u0000"+ + "!\u0093\u0001\u0000\u0000\u0000#\u0096\u0001\u0000\u0000\u0000%\u009d"+ + "\u0001\u0000\u0000\u0000\'\u00a0\u0001\u0000\u0000\u0000)\u00a8\u0001"+ + "\u0000\u0000\u0000+\u00ab\u0001\u0000\u0000\u0000-\u00b4\u0001\u0000\u0000"+ + "\u0000/\u00bf\u0001\u0000\u0000\u00001\u00cb\u0001\u0000\u0000\u00003"+ + "\u00dc\u0001\u0000\u0000\u00005\u00de\u0001\u0000\u0000\u00007\u00e0\u0001"+ + "\u0000\u0000\u00009\u00e8\u0001\u0000\u0000\u0000;\u00ee\u0001\u0000\u0000"+ + "\u0000=\u00f0\u0001\u0000\u0000\u0000?\u00f2\u0001\u0000\u0000\u0000A"+ + "\u00f4\u0001\u0000\u0000\u0000C\u00f6\u0001\u0000\u0000\u0000E\u00f8\u0001"+ + "\u0000\u0000\u0000G\u00fa\u0001\u0000\u0000\u0000I\u00fc\u0001\u0000\u0000"+ + "\u0000K\u011c\u0001\u0000\u0000\u0000M\u011e\u0001\u0000\u0000\u0000O"+ + "\u0121\u0001\u0000\u0000\u0000Q\u0155\u0001\u0000\u0000\u0000S\u0157\u0001"+ + "\u0000\u0000\u0000U\u015f\u0001\u0000\u0000\u0000W\u0178\u0001\u0000\u0000"+ + "\u0000Y\u017c\u0001\u0000\u0000\u0000[\u0183\u0001\u0000\u0000\u0000]"+ + "\u0193\u0001\u0000\u0000\u0000_\u0199\u0001\u0000\u0000\u0000a\u019b\u0001"+ + "\u0000\u0000\u0000c\u019d\u0001\u0000\u0000\u0000e\u019f\u0001\u0000\u0000"+ + "\u0000g\u01a8\u0001\u0000\u0000\u0000i\u01aa\u0001\u0000\u0000\u0000k"+ + "l\u0005+\u0000\u0000l\u0002\u0001\u0000\u0000\u0000mn\u0005-\u0000\u0000"+ + "n\u0004\u0001\u0000\u0000\u0000op\u0005*\u0000\u0000p\u0006\u0001\u0000"+ + "\u0000\u0000qr\u0005/\u0000\u0000r\b\u0001\u0000\u0000\u0000st\u0005%"+ + "\u0000\u0000t\n\u0001\u0000\u0000\u0000uv\u0005^\u0000\u0000v\f\u0001"+ + "\u0000\u0000\u0000wx\u0005=\u0000\u0000xy\u0005=\u0000\u0000y\u000e\u0001"+ + "\u0000\u0000\u0000z{\u0005!\u0000\u0000{|\u0005=\u0000\u0000|\u0010\u0001"+ + "\u0000\u0000\u0000}~\u0005>\u0000\u0000~\u0012\u0001\u0000\u0000\u0000"+ + "\u007f\u0080\u0005>\u0000\u0000\u0080\u0081\u0005=\u0000\u0000\u0081\u0014"+ + "\u0001\u0000\u0000\u0000\u0082\u0083\u0005<\u0000\u0000\u0083\u0016\u0001"+ + "\u0000\u0000\u0000\u0084\u0085\u0005<\u0000\u0000\u0085\u0086\u0005=\u0000"+ + "\u0000\u0086\u0018\u0001\u0000\u0000\u0000\u0087\u0088\u0005=\u0000\u0000"+ + "\u0088\u001a\u0001\u0000\u0000\u0000\u0089\u008a\u0005=\u0000\u0000\u008a"+ + "\u008b\u0005~\u0000\u0000\u008b\u001c\u0001\u0000\u0000\u0000\u008c\u008d"+ + "\u0005!\u0000\u0000\u008d\u008e\u0005~\u0000\u0000\u008e\u001e\u0001\u0000"+ + "\u0000\u0000\u008f\u0090\u0005a\u0000\u0000\u0090\u0091\u0005n\u0000\u0000"+ + "\u0091\u0092\u0005d\u0000\u0000\u0092 \u0001\u0000\u0000\u0000\u0093\u0094"+ + "\u0005o\u0000\u0000\u0094\u0095\u0005r\u0000\u0000\u0095\"\u0001\u0000"+ + "\u0000\u0000\u0096\u0097\u0005u\u0000\u0000\u0097\u0098\u0005n\u0000\u0000"+ + "\u0098\u0099\u0005l\u0000\u0000\u0099\u009a\u0005e\u0000\u0000\u009a\u009b"+ + "\u0005s\u0000\u0000\u009b\u009c\u0005s\u0000\u0000\u009c$\u0001\u0000"+ + "\u0000\u0000\u009d\u009e\u0005b\u0000\u0000\u009e\u009f\u0005y\u0000\u0000"+ + "\u009f&\u0001\u0000\u0000\u0000\u00a0\u00a1\u0005w\u0000\u0000\u00a1\u00a2"+ + "\u0005i\u0000\u0000\u00a2\u00a3\u0005t\u0000\u0000\u00a3\u00a4\u0005h"+ + "\u0000\u0000\u00a4\u00a5\u0005o\u0000\u0000\u00a5\u00a6\u0005u\u0000\u0000"+ + "\u00a6\u00a7\u0005t\u0000\u0000\u00a7(\u0001\u0000\u0000\u0000\u00a8\u00a9"+ + "\u0005o\u0000\u0000\u00a9\u00aa\u0005n\u0000\u0000\u00aa*\u0001\u0000"+ + "\u0000\u0000\u00ab\u00ac\u0005i\u0000\u0000\u00ac\u00ad\u0005g\u0000\u0000"+ + "\u00ad\u00ae\u0005n\u0000\u0000\u00ae\u00af\u0005o\u0000\u0000\u00af\u00b0"+ + "\u0005r\u0000\u0000\u00b0\u00b1\u0005i\u0000\u0000\u00b1\u00b2\u0005n"+ + "\u0000\u0000\u00b2\u00b3\u0005g\u0000\u0000\u00b3,\u0001\u0000\u0000\u0000"+ + "\u00b4\u00b5\u0005g\u0000\u0000\u00b5\u00b6\u0005r\u0000\u0000\u00b6\u00b7"+ + "\u0005o\u0000\u0000\u00b7\u00b8\u0005u\u0000\u0000\u00b8\u00b9\u0005p"+ + "\u0000\u0000\u00b9\u00ba\u0005_\u0000\u0000\u00ba\u00bb\u0005l\u0000\u0000"+ + "\u00bb\u00bc\u0005e\u0000\u0000\u00bc\u00bd\u0005f\u0000\u0000\u00bd\u00be"+ + "\u0005t\u0000\u0000\u00be.\u0001\u0000\u0000\u0000\u00bf\u00c0\u0005g"+ + "\u0000\u0000\u00c0\u00c1\u0005r\u0000\u0000\u00c1\u00c2\u0005o\u0000\u0000"+ + "\u00c2\u00c3\u0005u\u0000\u0000\u00c3\u00c4\u0005p\u0000\u0000\u00c4\u00c5"+ + "\u0005_\u0000\u0000\u00c5\u00c6\u0005r\u0000\u0000\u00c6\u00c7\u0005i"+ + "\u0000\u0000\u00c7\u00c8\u0005g\u0000\u0000\u00c8\u00c9\u0005h\u0000\u0000"+ + "\u00c9\u00ca\u0005t\u0000\u0000\u00ca0\u0001\u0000\u0000\u0000\u00cb\u00cc"+ + "\u0005b\u0000\u0000\u00cc\u00cd\u0005o\u0000\u0000\u00cd\u00ce\u0005o"+ + "\u0000\u0000\u00ce\u00cf\u0005l\u0000\u0000\u00cf2\u0001\u0000\u0000\u0000"+ + "\u00d0\u00d1\u0005o\u0000\u0000\u00d1\u00d2\u0005f\u0000\u0000\u00d2\u00d3"+ + "\u0005f\u0000\u0000\u00d3\u00d4\u0005s\u0000\u0000\u00d4\u00d5\u0005e"+ + "\u0000\u0000\u00d5\u00dd\u0005t\u0000\u0000\u00d6\u00d7\u0005O\u0000\u0000"+ + "\u00d7\u00d8\u0005F\u0000\u0000\u00d8\u00d9\u0005F\u0000\u0000\u00d9\u00da"+ + "\u0005S\u0000\u0000\u00da\u00db\u0005E\u0000\u0000\u00db\u00dd\u0005T"+ + "\u0000\u0000\u00dc\u00d0\u0001\u0000\u0000\u0000\u00dc\u00d6\u0001\u0000"+ + "\u0000\u0000\u00dd4\u0001\u0000\u0000\u0000\u00de\u00df\u0005@\u0000\u0000"+ + "\u00df6\u0001\u0000\u0000\u0000\u00e0\u00e1\u0005s\u0000\u0000\u00e1\u00e2"+ + "\u0005t\u0000\u0000\u00e2\u00e3\u0005a\u0000\u0000\u00e3\u00e4\u0005r"+ + "\u0000\u0000\u00e4\u00e5\u0005t\u0000\u0000\u00e5\u00e6\u0005(\u0000\u0000"+ + "\u00e6\u00e7\u0005)\u0000\u0000\u00e78\u0001\u0000\u0000\u0000\u00e8\u00e9"+ + "\u0005e\u0000\u0000\u00e9\u00ea\u0005n\u0000\u0000\u00ea\u00eb\u0005d"+ + "\u0000\u0000\u00eb\u00ec\u0005(\u0000\u0000\u00ec\u00ed\u0005)\u0000\u0000"+ + "\u00ed:\u0001\u0000\u0000\u0000\u00ee\u00ef\u0005{\u0000\u0000\u00ef<"+ + "\u0001\u0000\u0000\u0000\u00f0\u00f1\u0005}\u0000\u0000\u00f1>\u0001\u0000"+ + "\u0000\u0000\u00f2\u00f3\u0005[\u0000\u0000\u00f3@\u0001\u0000\u0000\u0000"+ + "\u00f4\u00f5\u0005]\u0000\u0000\u00f5B\u0001\u0000\u0000\u0000\u00f6\u00f7"+ + "\u0005(\u0000\u0000\u00f7D\u0001\u0000\u0000\u0000\u00f8\u00f9\u0005)"+ + "\u0000\u0000\u00f9F\u0001\u0000\u0000\u0000\u00fa\u00fb\u0005:\u0000\u0000"+ + "\u00fbH\u0001\u0000\u0000\u0000\u00fc\u00fd\u0005,\u0000\u0000\u00fdJ"+ + "\u0001\u0000\u0000\u0000\u00fe\u0104\u0003a0\u0000\u00ff\u0100\u0005\\"+ + "\u0000\u0000\u0100\u0103\u0007\u0000\u0000\u0000\u0101\u0103\b\u0001\u0000"+ + "\u0000\u0102\u00ff\u0001\u0000\u0000\u0000\u0102\u0101\u0001\u0000\u0000"+ + "\u0000\u0103\u0106\u0001\u0000\u0000\u0000\u0104\u0102\u0001\u0000\u0000"+ + "\u0000\u0104\u0105\u0001\u0000\u0000\u0000\u0105\u0107\u0001\u0000\u0000"+ + "\u0000\u0106\u0104\u0001\u0000\u0000\u0000\u0107\u0108\u0003a0\u0000\u0108"+ + "\u011d\u0001\u0000\u0000\u0000\u0109\u010f\u0003c1\u0000\u010a\u010b\u0005"+ + "\\\u0000\u0000\u010b\u010e\u0007\u0002\u0000\u0000\u010c\u010e\b\u0003"+ + "\u0000\u0000\u010d\u010a\u0001\u0000\u0000\u0000\u010d\u010c\u0001\u0000"+ + "\u0000\u0000\u010e\u0111\u0001\u0000\u0000\u0000\u010f\u010d\u0001\u0000"+ + "\u0000\u0000\u010f\u0110\u0001\u0000\u0000\u0000\u0110\u0112\u0001\u0000"+ + "\u0000\u0000\u0111\u010f\u0001\u0000\u0000\u0000\u0112\u0113\u0003c1\u0000"+ + "\u0113\u011d\u0001\u0000\u0000\u0000\u0114\u0118\u0005`\u0000\u0000\u0115"+ + "\u0117\b\u0004\u0000\u0000\u0116\u0115\u0001\u0000\u0000\u0000\u0117\u011a"+ + "\u0001\u0000\u0000\u0000\u0118\u0116\u0001\u0000\u0000\u0000\u0118\u0119"+ + "\u0001\u0000\u0000\u0000\u0119\u011b\u0001\u0000\u0000\u0000\u011a\u0118"+ + "\u0001\u0000\u0000\u0000\u011b\u011d\u0005`\u0000\u0000\u011c\u00fe\u0001"+ + "\u0000\u0000\u0000\u011c\u0109\u0001\u0000\u0000\u0000\u011c\u0114\u0001"+ + "\u0000\u0000\u0000\u011dL\u0001\u0000\u0000\u0000\u011e\u011f\u0007\u0005"+ + "\u0000\u0000\u011fN\u0001\u0000\u0000\u0000\u0120\u0122\u0003g3\u0000"+ + "\u0121\u0120\u0001\u0000\u0000\u0000\u0122\u0123\u0001\u0000\u0000\u0000"+ + "\u0123\u0121\u0001\u0000\u0000\u0000\u0123\u0124\u0001\u0000\u0000\u0000"+ + "\u0124P\u0001\u0000\u0000\u0000\u0125\u0127\u0003g3\u0000\u0126\u0125"+ + "\u0001\u0000\u0000\u0000\u0127\u0128\u0001\u0000\u0000\u0000\u0128\u0126"+ + "\u0001\u0000\u0000\u0000\u0128\u0129\u0001\u0000\u0000\u0000\u0129\u012a"+ + "\u0001\u0000\u0000\u0000\u012a\u012e\u0003i4\u0000\u012b\u012d\u0003g"+ + "3\u0000\u012c\u012b\u0001\u0000\u0000\u0000\u012d\u0130\u0001\u0000\u0000"+ + "\u0000\u012e\u012c\u0001\u0000\u0000\u0000\u012e\u012f\u0001\u0000\u0000"+ + "\u0000\u012f\u0156\u0001\u0000\u0000\u0000\u0130\u012e\u0001\u0000\u0000"+ + "\u0000\u0131\u0133\u0003i4\u0000\u0132\u0134\u0003g3\u0000\u0133\u0132"+ + "\u0001\u0000\u0000\u0000\u0134\u0135\u0001\u0000\u0000\u0000\u0135\u0133"+ + "\u0001\u0000\u0000\u0000\u0135\u0136\u0001\u0000\u0000\u0000\u0136\u0156"+ + "\u0001\u0000\u0000\u0000\u0137\u0139\u0003g3\u0000\u0138\u0137\u0001\u0000"+ + "\u0000\u0000\u0139\u013a\u0001\u0000\u0000\u0000\u013a\u0138\u0001\u0000"+ + "\u0000\u0000\u013a\u013b\u0001\u0000\u0000\u0000\u013b\u0143\u0001\u0000"+ + "\u0000\u0000\u013c\u0140\u0003i4\u0000\u013d\u013f\u0003g3\u0000\u013e"+ + "\u013d\u0001\u0000\u0000\u0000\u013f\u0142\u0001\u0000\u0000\u0000\u0140"+ + "\u013e\u0001\u0000\u0000\u0000\u0140\u0141\u0001\u0000\u0000\u0000\u0141"+ + "\u0144\u0001\u0000\u0000\u0000\u0142\u0140\u0001\u0000\u0000\u0000\u0143"+ + "\u013c\u0001\u0000\u0000\u0000\u0143\u0144\u0001\u0000\u0000\u0000\u0144"+ + "\u0145\u0001\u0000\u0000\u0000\u0145\u0146\u0003e2\u0000\u0146\u0156\u0001"+ + "\u0000\u0000\u0000\u0147\u0149\u0003i4\u0000\u0148\u014a\u0003g3\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\u014d\u0001\u0000\u0000\u0000\u014d\u014e\u0003e2\u0000\u014e\u0156"+ + "\u0001\u0000\u0000\u0000\u014f\u0150\u0007\u0006\u0000\u0000\u0150\u0151"+ + "\u0007\u0007\u0000\u0000\u0151\u0156\u0007\b\u0000\u0000\u0152\u0153\u0007"+ + "\u0007\u0000\u0000\u0153\u0154\u0007\t\u0000\u0000\u0154\u0156\u0007\u0007"+ + "\u0000\u0000\u0155\u0126\u0001\u0000\u0000\u0000\u0155\u0131\u0001\u0000"+ + "\u0000\u0000\u0155\u0138\u0001\u0000\u0000\u0000\u0155\u0147\u0001\u0000"+ + "\u0000\u0000\u0155\u014f\u0001\u0000\u0000\u0000\u0155\u0152\u0001\u0000"+ + "\u0000\u0000\u0156R\u0001\u0000\u0000\u0000\u0157\u0158\u00050\u0000\u0000"+ + "\u0158\u0159\u0005x\u0000\u0000\u0159\u015b\u0001\u0000\u0000\u0000\u015a"+ + "\u015c\u0007\n\u0000\u0000\u015b\u015a\u0001\u0000\u0000\u0000\u015c\u015d"+ + "\u0001\u0000\u0000\u0000\u015d\u015b\u0001\u0000\u0000\u0000\u015d\u015e"+ + "\u0001\u0000\u0000\u0000\u015eT\u0001\u0000\u0000\u0000\u015f\u016a\u0003"+ + "G#\u0000\u0160\u0162\u0003g3\u0000\u0161\u0160\u0001\u0000\u0000\u0000"+ + "\u0162\u0163\u0001\u0000\u0000\u0000\u0163\u0161\u0001\u0000\u0000\u0000"+ + "\u0163\u0164\u0001\u0000\u0000\u0000\u0164\u0166\u0001\u0000\u0000\u0000"+ + "\u0165\u0167\u0007\u000b\u0000\u0000\u0166\u0165\u0001\u0000\u0000\u0000"+ + "\u0167\u0168\u0001\u0000\u0000\u0000\u0168\u0166\u0001\u0000\u0000\u0000"+ + "\u0168\u0169\u0001\u0000\u0000\u0000\u0169\u016b\u0001\u0000\u0000\u0000"+ + "\u016a\u0161\u0001\u0000\u0000\u0000\u016b\u016c\u0001\u0000\u0000\u0000"+ + "\u016c\u016a\u0001\u0000\u0000\u0000\u016c\u016d\u0001\u0000\u0000\u0000"+ + "\u016dV\u0001\u0000\u0000\u0000\u016e\u0170\u0003g3\u0000\u016f\u016e"+ + "\u0001\u0000\u0000\u0000\u0170\u0171\u0001\u0000\u0000\u0000\u0171\u016f"+ + "\u0001\u0000\u0000\u0000\u0171\u0172\u0001\u0000\u0000\u0000\u0172\u0174"+ + "\u0001\u0000\u0000\u0000\u0173\u0175\u0007\u000b\u0000\u0000\u0174\u0173"+ + "\u0001\u0000\u0000\u0000\u0175\u0176\u0001\u0000\u0000\u0000\u0176\u0174"+ + "\u0001\u0000\u0000\u0000\u0176\u0177\u0001\u0000\u0000\u0000\u0177\u0179"+ + "\u0001\u0000\u0000\u0000\u0178\u016f\u0001\u0000\u0000\u0000\u0179\u017a"+ + "\u0001\u0000\u0000\u0000\u017a\u0178\u0001\u0000\u0000\u0000\u017a\u017b"+ + "\u0001\u0000\u0000\u0000\u017bX\u0001\u0000\u0000\u0000\u017c\u0180\u0007"+ + "\f\u0000\u0000\u017d\u017f\u0007\r\u0000\u0000\u017e\u017d\u0001\u0000"+ + "\u0000\u0000\u017f\u0182\u0001\u0000\u0000\u0000\u0180\u017e\u0001\u0000"+ + "\u0000\u0000\u0180\u0181\u0001\u0000\u0000\u0000\u0181Z\u0001\u0000\u0000"+ + "\u0000\u0182\u0180\u0001\u0000\u0000\u0000\u0183\u0187\u0005#\u0000\u0000"+ + "\u0184\u0186\b\u000e\u0000\u0000\u0185\u0184\u0001\u0000\u0000\u0000\u0186"+ + "\u0189\u0001\u0000\u0000\u0000\u0187\u0185\u0001\u0000\u0000\u0000\u0187"+ + "\u0188\u0001\u0000\u0000\u0000\u0188\u018b\u0001\u0000\u0000\u0000\u0189"+ + "\u0187\u0001\u0000\u0000\u0000\u018a\u018c\u0005\r\u0000\u0000\u018b\u018a"+ + "\u0001\u0000\u0000\u0000\u018b\u018c\u0001\u0000\u0000\u0000\u018c\u018e"+ + "\u0001\u0000\u0000\u0000\u018d\u018f\u0005\n\u0000\u0000\u018e\u018d\u0001"+ + "\u0000\u0000\u0000\u018e\u018f\u0001\u0000\u0000\u0000\u018f\u0190\u0001"+ + "\u0000\u0000\u0000\u0190\u0191\u0006-\u0000\u0000\u0191\\\u0001\u0000"+ + "\u0000\u0000\u0192\u0194\u0007\u000f\u0000\u0000\u0193\u0192\u0001\u0000"+ + "\u0000\u0000\u0194\u0195\u0001\u0000\u0000\u0000\u0195\u0193\u0001\u0000"+ + "\u0000\u0000\u0195\u0196\u0001\u0000\u0000\u0000\u0196\u0197\u0001\u0000"+ + "\u0000\u0000\u0197\u0198\u0006.\u0000\u0000\u0198^\u0001\u0000\u0000\u0000"+ + "\u0199\u019a\t\u0000\u0000\u0000\u019a`\u0001\u0000\u0000\u0000\u019b"+ + "\u019c\u0005\'\u0000\u0000\u019cb\u0001\u0000\u0000\u0000\u019d\u019e"+ + "\u0005\"\u0000\u0000\u019ed\u0001\u0000\u0000\u0000\u019f\u01a1\u0007"+ + "\u0010\u0000\u0000\u01a0\u01a2\u0007\u0011\u0000\u0000\u01a1\u01a0\u0001"+ + "\u0000\u0000\u0000\u01a1\u01a2\u0001\u0000\u0000\u0000\u01a2\u01a4\u0001"+ + "\u0000\u0000\u0000\u01a3\u01a5\u0003g3\u0000\u01a4\u01a3\u0001\u0000\u0000"+ + "\u0000\u01a5\u01a6\u0001\u0000\u0000\u0000\u01a6\u01a4\u0001\u0000\u0000"+ + "\u0000\u01a6\u01a7\u0001\u0000\u0000\u0000\u01a7f\u0001\u0000\u0000\u0000"+ + "\u01a8\u01a9\u0007\u0012\u0000\u0000\u01a9h\u0001\u0000\u0000\u0000\u01aa"+ + "\u01ab\u0005.\u0000\u0000\u01abj\u0001\u0000\u0000\u0000\u001f\u0000\u00dc"+ + "\u0102\u0104\u010d\u010f\u0118\u011c\u0123\u0128\u012e\u0135\u013a\u0140"+ + "\u0143\u014b\u0155\u015d\u0163\u0168\u016c\u0171\u0176\u017a\u0180\u0187"+ + "\u018b\u018e\u0195\u01a1\u01a6\u0001\u0000\u0001\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); + } + } +} diff --git a/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/parser/PromqlBaseParser.interp b/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/parser/PromqlBaseParser.interp new file mode 100644 index 0000000000000..bac69afaceffb --- /dev/null +++ b/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/parser/PromqlBaseParser.interp @@ -0,0 +1,129 @@ +token literal names: +null +'+' +'-' +'*' +'/' +'%' +'^' +'==' +'!=' +'>' +'>=' +'<' +'<=' +'=' +'=~' +'!~' +'and' +'or' +'unless' +'by' +'without' +'on' +'ignoring' +'group_left' +'group_right' +'bool' +null +'@' +'start()' +'end()' +'{' +'}' +'[' +']' +'(' +')' +':' +',' +null +null +null +null +null +null +null +null +null +null + +token symbolic names: +null +PLUS +MINUS +ASTERISK +SLASH +PERCENT +CARET +EQ +NEQ +GT +GTE +LT +LTE +LABEL_EQ +LABEL_RGX +LABEL_RGX_NEQ +AND +OR +UNLESS +BY +WITHOUT +ON +IGNORING +GROUP_LEFT +GROUP_RIGHT +BOOL +OFFSET +AT +AT_START +AT_END +LCB +RCB +LSB +RSB +LP +RP +COLON +COMMA +STRING +INTEGER_VALUE +DECIMAL_VALUE +HEXADECIMAL +TIME_VALUE_WITH_COLON +TIME_VALUE +IDENTIFIER +COMMENT +WS +UNRECOGNIZED + +rule names: +singleStatement +expression +subqueryResolution +value +function +functionParams +grouping +selector +seriesMatcher +modifier +labelList +labels +label +labelName +identifier +evaluation +offset +duration +at +constant +number +string +timeValue +nonReserved + + +atn: +[4, 1, 47, 280, 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, 1, 0, 1, 0, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 3, 1, 60, 8, 1, 1, 1, 1, 1, 1, 1, 3, 1, 65, 8, 1, 1, 1, 1, 1, 1, 1, 1, 1, 3, 1, 71, 8, 1, 1, 1, 1, 1, 1, 1, 1, 1, 3, 1, 77, 8, 1, 1, 1, 1, 1, 1, 1, 1, 1, 3, 1, 83, 8, 1, 1, 1, 3, 1, 86, 8, 1, 1, 1, 1, 1, 1, 1, 1, 1, 3, 1, 92, 8, 1, 1, 1, 1, 1, 1, 1, 1, 1, 3, 1, 98, 8, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 3, 1, 107, 8, 1, 5, 1, 109, 8, 1, 10, 1, 12, 1, 112, 9, 1, 1, 2, 1, 2, 3, 2, 116, 8, 2, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 3, 2, 128, 8, 2, 1, 3, 1, 3, 1, 3, 3, 3, 133, 8, 3, 1, 4, 1, 4, 1, 4, 3, 4, 138, 8, 4, 1, 4, 1, 4, 1, 4, 1, 4, 1, 4, 1, 4, 1, 4, 1, 4, 1, 4, 1, 4, 1, 4, 1, 4, 1, 4, 3, 4, 153, 8, 4, 1, 5, 1, 5, 1, 5, 5, 5, 158, 8, 5, 10, 5, 12, 5, 161, 9, 5, 1, 6, 1, 6, 1, 6, 1, 7, 1, 7, 1, 7, 1, 7, 1, 7, 3, 7, 171, 8, 7, 1, 7, 3, 7, 174, 8, 7, 1, 8, 1, 8, 1, 8, 3, 8, 179, 8, 8, 1, 8, 3, 8, 182, 8, 8, 1, 8, 1, 8, 1, 8, 1, 8, 3, 8, 188, 8, 8, 1, 9, 1, 9, 1, 9, 1, 9, 3, 9, 194, 8, 9, 3, 9, 196, 8, 9, 1, 10, 1, 10, 1, 10, 3, 10, 201, 8, 10, 5, 10, 203, 8, 10, 10, 10, 12, 10, 206, 9, 10, 1, 10, 1, 10, 1, 11, 1, 11, 1, 11, 3, 11, 213, 8, 11, 5, 11, 215, 8, 11, 10, 11, 12, 11, 218, 9, 11, 1, 12, 1, 12, 1, 12, 3, 12, 223, 8, 12, 1, 13, 1, 13, 1, 13, 3, 13, 228, 8, 13, 1, 14, 1, 14, 3, 14, 232, 8, 14, 1, 15, 1, 15, 3, 15, 236, 8, 15, 1, 15, 1, 15, 3, 15, 240, 8, 15, 3, 15, 242, 8, 15, 1, 16, 1, 16, 3, 16, 246, 8, 16, 1, 16, 1, 16, 1, 17, 1, 17, 1, 18, 1, 18, 3, 18, 254, 8, 18, 1, 18, 1, 18, 1, 18, 3, 18, 259, 8, 18, 1, 19, 1, 19, 1, 19, 3, 19, 264, 8, 19, 1, 20, 1, 20, 1, 20, 3, 20, 269, 8, 20, 1, 21, 1, 21, 1, 22, 1, 22, 1, 22, 3, 22, 276, 8, 22, 1, 23, 1, 23, 1, 23, 0, 1, 2, 24, 0, 2, 4, 6, 8, 10, 12, 14, 16, 18, 20, 22, 24, 26, 28, 30, 32, 34, 36, 38, 40, 42, 44, 46, 0, 11, 1, 0, 1, 2, 1, 0, 3, 5, 1, 0, 7, 12, 2, 0, 16, 16, 18, 18, 1, 0, 3, 4, 1, 0, 19, 20, 1, 0, 21, 22, 1, 0, 23, 24, 2, 0, 8, 8, 13, 15, 1, 0, 28, 29, 1, 0, 16, 26, 310, 0, 48, 1, 0, 0, 0, 2, 59, 1, 0, 0, 0, 4, 127, 1, 0, 0, 0, 6, 132, 1, 0, 0, 0, 8, 152, 1, 0, 0, 0, 10, 154, 1, 0, 0, 0, 12, 162, 1, 0, 0, 0, 14, 165, 1, 0, 0, 0, 16, 187, 1, 0, 0, 0, 18, 189, 1, 0, 0, 0, 20, 197, 1, 0, 0, 0, 22, 209, 1, 0, 0, 0, 24, 219, 1, 0, 0, 0, 26, 227, 1, 0, 0, 0, 28, 231, 1, 0, 0, 0, 30, 241, 1, 0, 0, 0, 32, 243, 1, 0, 0, 0, 34, 249, 1, 0, 0, 0, 36, 258, 1, 0, 0, 0, 38, 263, 1, 0, 0, 0, 40, 268, 1, 0, 0, 0, 42, 270, 1, 0, 0, 0, 44, 275, 1, 0, 0, 0, 46, 277, 1, 0, 0, 0, 48, 49, 3, 2, 1, 0, 49, 50, 5, 0, 0, 1, 50, 1, 1, 0, 0, 0, 51, 52, 6, 1, -1, 0, 52, 53, 7, 0, 0, 0, 53, 60, 3, 2, 1, 9, 54, 60, 3, 6, 3, 0, 55, 56, 5, 34, 0, 0, 56, 57, 3, 2, 1, 0, 57, 58, 5, 35, 0, 0, 58, 60, 1, 0, 0, 0, 59, 51, 1, 0, 0, 0, 59, 54, 1, 0, 0, 0, 59, 55, 1, 0, 0, 0, 60, 110, 1, 0, 0, 0, 61, 62, 10, 10, 0, 0, 62, 64, 5, 6, 0, 0, 63, 65, 3, 18, 9, 0, 64, 63, 1, 0, 0, 0, 64, 65, 1, 0, 0, 0, 65, 66, 1, 0, 0, 0, 66, 109, 3, 2, 1, 10, 67, 68, 10, 8, 0, 0, 68, 70, 7, 1, 0, 0, 69, 71, 3, 18, 9, 0, 70, 69, 1, 0, 0, 0, 70, 71, 1, 0, 0, 0, 71, 72, 1, 0, 0, 0, 72, 109, 3, 2, 1, 9, 73, 74, 10, 7, 0, 0, 74, 76, 7, 0, 0, 0, 75, 77, 3, 18, 9, 0, 76, 75, 1, 0, 0, 0, 76, 77, 1, 0, 0, 0, 77, 78, 1, 0, 0, 0, 78, 109, 3, 2, 1, 8, 79, 80, 10, 6, 0, 0, 80, 82, 7, 2, 0, 0, 81, 83, 5, 25, 0, 0, 82, 81, 1, 0, 0, 0, 82, 83, 1, 0, 0, 0, 83, 85, 1, 0, 0, 0, 84, 86, 3, 18, 9, 0, 85, 84, 1, 0, 0, 0, 85, 86, 1, 0, 0, 0, 86, 87, 1, 0, 0, 0, 87, 109, 3, 2, 1, 7, 88, 89, 10, 5, 0, 0, 89, 91, 7, 3, 0, 0, 90, 92, 3, 18, 9, 0, 91, 90, 1, 0, 0, 0, 91, 92, 1, 0, 0, 0, 92, 93, 1, 0, 0, 0, 93, 109, 3, 2, 1, 6, 94, 95, 10, 4, 0, 0, 95, 97, 5, 17, 0, 0, 96, 98, 3, 18, 9, 0, 97, 96, 1, 0, 0, 0, 97, 98, 1, 0, 0, 0, 98, 99, 1, 0, 0, 0, 99, 109, 3, 2, 1, 5, 100, 101, 10, 1, 0, 0, 101, 102, 5, 32, 0, 0, 102, 103, 3, 34, 17, 0, 103, 104, 3, 4, 2, 0, 104, 106, 5, 33, 0, 0, 105, 107, 3, 30, 15, 0, 106, 105, 1, 0, 0, 0, 106, 107, 1, 0, 0, 0, 107, 109, 1, 0, 0, 0, 108, 61, 1, 0, 0, 0, 108, 67, 1, 0, 0, 0, 108, 73, 1, 0, 0, 0, 108, 79, 1, 0, 0, 0, 108, 88, 1, 0, 0, 0, 108, 94, 1, 0, 0, 0, 108, 100, 1, 0, 0, 0, 109, 112, 1, 0, 0, 0, 110, 108, 1, 0, 0, 0, 110, 111, 1, 0, 0, 0, 111, 3, 1, 0, 0, 0, 112, 110, 1, 0, 0, 0, 113, 115, 5, 36, 0, 0, 114, 116, 3, 34, 17, 0, 115, 114, 1, 0, 0, 0, 115, 116, 1, 0, 0, 0, 116, 128, 1, 0, 0, 0, 117, 118, 5, 42, 0, 0, 118, 119, 5, 6, 0, 0, 119, 128, 3, 2, 1, 0, 120, 121, 5, 42, 0, 0, 121, 122, 7, 4, 0, 0, 122, 128, 3, 2, 1, 0, 123, 124, 5, 42, 0, 0, 124, 125, 7, 0, 0, 0, 125, 128, 3, 2, 1, 0, 126, 128, 5, 42, 0, 0, 127, 113, 1, 0, 0, 0, 127, 117, 1, 0, 0, 0, 127, 120, 1, 0, 0, 0, 127, 123, 1, 0, 0, 0, 127, 126, 1, 0, 0, 0, 128, 5, 1, 0, 0, 0, 129, 133, 3, 8, 4, 0, 130, 133, 3, 14, 7, 0, 131, 133, 3, 38, 19, 0, 132, 129, 1, 0, 0, 0, 132, 130, 1, 0, 0, 0, 132, 131, 1, 0, 0, 0, 133, 7, 1, 0, 0, 0, 134, 135, 5, 44, 0, 0, 135, 137, 5, 34, 0, 0, 136, 138, 3, 10, 5, 0, 137, 136, 1, 0, 0, 0, 137, 138, 1, 0, 0, 0, 138, 139, 1, 0, 0, 0, 139, 153, 5, 35, 0, 0, 140, 141, 5, 44, 0, 0, 141, 142, 5, 34, 0, 0, 142, 143, 3, 10, 5, 0, 143, 144, 5, 35, 0, 0, 144, 145, 3, 12, 6, 0, 145, 153, 1, 0, 0, 0, 146, 147, 5, 44, 0, 0, 147, 148, 3, 12, 6, 0, 148, 149, 5, 34, 0, 0, 149, 150, 3, 10, 5, 0, 150, 151, 5, 35, 0, 0, 151, 153, 1, 0, 0, 0, 152, 134, 1, 0, 0, 0, 152, 140, 1, 0, 0, 0, 152, 146, 1, 0, 0, 0, 153, 9, 1, 0, 0, 0, 154, 159, 3, 2, 1, 0, 155, 156, 5, 37, 0, 0, 156, 158, 3, 2, 1, 0, 157, 155, 1, 0, 0, 0, 158, 161, 1, 0, 0, 0, 159, 157, 1, 0, 0, 0, 159, 160, 1, 0, 0, 0, 160, 11, 1, 0, 0, 0, 161, 159, 1, 0, 0, 0, 162, 163, 7, 5, 0, 0, 163, 164, 3, 20, 10, 0, 164, 13, 1, 0, 0, 0, 165, 170, 3, 16, 8, 0, 166, 167, 5, 32, 0, 0, 167, 168, 3, 34, 17, 0, 168, 169, 5, 33, 0, 0, 169, 171, 1, 0, 0, 0, 170, 166, 1, 0, 0, 0, 170, 171, 1, 0, 0, 0, 171, 173, 1, 0, 0, 0, 172, 174, 3, 30, 15, 0, 173, 172, 1, 0, 0, 0, 173, 174, 1, 0, 0, 0, 174, 15, 1, 0, 0, 0, 175, 181, 3, 28, 14, 0, 176, 178, 5, 30, 0, 0, 177, 179, 3, 22, 11, 0, 178, 177, 1, 0, 0, 0, 178, 179, 1, 0, 0, 0, 179, 180, 1, 0, 0, 0, 180, 182, 5, 31, 0, 0, 181, 176, 1, 0, 0, 0, 181, 182, 1, 0, 0, 0, 182, 188, 1, 0, 0, 0, 183, 184, 5, 30, 0, 0, 184, 185, 3, 22, 11, 0, 185, 186, 5, 31, 0, 0, 186, 188, 1, 0, 0, 0, 187, 175, 1, 0, 0, 0, 187, 183, 1, 0, 0, 0, 188, 17, 1, 0, 0, 0, 189, 190, 7, 6, 0, 0, 190, 195, 3, 20, 10, 0, 191, 193, 7, 7, 0, 0, 192, 194, 3, 20, 10, 0, 193, 192, 1, 0, 0, 0, 193, 194, 1, 0, 0, 0, 194, 196, 1, 0, 0, 0, 195, 191, 1, 0, 0, 0, 195, 196, 1, 0, 0, 0, 196, 19, 1, 0, 0, 0, 197, 204, 5, 34, 0, 0, 198, 200, 3, 26, 13, 0, 199, 201, 5, 37, 0, 0, 200, 199, 1, 0, 0, 0, 200, 201, 1, 0, 0, 0, 201, 203, 1, 0, 0, 0, 202, 198, 1, 0, 0, 0, 203, 206, 1, 0, 0, 0, 204, 202, 1, 0, 0, 0, 204, 205, 1, 0, 0, 0, 205, 207, 1, 0, 0, 0, 206, 204, 1, 0, 0, 0, 207, 208, 5, 35, 0, 0, 208, 21, 1, 0, 0, 0, 209, 216, 3, 24, 12, 0, 210, 212, 5, 37, 0, 0, 211, 213, 3, 24, 12, 0, 212, 211, 1, 0, 0, 0, 212, 213, 1, 0, 0, 0, 213, 215, 1, 0, 0, 0, 214, 210, 1, 0, 0, 0, 215, 218, 1, 0, 0, 0, 216, 214, 1, 0, 0, 0, 216, 217, 1, 0, 0, 0, 217, 23, 1, 0, 0, 0, 218, 216, 1, 0, 0, 0, 219, 222, 3, 26, 13, 0, 220, 221, 7, 8, 0, 0, 221, 223, 5, 38, 0, 0, 222, 220, 1, 0, 0, 0, 222, 223, 1, 0, 0, 0, 223, 25, 1, 0, 0, 0, 224, 228, 3, 28, 14, 0, 225, 228, 5, 38, 0, 0, 226, 228, 3, 40, 20, 0, 227, 224, 1, 0, 0, 0, 227, 225, 1, 0, 0, 0, 227, 226, 1, 0, 0, 0, 228, 27, 1, 0, 0, 0, 229, 232, 5, 44, 0, 0, 230, 232, 3, 46, 23, 0, 231, 229, 1, 0, 0, 0, 231, 230, 1, 0, 0, 0, 232, 29, 1, 0, 0, 0, 233, 235, 3, 32, 16, 0, 234, 236, 3, 36, 18, 0, 235, 234, 1, 0, 0, 0, 235, 236, 1, 0, 0, 0, 236, 242, 1, 0, 0, 0, 237, 239, 3, 36, 18, 0, 238, 240, 3, 32, 16, 0, 239, 238, 1, 0, 0, 0, 239, 240, 1, 0, 0, 0, 240, 242, 1, 0, 0, 0, 241, 233, 1, 0, 0, 0, 241, 237, 1, 0, 0, 0, 242, 31, 1, 0, 0, 0, 243, 245, 5, 26, 0, 0, 244, 246, 5, 2, 0, 0, 245, 244, 1, 0, 0, 0, 245, 246, 1, 0, 0, 0, 246, 247, 1, 0, 0, 0, 247, 248, 3, 34, 17, 0, 248, 33, 1, 0, 0, 0, 249, 250, 3, 2, 1, 0, 250, 35, 1, 0, 0, 0, 251, 253, 5, 27, 0, 0, 252, 254, 5, 2, 0, 0, 253, 252, 1, 0, 0, 0, 253, 254, 1, 0, 0, 0, 254, 255, 1, 0, 0, 0, 255, 259, 3, 44, 22, 0, 256, 257, 5, 27, 0, 0, 257, 259, 7, 9, 0, 0, 258, 251, 1, 0, 0, 0, 258, 256, 1, 0, 0, 0, 259, 37, 1, 0, 0, 0, 260, 264, 3, 40, 20, 0, 261, 264, 3, 42, 21, 0, 262, 264, 3, 44, 22, 0, 263, 260, 1, 0, 0, 0, 263, 261, 1, 0, 0, 0, 263, 262, 1, 0, 0, 0, 264, 39, 1, 0, 0, 0, 265, 269, 5, 40, 0, 0, 266, 269, 5, 39, 0, 0, 267, 269, 5, 41, 0, 0, 268, 265, 1, 0, 0, 0, 268, 266, 1, 0, 0, 0, 268, 267, 1, 0, 0, 0, 269, 41, 1, 0, 0, 0, 270, 271, 5, 38, 0, 0, 271, 43, 1, 0, 0, 0, 272, 276, 5, 42, 0, 0, 273, 276, 5, 43, 0, 0, 274, 276, 3, 40, 20, 0, 275, 272, 1, 0, 0, 0, 275, 273, 1, 0, 0, 0, 275, 274, 1, 0, 0, 0, 276, 45, 1, 0, 0, 0, 277, 278, 7, 10, 0, 0, 278, 47, 1, 0, 0, 0, 40, 59, 64, 70, 76, 82, 85, 91, 97, 106, 108, 110, 115, 127, 132, 137, 152, 159, 170, 173, 178, 181, 187, 193, 195, 200, 204, 212, 216, 222, 227, 231, 235, 239, 241, 245, 253, 258, 263, 268, 275] \ No newline at end of file diff --git a/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/parser/PromqlBaseParser.java b/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/parser/PromqlBaseParser.java new file mode 100644 index 0000000000000..92779cebb02f3 --- /dev/null +++ b/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/parser/PromqlBaseParser.java @@ -0,0 +1,2641 @@ +// ANTLR GENERATED CODE: DO NOT EDIT +package org.elasticsearch.xpack.esql.parser; + +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +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 PromqlBaseParser extends ParserConfig { + static { RuntimeMetaData.checkVersion("4.13.1", RuntimeMetaData.VERSION); } + + protected static final DFA[] _decisionToDFA; + protected static final PredictionContextCache _sharedContextCache = + new PredictionContextCache(); + public static final int + PLUS=1, MINUS=2, ASTERISK=3, SLASH=4, PERCENT=5, CARET=6, EQ=7, NEQ=8, + GT=9, GTE=10, LT=11, LTE=12, LABEL_EQ=13, LABEL_RGX=14, LABEL_RGX_NEQ=15, + AND=16, OR=17, UNLESS=18, BY=19, WITHOUT=20, ON=21, IGNORING=22, GROUP_LEFT=23, + GROUP_RIGHT=24, BOOL=25, OFFSET=26, AT=27, AT_START=28, AT_END=29, LCB=30, + RCB=31, LSB=32, RSB=33, LP=34, RP=35, COLON=36, COMMA=37, STRING=38, INTEGER_VALUE=39, + DECIMAL_VALUE=40, HEXADECIMAL=41, TIME_VALUE_WITH_COLON=42, TIME_VALUE=43, + IDENTIFIER=44, COMMENT=45, WS=46, UNRECOGNIZED=47; + public static final int + RULE_singleStatement = 0, RULE_expression = 1, RULE_subqueryResolution = 2, + RULE_value = 3, RULE_function = 4, RULE_functionParams = 5, RULE_grouping = 6, + RULE_selector = 7, RULE_seriesMatcher = 8, RULE_modifier = 9, RULE_labelList = 10, + RULE_labels = 11, RULE_label = 12, RULE_labelName = 13, RULE_identifier = 14, + RULE_evaluation = 15, RULE_offset = 16, RULE_duration = 17, RULE_at = 18, + RULE_constant = 19, RULE_number = 20, RULE_string = 21, RULE_timeValue = 22, + RULE_nonReserved = 23; + private static String[] makeRuleNames() { + return new String[] { + "singleStatement", "expression", "subqueryResolution", "value", "function", + "functionParams", "grouping", "selector", "seriesMatcher", "modifier", + "labelList", "labels", "label", "labelName", "identifier", "evaluation", + "offset", "duration", "at", "constant", "number", "string", "timeValue", + "nonReserved" + }; + } + public static final String[] ruleNames = makeRuleNames(); + + private static String[] makeLiteralNames() { + return new String[] { + null, "'+'", "'-'", "'*'", "'/'", "'%'", "'^'", "'=='", "'!='", "'>'", + "'>='", "'<'", "'<='", "'='", "'=~'", "'!~'", "'and'", "'or'", "'unless'", + "'by'", "'without'", "'on'", "'ignoring'", "'group_left'", "'group_right'", + "'bool'", null, "'@'", "'start()'", "'end()'", "'{'", "'}'", "'['", "']'", + "'('", "')'", "':'", "','" + }; + } + private static final String[] _LITERAL_NAMES = makeLiteralNames(); + private static String[] makeSymbolicNames() { + return new String[] { + null, "PLUS", "MINUS", "ASTERISK", "SLASH", "PERCENT", "CARET", "EQ", + "NEQ", "GT", "GTE", "LT", "LTE", "LABEL_EQ", "LABEL_RGX", "LABEL_RGX_NEQ", + "AND", "OR", "UNLESS", "BY", "WITHOUT", "ON", "IGNORING", "GROUP_LEFT", + "GROUP_RIGHT", "BOOL", "OFFSET", "AT", "AT_START", "AT_END", "LCB", "RCB", + "LSB", "RSB", "LP", "RP", "COLON", "COMMA", "STRING", "INTEGER_VALUE", + "DECIMAL_VALUE", "HEXADECIMAL", "TIME_VALUE_WITH_COLON", "TIME_VALUE", + "IDENTIFIER", "COMMENT", "WS", "UNRECOGNIZED" + }; + } + 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 "PromqlBaseParser.g4"; } + + @Override + public String[] getRuleNames() { return ruleNames; } + + @Override + public String getSerializedATN() { return _serializedATN; } + + @Override + public ATN getATN() { return _ATN; } + + @SuppressWarnings("this-escape") + public PromqlBaseParser(TokenStream input) { + super(input); + _interp = new ParserATNSimulator(this,_ATN,_decisionToDFA,_sharedContextCache); + } + + @SuppressWarnings("CheckReturnValue") + public static class SingleStatementContext extends ParserRuleContext { + public ExpressionContext expression() { + return getRuleContext(ExpressionContext.class,0); + } + public TerminalNode EOF() { return getToken(PromqlBaseParser.EOF, 0); } + @SuppressWarnings("this-escape") + public SingleStatementContext(ParserRuleContext parent, int invokingState) { + super(parent, invokingState); + } + @Override public int getRuleIndex() { return RULE_singleStatement; } + @Override + public void enterRule(ParseTreeListener listener) { + if ( listener instanceof PromqlBaseParserListener ) ((PromqlBaseParserListener)listener).enterSingleStatement(this); + } + @Override + public void exitRule(ParseTreeListener listener) { + if ( listener instanceof PromqlBaseParserListener ) ((PromqlBaseParserListener)listener).exitSingleStatement(this); + } + @Override + public T accept(ParseTreeVisitor visitor) { + if ( visitor instanceof PromqlBaseParserVisitor ) return ((PromqlBaseParserVisitor)visitor).visitSingleStatement(this); + else return visitor.visitChildren(this); + } + } + + public final SingleStatementContext singleStatement() throws RecognitionException { + SingleStatementContext _localctx = new SingleStatementContext(_ctx, getState()); + enterRule(_localctx, 0, RULE_singleStatement); + try { + enterOuterAlt(_localctx, 1); + { + setState(48); + expression(0); + setState(49); + 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 ExpressionContext extends ParserRuleContext { + @SuppressWarnings("this-escape") + public ExpressionContext(ParserRuleContext parent, int invokingState) { + super(parent, invokingState); + } + @Override public int getRuleIndex() { return RULE_expression; } + + @SuppressWarnings("this-escape") + public ExpressionContext() { } + public void copyFrom(ExpressionContext ctx) { + super.copyFrom(ctx); + } + } + @SuppressWarnings("CheckReturnValue") + public static class ValueExpressionContext extends ExpressionContext { + public ValueContext value() { + return getRuleContext(ValueContext.class,0); + } + @SuppressWarnings("this-escape") + public ValueExpressionContext(ExpressionContext ctx) { copyFrom(ctx); } + @Override + public void enterRule(ParseTreeListener listener) { + if ( listener instanceof PromqlBaseParserListener ) ((PromqlBaseParserListener)listener).enterValueExpression(this); + } + @Override + public void exitRule(ParseTreeListener listener) { + if ( listener instanceof PromqlBaseParserListener ) ((PromqlBaseParserListener)listener).exitValueExpression(this); + } + @Override + public T accept(ParseTreeVisitor visitor) { + if ( visitor instanceof PromqlBaseParserVisitor ) return ((PromqlBaseParserVisitor)visitor).visitValueExpression(this); + else return visitor.visitChildren(this); + } + } + @SuppressWarnings("CheckReturnValue") + public static class SubqueryContext extends ExpressionContext { + public DurationContext range; + public ExpressionContext expression() { + return getRuleContext(ExpressionContext.class,0); + } + public TerminalNode LSB() { return getToken(PromqlBaseParser.LSB, 0); } + public SubqueryResolutionContext subqueryResolution() { + return getRuleContext(SubqueryResolutionContext.class,0); + } + public TerminalNode RSB() { return getToken(PromqlBaseParser.RSB, 0); } + public DurationContext duration() { + return getRuleContext(DurationContext.class,0); + } + public EvaluationContext evaluation() { + return getRuleContext(EvaluationContext.class,0); + } + @SuppressWarnings("this-escape") + public SubqueryContext(ExpressionContext ctx) { copyFrom(ctx); } + @Override + public void enterRule(ParseTreeListener listener) { + if ( listener instanceof PromqlBaseParserListener ) ((PromqlBaseParserListener)listener).enterSubquery(this); + } + @Override + public void exitRule(ParseTreeListener listener) { + if ( listener instanceof PromqlBaseParserListener ) ((PromqlBaseParserListener)listener).exitSubquery(this); + } + @Override + public T accept(ParseTreeVisitor visitor) { + if ( visitor instanceof PromqlBaseParserVisitor ) return ((PromqlBaseParserVisitor)visitor).visitSubquery(this); + else return visitor.visitChildren(this); + } + } + @SuppressWarnings("CheckReturnValue") + public static class ParenthesizedContext extends ExpressionContext { + public TerminalNode LP() { return getToken(PromqlBaseParser.LP, 0); } + public ExpressionContext expression() { + return getRuleContext(ExpressionContext.class,0); + } + public TerminalNode RP() { return getToken(PromqlBaseParser.RP, 0); } + @SuppressWarnings("this-escape") + public ParenthesizedContext(ExpressionContext ctx) { copyFrom(ctx); } + @Override + public void enterRule(ParseTreeListener listener) { + if ( listener instanceof PromqlBaseParserListener ) ((PromqlBaseParserListener)listener).enterParenthesized(this); + } + @Override + public void exitRule(ParseTreeListener listener) { + if ( listener instanceof PromqlBaseParserListener ) ((PromqlBaseParserListener)listener).exitParenthesized(this); + } + @Override + public T accept(ParseTreeVisitor visitor) { + if ( visitor instanceof PromqlBaseParserVisitor ) return ((PromqlBaseParserVisitor)visitor).visitParenthesized(this); + else return visitor.visitChildren(this); + } + } + @SuppressWarnings("CheckReturnValue") + public static class ArithmeticBinaryContext extends ExpressionContext { + public ExpressionContext left; + public Token op; + public ExpressionContext right; + public List expression() { + return getRuleContexts(ExpressionContext.class); + } + public ExpressionContext expression(int i) { + return getRuleContext(ExpressionContext.class,i); + } + public TerminalNode CARET() { return getToken(PromqlBaseParser.CARET, 0); } + public ModifierContext modifier() { + return getRuleContext(ModifierContext.class,0); + } + public TerminalNode ASTERISK() { return getToken(PromqlBaseParser.ASTERISK, 0); } + public TerminalNode PERCENT() { return getToken(PromqlBaseParser.PERCENT, 0); } + public TerminalNode SLASH() { return getToken(PromqlBaseParser.SLASH, 0); } + public TerminalNode MINUS() { return getToken(PromqlBaseParser.MINUS, 0); } + public TerminalNode PLUS() { return getToken(PromqlBaseParser.PLUS, 0); } + public TerminalNode EQ() { return getToken(PromqlBaseParser.EQ, 0); } + public TerminalNode NEQ() { return getToken(PromqlBaseParser.NEQ, 0); } + public TerminalNode GT() { return getToken(PromqlBaseParser.GT, 0); } + public TerminalNode GTE() { return getToken(PromqlBaseParser.GTE, 0); } + public TerminalNode LT() { return getToken(PromqlBaseParser.LT, 0); } + public TerminalNode LTE() { return getToken(PromqlBaseParser.LTE, 0); } + public TerminalNode BOOL() { return getToken(PromqlBaseParser.BOOL, 0); } + public TerminalNode AND() { return getToken(PromqlBaseParser.AND, 0); } + public TerminalNode UNLESS() { return getToken(PromqlBaseParser.UNLESS, 0); } + public TerminalNode OR() { return getToken(PromqlBaseParser.OR, 0); } + @SuppressWarnings("this-escape") + public ArithmeticBinaryContext(ExpressionContext ctx) { copyFrom(ctx); } + @Override + public void enterRule(ParseTreeListener listener) { + if ( listener instanceof PromqlBaseParserListener ) ((PromqlBaseParserListener)listener).enterArithmeticBinary(this); + } + @Override + public void exitRule(ParseTreeListener listener) { + if ( listener instanceof PromqlBaseParserListener ) ((PromqlBaseParserListener)listener).exitArithmeticBinary(this); + } + @Override + public T accept(ParseTreeVisitor visitor) { + if ( visitor instanceof PromqlBaseParserVisitor ) return ((PromqlBaseParserVisitor)visitor).visitArithmeticBinary(this); + else return visitor.visitChildren(this); + } + } + @SuppressWarnings("CheckReturnValue") + public static class ArithmeticUnaryContext extends ExpressionContext { + public Token operator; + public ExpressionContext expression() { + return getRuleContext(ExpressionContext.class,0); + } + public TerminalNode PLUS() { return getToken(PromqlBaseParser.PLUS, 0); } + public TerminalNode MINUS() { return getToken(PromqlBaseParser.MINUS, 0); } + @SuppressWarnings("this-escape") + public ArithmeticUnaryContext(ExpressionContext ctx) { copyFrom(ctx); } + @Override + public void enterRule(ParseTreeListener listener) { + if ( listener instanceof PromqlBaseParserListener ) ((PromqlBaseParserListener)listener).enterArithmeticUnary(this); + } + @Override + public void exitRule(ParseTreeListener listener) { + if ( listener instanceof PromqlBaseParserListener ) ((PromqlBaseParserListener)listener).exitArithmeticUnary(this); + } + @Override + public T accept(ParseTreeVisitor visitor) { + if ( visitor instanceof PromqlBaseParserVisitor ) return ((PromqlBaseParserVisitor)visitor).visitArithmeticUnary(this); + else return visitor.visitChildren(this); + } + } + + public final ExpressionContext expression() throws RecognitionException { + return expression(0); + } + + private ExpressionContext expression(int _p) throws RecognitionException { + ParserRuleContext _parentctx = _ctx; + int _parentState = getState(); + ExpressionContext _localctx = new ExpressionContext(_ctx, _parentState); + ExpressionContext _prevctx = _localctx; + int _startState = 2; + enterRecursionRule(_localctx, 2, RULE_expression, _p); + int _la; + try { + int _alt; + enterOuterAlt(_localctx, 1); + { + setState(59); + _errHandler.sync(this); + switch (_input.LA(1)) { + case PLUS: + case MINUS: + { + _localctx = new ArithmeticUnaryContext(_localctx); + _ctx = _localctx; + _prevctx = _localctx; + + setState(52); + ((ArithmeticUnaryContext)_localctx).operator = _input.LT(1); + _la = _input.LA(1); + if ( !(_la==PLUS || _la==MINUS) ) { + ((ArithmeticUnaryContext)_localctx).operator = (Token)_errHandler.recoverInline(this); + } + else { + if ( _input.LA(1)==Token.EOF ) matchedEOF = true; + _errHandler.reportMatch(this); + consume(); + } + setState(53); + expression(9); + } + break; + case AND: + case OR: + case UNLESS: + case BY: + case WITHOUT: + case ON: + case IGNORING: + case GROUP_LEFT: + case GROUP_RIGHT: + case BOOL: + case OFFSET: + case LCB: + case STRING: + case INTEGER_VALUE: + case DECIMAL_VALUE: + case HEXADECIMAL: + case TIME_VALUE_WITH_COLON: + case TIME_VALUE: + case IDENTIFIER: + { + _localctx = new ValueExpressionContext(_localctx); + _ctx = _localctx; + _prevctx = _localctx; + setState(54); + value(); + } + break; + case LP: + { + _localctx = new ParenthesizedContext(_localctx); + _ctx = _localctx; + _prevctx = _localctx; + setState(55); + match(LP); + setState(56); + expression(0); + setState(57); + match(RP); + } + break; + default: + throw new NoViableAltException(this); + } + _ctx.stop = _input.LT(-1); + setState(110); + _errHandler.sync(this); + _alt = getInterpreter().adaptivePredict(_input,10,_ctx); + while ( _alt!=2 && _alt!=org.antlr.v4.runtime.atn.ATN.INVALID_ALT_NUMBER ) { + if ( _alt==1 ) { + if ( _parseListeners!=null ) triggerExitRuleEvent(); + _prevctx = _localctx; + { + setState(108); + _errHandler.sync(this); + switch ( getInterpreter().adaptivePredict(_input,9,_ctx) ) { + case 1: + { + _localctx = new ArithmeticBinaryContext(new ExpressionContext(_parentctx, _parentState)); + ((ArithmeticBinaryContext)_localctx).left = _prevctx; + pushNewRecursionContext(_localctx, _startState, RULE_expression); + setState(61); + if (!(precpred(_ctx, 10))) throw new FailedPredicateException(this, "precpred(_ctx, 10)"); + setState(62); + ((ArithmeticBinaryContext)_localctx).op = match(CARET); + setState(64); + _errHandler.sync(this); + switch ( getInterpreter().adaptivePredict(_input,1,_ctx) ) { + case 1: + { + setState(63); + modifier(); + } + break; + } + setState(66); + ((ArithmeticBinaryContext)_localctx).right = expression(10); + } + break; + case 2: + { + _localctx = new ArithmeticBinaryContext(new ExpressionContext(_parentctx, _parentState)); + ((ArithmeticBinaryContext)_localctx).left = _prevctx; + pushNewRecursionContext(_localctx, _startState, RULE_expression); + setState(67); + if (!(precpred(_ctx, 8))) throw new FailedPredicateException(this, "precpred(_ctx, 8)"); + setState(68); + ((ArithmeticBinaryContext)_localctx).op = _input.LT(1); + _la = _input.LA(1); + if ( !((((_la) & ~0x3f) == 0 && ((1L << _la) & 56L) != 0)) ) { + ((ArithmeticBinaryContext)_localctx).op = (Token)_errHandler.recoverInline(this); + } + else { + if ( _input.LA(1)==Token.EOF ) matchedEOF = true; + _errHandler.reportMatch(this); + consume(); + } + setState(70); + _errHandler.sync(this); + switch ( getInterpreter().adaptivePredict(_input,2,_ctx) ) { + case 1: + { + setState(69); + modifier(); + } + break; + } + setState(72); + ((ArithmeticBinaryContext)_localctx).right = expression(9); + } + break; + case 3: + { + _localctx = new ArithmeticBinaryContext(new ExpressionContext(_parentctx, _parentState)); + ((ArithmeticBinaryContext)_localctx).left = _prevctx; + pushNewRecursionContext(_localctx, _startState, RULE_expression); + setState(73); + if (!(precpred(_ctx, 7))) throw new FailedPredicateException(this, "precpred(_ctx, 7)"); + setState(74); + ((ArithmeticBinaryContext)_localctx).op = _input.LT(1); + _la = _input.LA(1); + if ( !(_la==PLUS || _la==MINUS) ) { + ((ArithmeticBinaryContext)_localctx).op = (Token)_errHandler.recoverInline(this); + } + else { + if ( _input.LA(1)==Token.EOF ) matchedEOF = true; + _errHandler.reportMatch(this); + consume(); + } + setState(76); + _errHandler.sync(this); + switch ( getInterpreter().adaptivePredict(_input,3,_ctx) ) { + case 1: + { + setState(75); + modifier(); + } + break; + } + setState(78); + ((ArithmeticBinaryContext)_localctx).right = expression(8); + } + break; + case 4: + { + _localctx = new ArithmeticBinaryContext(new ExpressionContext(_parentctx, _parentState)); + ((ArithmeticBinaryContext)_localctx).left = _prevctx; + pushNewRecursionContext(_localctx, _startState, RULE_expression); + setState(79); + if (!(precpred(_ctx, 6))) throw new FailedPredicateException(this, "precpred(_ctx, 6)"); + setState(80); + ((ArithmeticBinaryContext)_localctx).op = _input.LT(1); + _la = _input.LA(1); + if ( !((((_la) & ~0x3f) == 0 && ((1L << _la) & 8064L) != 0)) ) { + ((ArithmeticBinaryContext)_localctx).op = (Token)_errHandler.recoverInline(this); + } + else { + if ( _input.LA(1)==Token.EOF ) matchedEOF = true; + _errHandler.reportMatch(this); + consume(); + } + setState(82); + _errHandler.sync(this); + switch ( getInterpreter().adaptivePredict(_input,4,_ctx) ) { + case 1: + { + setState(81); + match(BOOL); + } + break; + } + setState(85); + _errHandler.sync(this); + switch ( getInterpreter().adaptivePredict(_input,5,_ctx) ) { + case 1: + { + setState(84); + modifier(); + } + break; + } + setState(87); + ((ArithmeticBinaryContext)_localctx).right = expression(7); + } + break; + case 5: + { + _localctx = new ArithmeticBinaryContext(new ExpressionContext(_parentctx, _parentState)); + ((ArithmeticBinaryContext)_localctx).left = _prevctx; + pushNewRecursionContext(_localctx, _startState, RULE_expression); + setState(88); + if (!(precpred(_ctx, 5))) throw new FailedPredicateException(this, "precpred(_ctx, 5)"); + setState(89); + ((ArithmeticBinaryContext)_localctx).op = _input.LT(1); + _la = _input.LA(1); + if ( !(_la==AND || _la==UNLESS) ) { + ((ArithmeticBinaryContext)_localctx).op = (Token)_errHandler.recoverInline(this); + } + else { + if ( _input.LA(1)==Token.EOF ) matchedEOF = true; + _errHandler.reportMatch(this); + consume(); + } + setState(91); + _errHandler.sync(this); + switch ( getInterpreter().adaptivePredict(_input,6,_ctx) ) { + case 1: + { + setState(90); + modifier(); + } + break; + } + setState(93); + ((ArithmeticBinaryContext)_localctx).right = expression(6); + } + break; + case 6: + { + _localctx = new ArithmeticBinaryContext(new ExpressionContext(_parentctx, _parentState)); + ((ArithmeticBinaryContext)_localctx).left = _prevctx; + pushNewRecursionContext(_localctx, _startState, RULE_expression); + setState(94); + if (!(precpred(_ctx, 4))) throw new FailedPredicateException(this, "precpred(_ctx, 4)"); + setState(95); + ((ArithmeticBinaryContext)_localctx).op = match(OR); + setState(97); + _errHandler.sync(this); + switch ( getInterpreter().adaptivePredict(_input,7,_ctx) ) { + case 1: + { + setState(96); + modifier(); + } + break; + } + setState(99); + ((ArithmeticBinaryContext)_localctx).right = expression(5); + } + break; + case 7: + { + _localctx = new SubqueryContext(new ExpressionContext(_parentctx, _parentState)); + pushNewRecursionContext(_localctx, _startState, RULE_expression); + setState(100); + if (!(precpred(_ctx, 1))) throw new FailedPredicateException(this, "precpred(_ctx, 1)"); + setState(101); + match(LSB); + setState(102); + ((SubqueryContext)_localctx).range = duration(); + setState(103); + subqueryResolution(); + setState(104); + match(RSB); + setState(106); + _errHandler.sync(this); + switch ( getInterpreter().adaptivePredict(_input,8,_ctx) ) { + case 1: + { + setState(105); + evaluation(); + } + break; + } + } + break; + } + } + } + setState(112); + _errHandler.sync(this); + _alt = getInterpreter().adaptivePredict(_input,10,_ctx); + } + } + } + catch (RecognitionException re) { + _localctx.exception = re; + _errHandler.reportError(this, re); + _errHandler.recover(this, re); + } + finally { + unrollRecursionContexts(_parentctx); + } + return _localctx; + } + + @SuppressWarnings("CheckReturnValue") + public static class SubqueryResolutionContext extends ParserRuleContext { + public DurationContext resolution; + public Token op; + public TerminalNode COLON() { return getToken(PromqlBaseParser.COLON, 0); } + public DurationContext duration() { + return getRuleContext(DurationContext.class,0); + } + public TerminalNode TIME_VALUE_WITH_COLON() { return getToken(PromqlBaseParser.TIME_VALUE_WITH_COLON, 0); } + public ExpressionContext expression() { + return getRuleContext(ExpressionContext.class,0); + } + public TerminalNode CARET() { return getToken(PromqlBaseParser.CARET, 0); } + public TerminalNode ASTERISK() { return getToken(PromqlBaseParser.ASTERISK, 0); } + public TerminalNode SLASH() { return getToken(PromqlBaseParser.SLASH, 0); } + public TerminalNode MINUS() { return getToken(PromqlBaseParser.MINUS, 0); } + public TerminalNode PLUS() { return getToken(PromqlBaseParser.PLUS, 0); } + @SuppressWarnings("this-escape") + public SubqueryResolutionContext(ParserRuleContext parent, int invokingState) { + super(parent, invokingState); + } + @Override public int getRuleIndex() { return RULE_subqueryResolution; } + @Override + public void enterRule(ParseTreeListener listener) { + if ( listener instanceof PromqlBaseParserListener ) ((PromqlBaseParserListener)listener).enterSubqueryResolution(this); + } + @Override + public void exitRule(ParseTreeListener listener) { + if ( listener instanceof PromqlBaseParserListener ) ((PromqlBaseParserListener)listener).exitSubqueryResolution(this); + } + @Override + public T accept(ParseTreeVisitor visitor) { + if ( visitor instanceof PromqlBaseParserVisitor ) return ((PromqlBaseParserVisitor)visitor).visitSubqueryResolution(this); + else return visitor.visitChildren(this); + } + } + + public final SubqueryResolutionContext subqueryResolution() throws RecognitionException { + SubqueryResolutionContext _localctx = new SubqueryResolutionContext(_ctx, getState()); + enterRule(_localctx, 4, RULE_subqueryResolution); + int _la; + try { + setState(127); + _errHandler.sync(this); + switch ( getInterpreter().adaptivePredict(_input,12,_ctx) ) { + case 1: + enterOuterAlt(_localctx, 1); + { + setState(113); + match(COLON); + setState(115); + _errHandler.sync(this); + _la = _input.LA(1); + if ((((_la) & ~0x3f) == 0 && ((1L << _la) & 34927881945094L) != 0)) { + { + setState(114); + ((SubqueryResolutionContext)_localctx).resolution = duration(); + } + } + + } + break; + case 2: + enterOuterAlt(_localctx, 2); + { + setState(117); + match(TIME_VALUE_WITH_COLON); + setState(118); + ((SubqueryResolutionContext)_localctx).op = match(CARET); + setState(119); + expression(0); + } + break; + case 3: + enterOuterAlt(_localctx, 3); + { + setState(120); + match(TIME_VALUE_WITH_COLON); + setState(121); + ((SubqueryResolutionContext)_localctx).op = _input.LT(1); + _la = _input.LA(1); + if ( !(_la==ASTERISK || _la==SLASH) ) { + ((SubqueryResolutionContext)_localctx).op = (Token)_errHandler.recoverInline(this); + } + else { + if ( _input.LA(1)==Token.EOF ) matchedEOF = true; + _errHandler.reportMatch(this); + consume(); + } + setState(122); + expression(0); + } + break; + case 4: + enterOuterAlt(_localctx, 4); + { + setState(123); + match(TIME_VALUE_WITH_COLON); + setState(124); + ((SubqueryResolutionContext)_localctx).op = _input.LT(1); + _la = _input.LA(1); + if ( !(_la==PLUS || _la==MINUS) ) { + ((SubqueryResolutionContext)_localctx).op = (Token)_errHandler.recoverInline(this); + } + else { + if ( _input.LA(1)==Token.EOF ) matchedEOF = true; + _errHandler.reportMatch(this); + consume(); + } + setState(125); + expression(0); + } + break; + case 5: + enterOuterAlt(_localctx, 5); + { + setState(126); + match(TIME_VALUE_WITH_COLON); + } + break; + } + } + 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 FunctionContext function() { + return getRuleContext(FunctionContext.class,0); + } + public SelectorContext selector() { + return getRuleContext(SelectorContext.class,0); + } + public ConstantContext constant() { + return getRuleContext(ConstantContext.class,0); + } + @SuppressWarnings("this-escape") + 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 PromqlBaseParserListener ) ((PromqlBaseParserListener)listener).enterValue(this); + } + @Override + public void exitRule(ParseTreeListener listener) { + if ( listener instanceof PromqlBaseParserListener ) ((PromqlBaseParserListener)listener).exitValue(this); + } + @Override + public T accept(ParseTreeVisitor visitor) { + if ( visitor instanceof PromqlBaseParserVisitor ) return ((PromqlBaseParserVisitor)visitor).visitValue(this); + else return visitor.visitChildren(this); + } + } + + public final ValueContext value() throws RecognitionException { + ValueContext _localctx = new ValueContext(_ctx, getState()); + enterRule(_localctx, 6, RULE_value); + try { + setState(132); + _errHandler.sync(this); + switch ( getInterpreter().adaptivePredict(_input,13,_ctx) ) { + case 1: + enterOuterAlt(_localctx, 1); + { + setState(129); + function(); + } + break; + case 2: + enterOuterAlt(_localctx, 2); + { + setState(130); + selector(); + } + break; + case 3: + enterOuterAlt(_localctx, 3); + { + setState(131); + constant(); + } + break; + } + } + catch (RecognitionException re) { + _localctx.exception = re; + _errHandler.reportError(this, re); + _errHandler.recover(this, re); + } + finally { + exitRule(); + } + return _localctx; + } + + @SuppressWarnings("CheckReturnValue") + public static class FunctionContext extends ParserRuleContext { + public TerminalNode IDENTIFIER() { return getToken(PromqlBaseParser.IDENTIFIER, 0); } + public TerminalNode LP() { return getToken(PromqlBaseParser.LP, 0); } + public TerminalNode RP() { return getToken(PromqlBaseParser.RP, 0); } + public FunctionParamsContext functionParams() { + return getRuleContext(FunctionParamsContext.class,0); + } + public GroupingContext grouping() { + return getRuleContext(GroupingContext.class,0); + } + @SuppressWarnings("this-escape") + public FunctionContext(ParserRuleContext parent, int invokingState) { + super(parent, invokingState); + } + @Override public int getRuleIndex() { return RULE_function; } + @Override + public void enterRule(ParseTreeListener listener) { + if ( listener instanceof PromqlBaseParserListener ) ((PromqlBaseParserListener)listener).enterFunction(this); + } + @Override + public void exitRule(ParseTreeListener listener) { + if ( listener instanceof PromqlBaseParserListener ) ((PromqlBaseParserListener)listener).exitFunction(this); + } + @Override + public T accept(ParseTreeVisitor visitor) { + if ( visitor instanceof PromqlBaseParserVisitor ) return ((PromqlBaseParserVisitor)visitor).visitFunction(this); + else return visitor.visitChildren(this); + } + } + + public final FunctionContext function() throws RecognitionException { + FunctionContext _localctx = new FunctionContext(_ctx, getState()); + enterRule(_localctx, 8, RULE_function); + int _la; + try { + setState(152); + _errHandler.sync(this); + switch ( getInterpreter().adaptivePredict(_input,15,_ctx) ) { + case 1: + enterOuterAlt(_localctx, 1); + { + setState(134); + match(IDENTIFIER); + setState(135); + match(LP); + setState(137); + _errHandler.sync(this); + _la = _input.LA(1); + if ((((_la) & ~0x3f) == 0 && ((1L << _la) & 34927881945094L) != 0)) { + { + setState(136); + functionParams(); + } + } + + setState(139); + match(RP); + } + break; + case 2: + enterOuterAlt(_localctx, 2); + { + setState(140); + match(IDENTIFIER); + setState(141); + match(LP); + setState(142); + functionParams(); + setState(143); + match(RP); + setState(144); + grouping(); + } + break; + case 3: + enterOuterAlt(_localctx, 3); + { + setState(146); + match(IDENTIFIER); + setState(147); + grouping(); + setState(148); + match(LP); + setState(149); + functionParams(); + setState(150); + match(RP); + } + break; + } + } + catch (RecognitionException re) { + _localctx.exception = re; + _errHandler.reportError(this, re); + _errHandler.recover(this, re); + } + finally { + exitRule(); + } + return _localctx; + } + + @SuppressWarnings("CheckReturnValue") + public static class FunctionParamsContext extends ParserRuleContext { + public List expression() { + return getRuleContexts(ExpressionContext.class); + } + public ExpressionContext expression(int i) { + return getRuleContext(ExpressionContext.class,i); + } + public List COMMA() { return getTokens(PromqlBaseParser.COMMA); } + public TerminalNode COMMA(int i) { + return getToken(PromqlBaseParser.COMMA, i); + } + @SuppressWarnings("this-escape") + public FunctionParamsContext(ParserRuleContext parent, int invokingState) { + super(parent, invokingState); + } + @Override public int getRuleIndex() { return RULE_functionParams; } + @Override + public void enterRule(ParseTreeListener listener) { + if ( listener instanceof PromqlBaseParserListener ) ((PromqlBaseParserListener)listener).enterFunctionParams(this); + } + @Override + public void exitRule(ParseTreeListener listener) { + if ( listener instanceof PromqlBaseParserListener ) ((PromqlBaseParserListener)listener).exitFunctionParams(this); + } + @Override + public T accept(ParseTreeVisitor visitor) { + if ( visitor instanceof PromqlBaseParserVisitor ) return ((PromqlBaseParserVisitor)visitor).visitFunctionParams(this); + else return visitor.visitChildren(this); + } + } + + public final FunctionParamsContext functionParams() throws RecognitionException { + FunctionParamsContext _localctx = new FunctionParamsContext(_ctx, getState()); + enterRule(_localctx, 10, RULE_functionParams); + int _la; + try { + enterOuterAlt(_localctx, 1); + { + setState(154); + expression(0); + setState(159); + _errHandler.sync(this); + _la = _input.LA(1); + while (_la==COMMA) { + { + { + setState(155); + match(COMMA); + setState(156); + expression(0); + } + } + setState(161); + _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 GroupingContext extends ParserRuleContext { + public LabelListContext labelList() { + return getRuleContext(LabelListContext.class,0); + } + public TerminalNode BY() { return getToken(PromqlBaseParser.BY, 0); } + public TerminalNode WITHOUT() { return getToken(PromqlBaseParser.WITHOUT, 0); } + @SuppressWarnings("this-escape") + public GroupingContext(ParserRuleContext parent, int invokingState) { + super(parent, invokingState); + } + @Override public int getRuleIndex() { return RULE_grouping; } + @Override + public void enterRule(ParseTreeListener listener) { + if ( listener instanceof PromqlBaseParserListener ) ((PromqlBaseParserListener)listener).enterGrouping(this); + } + @Override + public void exitRule(ParseTreeListener listener) { + if ( listener instanceof PromqlBaseParserListener ) ((PromqlBaseParserListener)listener).exitGrouping(this); + } + @Override + public T accept(ParseTreeVisitor visitor) { + if ( visitor instanceof PromqlBaseParserVisitor ) return ((PromqlBaseParserVisitor)visitor).visitGrouping(this); + else return visitor.visitChildren(this); + } + } + + public final GroupingContext grouping() throws RecognitionException { + GroupingContext _localctx = new GroupingContext(_ctx, getState()); + enterRule(_localctx, 12, RULE_grouping); + int _la; + try { + enterOuterAlt(_localctx, 1); + { + setState(162); + _la = _input.LA(1); + if ( !(_la==BY || _la==WITHOUT) ) { + _errHandler.recoverInline(this); + } + else { + if ( _input.LA(1)==Token.EOF ) matchedEOF = true; + _errHandler.reportMatch(this); + consume(); + } + setState(163); + labelList(); + } + } + catch (RecognitionException re) { + _localctx.exception = re; + _errHandler.reportError(this, re); + _errHandler.recover(this, re); + } + finally { + exitRule(); + } + return _localctx; + } + + @SuppressWarnings("CheckReturnValue") + public static class SelectorContext extends ParserRuleContext { + public SeriesMatcherContext seriesMatcher() { + return getRuleContext(SeriesMatcherContext.class,0); + } + public TerminalNode LSB() { return getToken(PromqlBaseParser.LSB, 0); } + public DurationContext duration() { + return getRuleContext(DurationContext.class,0); + } + public TerminalNode RSB() { return getToken(PromqlBaseParser.RSB, 0); } + public EvaluationContext evaluation() { + return getRuleContext(EvaluationContext.class,0); + } + @SuppressWarnings("this-escape") + public SelectorContext(ParserRuleContext parent, int invokingState) { + super(parent, invokingState); + } + @Override public int getRuleIndex() { return RULE_selector; } + @Override + public void enterRule(ParseTreeListener listener) { + if ( listener instanceof PromqlBaseParserListener ) ((PromqlBaseParserListener)listener).enterSelector(this); + } + @Override + public void exitRule(ParseTreeListener listener) { + if ( listener instanceof PromqlBaseParserListener ) ((PromqlBaseParserListener)listener).exitSelector(this); + } + @Override + public T accept(ParseTreeVisitor visitor) { + if ( visitor instanceof PromqlBaseParserVisitor ) return ((PromqlBaseParserVisitor)visitor).visitSelector(this); + else return visitor.visitChildren(this); + } + } + + public final SelectorContext selector() throws RecognitionException { + SelectorContext _localctx = new SelectorContext(_ctx, getState()); + enterRule(_localctx, 14, RULE_selector); + try { + enterOuterAlt(_localctx, 1); + { + setState(165); + seriesMatcher(); + setState(170); + _errHandler.sync(this); + switch ( getInterpreter().adaptivePredict(_input,17,_ctx) ) { + case 1: + { + setState(166); + match(LSB); + setState(167); + duration(); + setState(168); + match(RSB); + } + break; + } + setState(173); + _errHandler.sync(this); + switch ( getInterpreter().adaptivePredict(_input,18,_ctx) ) { + case 1: + { + setState(172); + evaluation(); + } + break; + } + } + } + catch (RecognitionException re) { + _localctx.exception = re; + _errHandler.reportError(this, re); + _errHandler.recover(this, re); + } + finally { + exitRule(); + } + return _localctx; + } + + @SuppressWarnings("CheckReturnValue") + public static class SeriesMatcherContext extends ParserRuleContext { + public IdentifierContext identifier() { + return getRuleContext(IdentifierContext.class,0); + } + public TerminalNode LCB() { return getToken(PromqlBaseParser.LCB, 0); } + public TerminalNode RCB() { return getToken(PromqlBaseParser.RCB, 0); } + public LabelsContext labels() { + return getRuleContext(LabelsContext.class,0); + } + @SuppressWarnings("this-escape") + public SeriesMatcherContext(ParserRuleContext parent, int invokingState) { + super(parent, invokingState); + } + @Override public int getRuleIndex() { return RULE_seriesMatcher; } + @Override + public void enterRule(ParseTreeListener listener) { + if ( listener instanceof PromqlBaseParserListener ) ((PromqlBaseParserListener)listener).enterSeriesMatcher(this); + } + @Override + public void exitRule(ParseTreeListener listener) { + if ( listener instanceof PromqlBaseParserListener ) ((PromqlBaseParserListener)listener).exitSeriesMatcher(this); + } + @Override + public T accept(ParseTreeVisitor visitor) { + if ( visitor instanceof PromqlBaseParserVisitor ) return ((PromqlBaseParserVisitor)visitor).visitSeriesMatcher(this); + else return visitor.visitChildren(this); + } + } + + public final SeriesMatcherContext seriesMatcher() throws RecognitionException { + SeriesMatcherContext _localctx = new SeriesMatcherContext(_ctx, getState()); + enterRule(_localctx, 16, RULE_seriesMatcher); + int _la; + try { + setState(187); + _errHandler.sync(this); + switch (_input.LA(1)) { + case AND: + case OR: + case UNLESS: + case BY: + case WITHOUT: + case ON: + case IGNORING: + case GROUP_LEFT: + case GROUP_RIGHT: + case BOOL: + case OFFSET: + case IDENTIFIER: + enterOuterAlt(_localctx, 1); + { + setState(175); + identifier(); + setState(181); + _errHandler.sync(this); + switch ( getInterpreter().adaptivePredict(_input,20,_ctx) ) { + case 1: + { + setState(176); + match(LCB); + setState(178); + _errHandler.sync(this); + _la = _input.LA(1); + if ((((_la) & ~0x3f) == 0 && ((1L << _la) & 21715488800768L) != 0)) { + { + setState(177); + labels(); + } + } + + setState(180); + match(RCB); + } + break; + } + } + break; + case LCB: + enterOuterAlt(_localctx, 2); + { + setState(183); + match(LCB); + setState(184); + labels(); + setState(185); + match(RCB); + } + break; + default: + throw new NoViableAltException(this); + } + } + catch (RecognitionException re) { + _localctx.exception = re; + _errHandler.reportError(this, re); + _errHandler.recover(this, re); + } + finally { + exitRule(); + } + return _localctx; + } + + @SuppressWarnings("CheckReturnValue") + public static class ModifierContext extends ParserRuleContext { + public Token matching; + public LabelListContext modifierLabels; + public Token joining; + public LabelListContext groupLabels; + public List labelList() { + return getRuleContexts(LabelListContext.class); + } + public LabelListContext labelList(int i) { + return getRuleContext(LabelListContext.class,i); + } + public TerminalNode IGNORING() { return getToken(PromqlBaseParser.IGNORING, 0); } + public TerminalNode ON() { return getToken(PromqlBaseParser.ON, 0); } + public TerminalNode GROUP_LEFT() { return getToken(PromqlBaseParser.GROUP_LEFT, 0); } + public TerminalNode GROUP_RIGHT() { return getToken(PromqlBaseParser.GROUP_RIGHT, 0); } + @SuppressWarnings("this-escape") + public ModifierContext(ParserRuleContext parent, int invokingState) { + super(parent, invokingState); + } + @Override public int getRuleIndex() { return RULE_modifier; } + @Override + public void enterRule(ParseTreeListener listener) { + if ( listener instanceof PromqlBaseParserListener ) ((PromqlBaseParserListener)listener).enterModifier(this); + } + @Override + public void exitRule(ParseTreeListener listener) { + if ( listener instanceof PromqlBaseParserListener ) ((PromqlBaseParserListener)listener).exitModifier(this); + } + @Override + public T accept(ParseTreeVisitor visitor) { + if ( visitor instanceof PromqlBaseParserVisitor ) return ((PromqlBaseParserVisitor)visitor).visitModifier(this); + else return visitor.visitChildren(this); + } + } + + public final ModifierContext modifier() throws RecognitionException { + ModifierContext _localctx = new ModifierContext(_ctx, getState()); + enterRule(_localctx, 18, RULE_modifier); + int _la; + try { + enterOuterAlt(_localctx, 1); + { + setState(189); + ((ModifierContext)_localctx).matching = _input.LT(1); + _la = _input.LA(1); + if ( !(_la==ON || _la==IGNORING) ) { + ((ModifierContext)_localctx).matching = (Token)_errHandler.recoverInline(this); + } + else { + if ( _input.LA(1)==Token.EOF ) matchedEOF = true; + _errHandler.reportMatch(this); + consume(); + } + setState(190); + ((ModifierContext)_localctx).modifierLabels = labelList(); + setState(195); + _errHandler.sync(this); + switch ( getInterpreter().adaptivePredict(_input,23,_ctx) ) { + case 1: + { + setState(191); + ((ModifierContext)_localctx).joining = _input.LT(1); + _la = _input.LA(1); + if ( !(_la==GROUP_LEFT || _la==GROUP_RIGHT) ) { + ((ModifierContext)_localctx).joining = (Token)_errHandler.recoverInline(this); + } + else { + if ( _input.LA(1)==Token.EOF ) matchedEOF = true; + _errHandler.reportMatch(this); + consume(); + } + setState(193); + _errHandler.sync(this); + switch ( getInterpreter().adaptivePredict(_input,22,_ctx) ) { + case 1: + { + setState(192); + ((ModifierContext)_localctx).groupLabels = labelList(); + } + break; + } + } + break; + } + } + } + catch (RecognitionException re) { + _localctx.exception = re; + _errHandler.reportError(this, re); + _errHandler.recover(this, re); + } + finally { + exitRule(); + } + return _localctx; + } + + @SuppressWarnings("CheckReturnValue") + public static class LabelListContext extends ParserRuleContext { + public TerminalNode LP() { return getToken(PromqlBaseParser.LP, 0); } + public TerminalNode RP() { return getToken(PromqlBaseParser.RP, 0); } + public List labelName() { + return getRuleContexts(LabelNameContext.class); + } + public LabelNameContext labelName(int i) { + return getRuleContext(LabelNameContext.class,i); + } + public List COMMA() { return getTokens(PromqlBaseParser.COMMA); } + public TerminalNode COMMA(int i) { + return getToken(PromqlBaseParser.COMMA, i); + } + @SuppressWarnings("this-escape") + public LabelListContext(ParserRuleContext parent, int invokingState) { + super(parent, invokingState); + } + @Override public int getRuleIndex() { return RULE_labelList; } + @Override + public void enterRule(ParseTreeListener listener) { + if ( listener instanceof PromqlBaseParserListener ) ((PromqlBaseParserListener)listener).enterLabelList(this); + } + @Override + public void exitRule(ParseTreeListener listener) { + if ( listener instanceof PromqlBaseParserListener ) ((PromqlBaseParserListener)listener).exitLabelList(this); + } + @Override + public T accept(ParseTreeVisitor visitor) { + if ( visitor instanceof PromqlBaseParserVisitor ) return ((PromqlBaseParserVisitor)visitor).visitLabelList(this); + else return visitor.visitChildren(this); + } + } + + public final LabelListContext labelList() throws RecognitionException { + LabelListContext _localctx = new LabelListContext(_ctx, getState()); + enterRule(_localctx, 20, RULE_labelList); + int _la; + try { + enterOuterAlt(_localctx, 1); + { + setState(197); + match(LP); + setState(204); + _errHandler.sync(this); + _la = _input.LA(1); + while ((((_la) & ~0x3f) == 0 && ((1L << _la) & 21715488800768L) != 0)) { + { + { + setState(198); + labelName(); + setState(200); + _errHandler.sync(this); + _la = _input.LA(1); + if (_la==COMMA) { + { + setState(199); + match(COMMA); + } + } + + } + } + setState(206); + _errHandler.sync(this); + _la = _input.LA(1); + } + setState(207); + match(RP); + } + } + catch (RecognitionException re) { + _localctx.exception = re; + _errHandler.reportError(this, re); + _errHandler.recover(this, re); + } + finally { + exitRule(); + } + return _localctx; + } + + @SuppressWarnings("CheckReturnValue") + public static class LabelsContext extends ParserRuleContext { + public List label() { + return getRuleContexts(LabelContext.class); + } + public LabelContext label(int i) { + return getRuleContext(LabelContext.class,i); + } + public List COMMA() { return getTokens(PromqlBaseParser.COMMA); } + public TerminalNode COMMA(int i) { + return getToken(PromqlBaseParser.COMMA, i); + } + @SuppressWarnings("this-escape") + public LabelsContext(ParserRuleContext parent, int invokingState) { + super(parent, invokingState); + } + @Override public int getRuleIndex() { return RULE_labels; } + @Override + public void enterRule(ParseTreeListener listener) { + if ( listener instanceof PromqlBaseParserListener ) ((PromqlBaseParserListener)listener).enterLabels(this); + } + @Override + public void exitRule(ParseTreeListener listener) { + if ( listener instanceof PromqlBaseParserListener ) ((PromqlBaseParserListener)listener).exitLabels(this); + } + @Override + public T accept(ParseTreeVisitor visitor) { + if ( visitor instanceof PromqlBaseParserVisitor ) return ((PromqlBaseParserVisitor)visitor).visitLabels(this); + else return visitor.visitChildren(this); + } + } + + public final LabelsContext labels() throws RecognitionException { + LabelsContext _localctx = new LabelsContext(_ctx, getState()); + enterRule(_localctx, 22, RULE_labels); + int _la; + try { + enterOuterAlt(_localctx, 1); + { + setState(209); + label(); + setState(216); + _errHandler.sync(this); + _la = _input.LA(1); + while (_la==COMMA) { + { + { + setState(210); + match(COMMA); + setState(212); + _errHandler.sync(this); + _la = _input.LA(1); + if ((((_la) & ~0x3f) == 0 && ((1L << _la) & 21715488800768L) != 0)) { + { + setState(211); + label(); + } + } + + } + } + setState(218); + _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 LabelContext extends ParserRuleContext { + public Token kind; + public LabelNameContext labelName() { + return getRuleContext(LabelNameContext.class,0); + } + public TerminalNode STRING() { return getToken(PromqlBaseParser.STRING, 0); } + public TerminalNode LABEL_EQ() { return getToken(PromqlBaseParser.LABEL_EQ, 0); } + public TerminalNode NEQ() { return getToken(PromqlBaseParser.NEQ, 0); } + public TerminalNode LABEL_RGX() { return getToken(PromqlBaseParser.LABEL_RGX, 0); } + public TerminalNode LABEL_RGX_NEQ() { return getToken(PromqlBaseParser.LABEL_RGX_NEQ, 0); } + @SuppressWarnings("this-escape") + public LabelContext(ParserRuleContext parent, int invokingState) { + super(parent, invokingState); + } + @Override public int getRuleIndex() { return RULE_label; } + @Override + public void enterRule(ParseTreeListener listener) { + if ( listener instanceof PromqlBaseParserListener ) ((PromqlBaseParserListener)listener).enterLabel(this); + } + @Override + public void exitRule(ParseTreeListener listener) { + if ( listener instanceof PromqlBaseParserListener ) ((PromqlBaseParserListener)listener).exitLabel(this); + } + @Override + public T accept(ParseTreeVisitor visitor) { + if ( visitor instanceof PromqlBaseParserVisitor ) return ((PromqlBaseParserVisitor)visitor).visitLabel(this); + else return visitor.visitChildren(this); + } + } + + public final LabelContext label() throws RecognitionException { + LabelContext _localctx = new LabelContext(_ctx, getState()); + enterRule(_localctx, 24, RULE_label); + int _la; + try { + enterOuterAlt(_localctx, 1); + { + setState(219); + labelName(); + setState(222); + _errHandler.sync(this); + _la = _input.LA(1); + if ((((_la) & ~0x3f) == 0 && ((1L << _la) & 57600L) != 0)) { + { + setState(220); + ((LabelContext)_localctx).kind = _input.LT(1); + _la = _input.LA(1); + if ( !((((_la) & ~0x3f) == 0 && ((1L << _la) & 57600L) != 0)) ) { + ((LabelContext)_localctx).kind = (Token)_errHandler.recoverInline(this); + } + else { + if ( _input.LA(1)==Token.EOF ) matchedEOF = true; + _errHandler.reportMatch(this); + consume(); + } + setState(221); + match(STRING); + } + } + + } + } + catch (RecognitionException re) { + _localctx.exception = re; + _errHandler.reportError(this, re); + _errHandler.recover(this, re); + } + finally { + exitRule(); + } + return _localctx; + } + + @SuppressWarnings("CheckReturnValue") + public static class LabelNameContext extends ParserRuleContext { + public IdentifierContext identifier() { + return getRuleContext(IdentifierContext.class,0); + } + public TerminalNode STRING() { return getToken(PromqlBaseParser.STRING, 0); } + public NumberContext number() { + return getRuleContext(NumberContext.class,0); + } + @SuppressWarnings("this-escape") + public LabelNameContext(ParserRuleContext parent, int invokingState) { + super(parent, invokingState); + } + @Override public int getRuleIndex() { return RULE_labelName; } + @Override + public void enterRule(ParseTreeListener listener) { + if ( listener instanceof PromqlBaseParserListener ) ((PromqlBaseParserListener)listener).enterLabelName(this); + } + @Override + public void exitRule(ParseTreeListener listener) { + if ( listener instanceof PromqlBaseParserListener ) ((PromqlBaseParserListener)listener).exitLabelName(this); + } + @Override + public T accept(ParseTreeVisitor visitor) { + if ( visitor instanceof PromqlBaseParserVisitor ) return ((PromqlBaseParserVisitor)visitor).visitLabelName(this); + else return visitor.visitChildren(this); + } + } + + public final LabelNameContext labelName() throws RecognitionException { + LabelNameContext _localctx = new LabelNameContext(_ctx, getState()); + enterRule(_localctx, 26, RULE_labelName); + try { + setState(227); + _errHandler.sync(this); + switch (_input.LA(1)) { + case AND: + case OR: + case UNLESS: + case BY: + case WITHOUT: + case ON: + case IGNORING: + case GROUP_LEFT: + case GROUP_RIGHT: + case BOOL: + case OFFSET: + case IDENTIFIER: + enterOuterAlt(_localctx, 1); + { + setState(224); + identifier(); + } + break; + case STRING: + enterOuterAlt(_localctx, 2); + { + setState(225); + match(STRING); + } + break; + case INTEGER_VALUE: + case DECIMAL_VALUE: + case HEXADECIMAL: + enterOuterAlt(_localctx, 3); + { + setState(226); + number(); + } + break; + default: + throw new NoViableAltException(this); + } + } + 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 TerminalNode IDENTIFIER() { return getToken(PromqlBaseParser.IDENTIFIER, 0); } + public NonReservedContext nonReserved() { + return getRuleContext(NonReservedContext.class,0); + } + @SuppressWarnings("this-escape") + 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 PromqlBaseParserListener ) ((PromqlBaseParserListener)listener).enterIdentifier(this); + } + @Override + public void exitRule(ParseTreeListener listener) { + if ( listener instanceof PromqlBaseParserListener ) ((PromqlBaseParserListener)listener).exitIdentifier(this); + } + @Override + public T accept(ParseTreeVisitor visitor) { + if ( visitor instanceof PromqlBaseParserVisitor ) return ((PromqlBaseParserVisitor)visitor).visitIdentifier(this); + else return visitor.visitChildren(this); + } + } + + public final IdentifierContext identifier() throws RecognitionException { + IdentifierContext _localctx = new IdentifierContext(_ctx, getState()); + enterRule(_localctx, 28, RULE_identifier); + try { + setState(231); + _errHandler.sync(this); + switch (_input.LA(1)) { + case IDENTIFIER: + enterOuterAlt(_localctx, 1); + { + setState(229); + match(IDENTIFIER); + } + break; + case AND: + case OR: + case UNLESS: + case BY: + case WITHOUT: + case ON: + case IGNORING: + case GROUP_LEFT: + case GROUP_RIGHT: + case BOOL: + case OFFSET: + enterOuterAlt(_localctx, 2); + { + setState(230); + nonReserved(); + } + break; + default: + throw new NoViableAltException(this); + } + } + catch (RecognitionException re) { + _localctx.exception = re; + _errHandler.reportError(this, re); + _errHandler.recover(this, re); + } + finally { + exitRule(); + } + return _localctx; + } + + @SuppressWarnings("CheckReturnValue") + public static class EvaluationContext extends ParserRuleContext { + public OffsetContext offset() { + return getRuleContext(OffsetContext.class,0); + } + public AtContext at() { + return getRuleContext(AtContext.class,0); + } + @SuppressWarnings("this-escape") + public EvaluationContext(ParserRuleContext parent, int invokingState) { + super(parent, invokingState); + } + @Override public int getRuleIndex() { return RULE_evaluation; } + @Override + public void enterRule(ParseTreeListener listener) { + if ( listener instanceof PromqlBaseParserListener ) ((PromqlBaseParserListener)listener).enterEvaluation(this); + } + @Override + public void exitRule(ParseTreeListener listener) { + if ( listener instanceof PromqlBaseParserListener ) ((PromqlBaseParserListener)listener).exitEvaluation(this); + } + @Override + public T accept(ParseTreeVisitor visitor) { + if ( visitor instanceof PromqlBaseParserVisitor ) return ((PromqlBaseParserVisitor)visitor).visitEvaluation(this); + else return visitor.visitChildren(this); + } + } + + public final EvaluationContext evaluation() throws RecognitionException { + EvaluationContext _localctx = new EvaluationContext(_ctx, getState()); + enterRule(_localctx, 30, RULE_evaluation); + try { + setState(241); + _errHandler.sync(this); + switch (_input.LA(1)) { + case OFFSET: + enterOuterAlt(_localctx, 1); + { + setState(233); + offset(); + setState(235); + _errHandler.sync(this); + switch ( getInterpreter().adaptivePredict(_input,31,_ctx) ) { + case 1: + { + setState(234); + at(); + } + break; + } + } + break; + case AT: + enterOuterAlt(_localctx, 2); + { + setState(237); + at(); + setState(239); + _errHandler.sync(this); + switch ( getInterpreter().adaptivePredict(_input,32,_ctx) ) { + case 1: + { + setState(238); + offset(); + } + break; + } + } + break; + default: + throw new NoViableAltException(this); + } + } + catch (RecognitionException re) { + _localctx.exception = re; + _errHandler.reportError(this, re); + _errHandler.recover(this, re); + } + finally { + exitRule(); + } + return _localctx; + } + + @SuppressWarnings("CheckReturnValue") + public static class OffsetContext extends ParserRuleContext { + public TerminalNode OFFSET() { return getToken(PromqlBaseParser.OFFSET, 0); } + public DurationContext duration() { + return getRuleContext(DurationContext.class,0); + } + public TerminalNode MINUS() { return getToken(PromqlBaseParser.MINUS, 0); } + @SuppressWarnings("this-escape") + public OffsetContext(ParserRuleContext parent, int invokingState) { + super(parent, invokingState); + } + @Override public int getRuleIndex() { return RULE_offset; } + @Override + public void enterRule(ParseTreeListener listener) { + if ( listener instanceof PromqlBaseParserListener ) ((PromqlBaseParserListener)listener).enterOffset(this); + } + @Override + public void exitRule(ParseTreeListener listener) { + if ( listener instanceof PromqlBaseParserListener ) ((PromqlBaseParserListener)listener).exitOffset(this); + } + @Override + public T accept(ParseTreeVisitor visitor) { + if ( visitor instanceof PromqlBaseParserVisitor ) return ((PromqlBaseParserVisitor)visitor).visitOffset(this); + else return visitor.visitChildren(this); + } + } + + public final OffsetContext offset() throws RecognitionException { + OffsetContext _localctx = new OffsetContext(_ctx, getState()); + enterRule(_localctx, 32, RULE_offset); + try { + enterOuterAlt(_localctx, 1); + { + setState(243); + match(OFFSET); + setState(245); + _errHandler.sync(this); + switch ( getInterpreter().adaptivePredict(_input,34,_ctx) ) { + case 1: + { + setState(244); + match(MINUS); + } + break; + } + setState(247); + duration(); + } + } + catch (RecognitionException re) { + _localctx.exception = re; + _errHandler.reportError(this, re); + _errHandler.recover(this, re); + } + finally { + exitRule(); + } + return _localctx; + } + + @SuppressWarnings("CheckReturnValue") + public static class DurationContext extends ParserRuleContext { + public ExpressionContext expression() { + return getRuleContext(ExpressionContext.class,0); + } + @SuppressWarnings("this-escape") + public DurationContext(ParserRuleContext parent, int invokingState) { + super(parent, invokingState); + } + @Override public int getRuleIndex() { return RULE_duration; } + @Override + public void enterRule(ParseTreeListener listener) { + if ( listener instanceof PromqlBaseParserListener ) ((PromqlBaseParserListener)listener).enterDuration(this); + } + @Override + public void exitRule(ParseTreeListener listener) { + if ( listener instanceof PromqlBaseParserListener ) ((PromqlBaseParserListener)listener).exitDuration(this); + } + @Override + public T accept(ParseTreeVisitor visitor) { + if ( visitor instanceof PromqlBaseParserVisitor ) return ((PromqlBaseParserVisitor)visitor).visitDuration(this); + else return visitor.visitChildren(this); + } + } + + public final DurationContext duration() throws RecognitionException { + DurationContext _localctx = new DurationContext(_ctx, getState()); + enterRule(_localctx, 34, RULE_duration); + try { + enterOuterAlt(_localctx, 1); + { + setState(249); + expression(0); + } + } + catch (RecognitionException re) { + _localctx.exception = re; + _errHandler.reportError(this, re); + _errHandler.recover(this, re); + } + finally { + exitRule(); + } + return _localctx; + } + + @SuppressWarnings("CheckReturnValue") + public static class AtContext extends ParserRuleContext { + public TerminalNode AT() { return getToken(PromqlBaseParser.AT, 0); } + public TimeValueContext timeValue() { + return getRuleContext(TimeValueContext.class,0); + } + public TerminalNode MINUS() { return getToken(PromqlBaseParser.MINUS, 0); } + public TerminalNode AT_START() { return getToken(PromqlBaseParser.AT_START, 0); } + public TerminalNode AT_END() { return getToken(PromqlBaseParser.AT_END, 0); } + @SuppressWarnings("this-escape") + public AtContext(ParserRuleContext parent, int invokingState) { + super(parent, invokingState); + } + @Override public int getRuleIndex() { return RULE_at; } + @Override + public void enterRule(ParseTreeListener listener) { + if ( listener instanceof PromqlBaseParserListener ) ((PromqlBaseParserListener)listener).enterAt(this); + } + @Override + public void exitRule(ParseTreeListener listener) { + if ( listener instanceof PromqlBaseParserListener ) ((PromqlBaseParserListener)listener).exitAt(this); + } + @Override + public T accept(ParseTreeVisitor visitor) { + if ( visitor instanceof PromqlBaseParserVisitor ) return ((PromqlBaseParserVisitor)visitor).visitAt(this); + else return visitor.visitChildren(this); + } + } + + public final AtContext at() throws RecognitionException { + AtContext _localctx = new AtContext(_ctx, getState()); + enterRule(_localctx, 36, RULE_at); + int _la; + try { + setState(258); + _errHandler.sync(this); + switch ( getInterpreter().adaptivePredict(_input,36,_ctx) ) { + case 1: + enterOuterAlt(_localctx, 1); + { + setState(251); + match(AT); + setState(253); + _errHandler.sync(this); + _la = _input.LA(1); + if (_la==MINUS) { + { + setState(252); + match(MINUS); + } + } + + setState(255); + timeValue(); + } + break; + case 2: + enterOuterAlt(_localctx, 2); + { + setState(256); + match(AT); + setState(257); + _la = _input.LA(1); + if ( !(_la==AT_START || _la==AT_END) ) { + _errHandler.recoverInline(this); + } + else { + if ( _input.LA(1)==Token.EOF ) matchedEOF = true; + _errHandler.reportMatch(this); + consume(); + } + } + break; + } + } + catch (RecognitionException re) { + _localctx.exception = re; + _errHandler.reportError(this, re); + _errHandler.recover(this, re); + } + finally { + exitRule(); + } + return _localctx; + } + + @SuppressWarnings("CheckReturnValue") + public static class ConstantContext extends ParserRuleContext { + public NumberContext number() { + return getRuleContext(NumberContext.class,0); + } + public StringContext string() { + return getRuleContext(StringContext.class,0); + } + public TimeValueContext timeValue() { + return getRuleContext(TimeValueContext.class,0); + } + @SuppressWarnings("this-escape") + public ConstantContext(ParserRuleContext parent, int invokingState) { + super(parent, invokingState); + } + @Override public int getRuleIndex() { return RULE_constant; } + @Override + public void enterRule(ParseTreeListener listener) { + if ( listener instanceof PromqlBaseParserListener ) ((PromqlBaseParserListener)listener).enterConstant(this); + } + @Override + public void exitRule(ParseTreeListener listener) { + if ( listener instanceof PromqlBaseParserListener ) ((PromqlBaseParserListener)listener).exitConstant(this); + } + @Override + public T accept(ParseTreeVisitor visitor) { + if ( visitor instanceof PromqlBaseParserVisitor ) return ((PromqlBaseParserVisitor)visitor).visitConstant(this); + else return visitor.visitChildren(this); + } + } + + public final ConstantContext constant() throws RecognitionException { + ConstantContext _localctx = new ConstantContext(_ctx, getState()); + enterRule(_localctx, 38, RULE_constant); + try { + setState(263); + _errHandler.sync(this); + switch ( getInterpreter().adaptivePredict(_input,37,_ctx) ) { + case 1: + enterOuterAlt(_localctx, 1); + { + setState(260); + number(); + } + break; + case 2: + enterOuterAlt(_localctx, 2); + { + setState(261); + string(); + } + break; + case 3: + enterOuterAlt(_localctx, 3); + { + setState(262); + timeValue(); + } + break; + } + } + catch (RecognitionException re) { + _localctx.exception = re; + _errHandler.reportError(this, re); + _errHandler.recover(this, re); + } + finally { + exitRule(); + } + return _localctx; + } + + @SuppressWarnings("CheckReturnValue") + public static class NumberContext extends ParserRuleContext { + @SuppressWarnings("this-escape") + public NumberContext(ParserRuleContext parent, int invokingState) { + super(parent, invokingState); + } + @Override public int getRuleIndex() { return RULE_number; } + + @SuppressWarnings("this-escape") + public NumberContext() { } + public void copyFrom(NumberContext ctx) { + super.copyFrom(ctx); + } + } + @SuppressWarnings("CheckReturnValue") + public static class DecimalLiteralContext extends NumberContext { + public TerminalNode DECIMAL_VALUE() { return getToken(PromqlBaseParser.DECIMAL_VALUE, 0); } + @SuppressWarnings("this-escape") + public DecimalLiteralContext(NumberContext ctx) { copyFrom(ctx); } + @Override + public void enterRule(ParseTreeListener listener) { + if ( listener instanceof PromqlBaseParserListener ) ((PromqlBaseParserListener)listener).enterDecimalLiteral(this); + } + @Override + public void exitRule(ParseTreeListener listener) { + if ( listener instanceof PromqlBaseParserListener ) ((PromqlBaseParserListener)listener).exitDecimalLiteral(this); + } + @Override + public T accept(ParseTreeVisitor visitor) { + if ( visitor instanceof PromqlBaseParserVisitor ) return ((PromqlBaseParserVisitor)visitor).visitDecimalLiteral(this); + else return visitor.visitChildren(this); + } + } + @SuppressWarnings("CheckReturnValue") + public static class IntegerLiteralContext extends NumberContext { + public TerminalNode INTEGER_VALUE() { return getToken(PromqlBaseParser.INTEGER_VALUE, 0); } + @SuppressWarnings("this-escape") + public IntegerLiteralContext(NumberContext ctx) { copyFrom(ctx); } + @Override + public void enterRule(ParseTreeListener listener) { + if ( listener instanceof PromqlBaseParserListener ) ((PromqlBaseParserListener)listener).enterIntegerLiteral(this); + } + @Override + public void exitRule(ParseTreeListener listener) { + if ( listener instanceof PromqlBaseParserListener ) ((PromqlBaseParserListener)listener).exitIntegerLiteral(this); + } + @Override + public T accept(ParseTreeVisitor visitor) { + if ( visitor instanceof PromqlBaseParserVisitor ) return ((PromqlBaseParserVisitor)visitor).visitIntegerLiteral(this); + else return visitor.visitChildren(this); + } + } + @SuppressWarnings("CheckReturnValue") + public static class HexLiteralContext extends NumberContext { + public TerminalNode HEXADECIMAL() { return getToken(PromqlBaseParser.HEXADECIMAL, 0); } + @SuppressWarnings("this-escape") + public HexLiteralContext(NumberContext ctx) { copyFrom(ctx); } + @Override + public void enterRule(ParseTreeListener listener) { + if ( listener instanceof PromqlBaseParserListener ) ((PromqlBaseParserListener)listener).enterHexLiteral(this); + } + @Override + public void exitRule(ParseTreeListener listener) { + if ( listener instanceof PromqlBaseParserListener ) ((PromqlBaseParserListener)listener).exitHexLiteral(this); + } + @Override + public T accept(ParseTreeVisitor visitor) { + if ( visitor instanceof PromqlBaseParserVisitor ) return ((PromqlBaseParserVisitor)visitor).visitHexLiteral(this); + else return visitor.visitChildren(this); + } + } + + public final NumberContext number() throws RecognitionException { + NumberContext _localctx = new NumberContext(_ctx, getState()); + enterRule(_localctx, 40, RULE_number); + try { + setState(268); + _errHandler.sync(this); + switch (_input.LA(1)) { + case DECIMAL_VALUE: + _localctx = new DecimalLiteralContext(_localctx); + enterOuterAlt(_localctx, 1); + { + setState(265); + match(DECIMAL_VALUE); + } + break; + case INTEGER_VALUE: + _localctx = new IntegerLiteralContext(_localctx); + enterOuterAlt(_localctx, 2); + { + setState(266); + match(INTEGER_VALUE); + } + break; + case HEXADECIMAL: + _localctx = new HexLiteralContext(_localctx); + enterOuterAlt(_localctx, 3); + { + setState(267); + match(HEXADECIMAL); + } + break; + default: + throw new NoViableAltException(this); + } + } + catch (RecognitionException re) { + _localctx.exception = re; + _errHandler.reportError(this, re); + _errHandler.recover(this, re); + } + finally { + exitRule(); + } + return _localctx; + } + + @SuppressWarnings("CheckReturnValue") + public static class StringContext extends ParserRuleContext { + public TerminalNode STRING() { return getToken(PromqlBaseParser.STRING, 0); } + @SuppressWarnings("this-escape") + public StringContext(ParserRuleContext parent, int invokingState) { + super(parent, invokingState); + } + @Override public int getRuleIndex() { return RULE_string; } + @Override + public void enterRule(ParseTreeListener listener) { + if ( listener instanceof PromqlBaseParserListener ) ((PromqlBaseParserListener)listener).enterString(this); + } + @Override + public void exitRule(ParseTreeListener listener) { + if ( listener instanceof PromqlBaseParserListener ) ((PromqlBaseParserListener)listener).exitString(this); + } + @Override + public T accept(ParseTreeVisitor visitor) { + if ( visitor instanceof PromqlBaseParserVisitor ) return ((PromqlBaseParserVisitor)visitor).visitString(this); + else return visitor.visitChildren(this); + } + } + + public final StringContext string() throws RecognitionException { + StringContext _localctx = new StringContext(_ctx, getState()); + enterRule(_localctx, 42, RULE_string); + try { + enterOuterAlt(_localctx, 1); + { + setState(270); + match(STRING); + } + } + catch (RecognitionException re) { + _localctx.exception = re; + _errHandler.reportError(this, re); + _errHandler.recover(this, re); + } + finally { + exitRule(); + } + return _localctx; + } + + @SuppressWarnings("CheckReturnValue") + public static class TimeValueContext extends ParserRuleContext { + public TerminalNode TIME_VALUE_WITH_COLON() { return getToken(PromqlBaseParser.TIME_VALUE_WITH_COLON, 0); } + public TerminalNode TIME_VALUE() { return getToken(PromqlBaseParser.TIME_VALUE, 0); } + public NumberContext number() { + return getRuleContext(NumberContext.class,0); + } + @SuppressWarnings("this-escape") + public TimeValueContext(ParserRuleContext parent, int invokingState) { + super(parent, invokingState); + } + @Override public int getRuleIndex() { return RULE_timeValue; } + @Override + public void enterRule(ParseTreeListener listener) { + if ( listener instanceof PromqlBaseParserListener ) ((PromqlBaseParserListener)listener).enterTimeValue(this); + } + @Override + public void exitRule(ParseTreeListener listener) { + if ( listener instanceof PromqlBaseParserListener ) ((PromqlBaseParserListener)listener).exitTimeValue(this); + } + @Override + public T accept(ParseTreeVisitor visitor) { + if ( visitor instanceof PromqlBaseParserVisitor ) return ((PromqlBaseParserVisitor)visitor).visitTimeValue(this); + else return visitor.visitChildren(this); + } + } + + public final TimeValueContext timeValue() throws RecognitionException { + TimeValueContext _localctx = new TimeValueContext(_ctx, getState()); + enterRule(_localctx, 44, RULE_timeValue); + try { + setState(275); + _errHandler.sync(this); + switch (_input.LA(1)) { + case TIME_VALUE_WITH_COLON: + enterOuterAlt(_localctx, 1); + { + setState(272); + match(TIME_VALUE_WITH_COLON); + } + break; + case TIME_VALUE: + enterOuterAlt(_localctx, 2); + { + setState(273); + match(TIME_VALUE); + } + break; + case INTEGER_VALUE: + case DECIMAL_VALUE: + case HEXADECIMAL: + enterOuterAlt(_localctx, 3); + { + setState(274); + number(); + } + break; + default: + throw new NoViableAltException(this); + } + } + catch (RecognitionException re) { + _localctx.exception = re; + _errHandler.reportError(this, re); + _errHandler.recover(this, re); + } + finally { + exitRule(); + } + return _localctx; + } + + @SuppressWarnings("CheckReturnValue") + public static class NonReservedContext extends ParserRuleContext { + public TerminalNode AND() { return getToken(PromqlBaseParser.AND, 0); } + public TerminalNode BOOL() { return getToken(PromqlBaseParser.BOOL, 0); } + public TerminalNode BY() { return getToken(PromqlBaseParser.BY, 0); } + public TerminalNode GROUP_LEFT() { return getToken(PromqlBaseParser.GROUP_LEFT, 0); } + public TerminalNode GROUP_RIGHT() { return getToken(PromqlBaseParser.GROUP_RIGHT, 0); } + public TerminalNode IGNORING() { return getToken(PromqlBaseParser.IGNORING, 0); } + public TerminalNode OFFSET() { return getToken(PromqlBaseParser.OFFSET, 0); } + public TerminalNode OR() { return getToken(PromqlBaseParser.OR, 0); } + public TerminalNode ON() { return getToken(PromqlBaseParser.ON, 0); } + public TerminalNode UNLESS() { return getToken(PromqlBaseParser.UNLESS, 0); } + public TerminalNode WITHOUT() { return getToken(PromqlBaseParser.WITHOUT, 0); } + @SuppressWarnings("this-escape") + public NonReservedContext(ParserRuleContext parent, int invokingState) { + super(parent, invokingState); + } + @Override public int getRuleIndex() { return RULE_nonReserved; } + @Override + public void enterRule(ParseTreeListener listener) { + if ( listener instanceof PromqlBaseParserListener ) ((PromqlBaseParserListener)listener).enterNonReserved(this); + } + @Override + public void exitRule(ParseTreeListener listener) { + if ( listener instanceof PromqlBaseParserListener ) ((PromqlBaseParserListener)listener).exitNonReserved(this); + } + @Override + public T accept(ParseTreeVisitor visitor) { + if ( visitor instanceof PromqlBaseParserVisitor ) return ((PromqlBaseParserVisitor)visitor).visitNonReserved(this); + else return visitor.visitChildren(this); + } + } + + public final NonReservedContext nonReserved() throws RecognitionException { + NonReservedContext _localctx = new NonReservedContext(_ctx, getState()); + enterRule(_localctx, 46, RULE_nonReserved); + int _la; + try { + enterOuterAlt(_localctx, 1); + { + setState(277); + _la = _input.LA(1); + if ( !((((_la) & ~0x3f) == 0 && ((1L << _la) & 134152192L) != 0)) ) { + _errHandler.recoverInline(this); + } + else { + if ( _input.LA(1)==Token.EOF ) matchedEOF = true; + _errHandler.reportMatch(this); + consume(); + } + } + } + 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: + return expression_sempred((ExpressionContext)_localctx, predIndex); + } + return true; + } + private boolean expression_sempred(ExpressionContext _localctx, int predIndex) { + switch (predIndex) { + case 0: + return precpred(_ctx, 10); + case 1: + return precpred(_ctx, 8); + case 2: + return precpred(_ctx, 7); + case 3: + return precpred(_ctx, 6); + case 4: + return precpred(_ctx, 5); + case 5: + return precpred(_ctx, 4); + case 6: + return precpred(_ctx, 1); + } + return true; + } + + public static final String _serializedATN = + "\u0004\u0001/\u0118\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"+ + "\f\u0007\f\u0002\r\u0007\r\u0002\u000e\u0007\u000e\u0002\u000f\u0007\u000f"+ + "\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\u0001\u0000\u0001\u0000"+ + "\u0001\u0000\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001"+ + "\u0001\u0001\u0001\u0001\u0001\u0001\u0003\u0001<\b\u0001\u0001\u0001"+ + "\u0001\u0001\u0001\u0001\u0003\u0001A\b\u0001\u0001\u0001\u0001\u0001"+ + "\u0001\u0001\u0001\u0001\u0003\u0001G\b\u0001\u0001\u0001\u0001\u0001"+ + "\u0001\u0001\u0001\u0001\u0003\u0001M\b\u0001\u0001\u0001\u0001\u0001"+ + "\u0001\u0001\u0001\u0001\u0003\u0001S\b\u0001\u0001\u0001\u0003\u0001"+ + "V\b\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0003\u0001"+ + "\\\b\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0003\u0001"+ + "b\b\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001"+ + "\u0001\u0001\u0001\u0001\u0003\u0001k\b\u0001\u0005\u0001m\b\u0001\n\u0001"+ + "\f\u0001p\t\u0001\u0001\u0002\u0001\u0002\u0003\u0002t\b\u0002\u0001\u0002"+ + "\u0001\u0002\u0001\u0002\u0001\u0002\u0001\u0002\u0001\u0002\u0001\u0002"+ + "\u0001\u0002\u0001\u0002\u0001\u0002\u0003\u0002\u0080\b\u0002\u0001\u0003"+ + "\u0001\u0003\u0001\u0003\u0003\u0003\u0085\b\u0003\u0001\u0004\u0001\u0004"+ + "\u0001\u0004\u0003\u0004\u008a\b\u0004\u0001\u0004\u0001\u0004\u0001\u0004"+ + "\u0001\u0004\u0001\u0004\u0001\u0004\u0001\u0004\u0001\u0004\u0001\u0004"+ + "\u0001\u0004\u0001\u0004\u0001\u0004\u0001\u0004\u0003\u0004\u0099\b\u0004"+ + "\u0001\u0005\u0001\u0005\u0001\u0005\u0005\u0005\u009e\b\u0005\n\u0005"+ + "\f\u0005\u00a1\t\u0005\u0001\u0006\u0001\u0006\u0001\u0006\u0001\u0007"+ + "\u0001\u0007\u0001\u0007\u0001\u0007\u0001\u0007\u0003\u0007\u00ab\b\u0007"+ + "\u0001\u0007\u0003\u0007\u00ae\b\u0007\u0001\b\u0001\b\u0001\b\u0003\b"+ + "\u00b3\b\b\u0001\b\u0003\b\u00b6\b\b\u0001\b\u0001\b\u0001\b\u0001\b\u0003"+ + "\b\u00bc\b\b\u0001\t\u0001\t\u0001\t\u0001\t\u0003\t\u00c2\b\t\u0003\t"+ + "\u00c4\b\t\u0001\n\u0001\n\u0001\n\u0003\n\u00c9\b\n\u0005\n\u00cb\b\n"+ + "\n\n\f\n\u00ce\t\n\u0001\n\u0001\n\u0001\u000b\u0001\u000b\u0001\u000b"+ + "\u0003\u000b\u00d5\b\u000b\u0005\u000b\u00d7\b\u000b\n\u000b\f\u000b\u00da"+ + "\t\u000b\u0001\f\u0001\f\u0001\f\u0003\f\u00df\b\f\u0001\r\u0001\r\u0001"+ + "\r\u0003\r\u00e4\b\r\u0001\u000e\u0001\u000e\u0003\u000e\u00e8\b\u000e"+ + "\u0001\u000f\u0001\u000f\u0003\u000f\u00ec\b\u000f\u0001\u000f\u0001\u000f"+ + "\u0003\u000f\u00f0\b\u000f\u0003\u000f\u00f2\b\u000f\u0001\u0010\u0001"+ + "\u0010\u0003\u0010\u00f6\b\u0010\u0001\u0010\u0001\u0010\u0001\u0011\u0001"+ + "\u0011\u0001\u0012\u0001\u0012\u0003\u0012\u00fe\b\u0012\u0001\u0012\u0001"+ + "\u0012\u0001\u0012\u0003\u0012\u0103\b\u0012\u0001\u0013\u0001\u0013\u0001"+ + "\u0013\u0003\u0013\u0108\b\u0013\u0001\u0014\u0001\u0014\u0001\u0014\u0003"+ + "\u0014\u010d\b\u0014\u0001\u0015\u0001\u0015\u0001\u0016\u0001\u0016\u0001"+ + "\u0016\u0003\u0016\u0114\b\u0016\u0001\u0017\u0001\u0017\u0001\u0017\u0000"+ + "\u0001\u0002\u0018\u0000\u0002\u0004\u0006\b\n\f\u000e\u0010\u0012\u0014"+ + "\u0016\u0018\u001a\u001c\u001e \"$&(*,.\u0000\u000b\u0001\u0000\u0001"+ + "\u0002\u0001\u0000\u0003\u0005\u0001\u0000\u0007\f\u0002\u0000\u0010\u0010"+ + "\u0012\u0012\u0001\u0000\u0003\u0004\u0001\u0000\u0013\u0014\u0001\u0000"+ + "\u0015\u0016\u0001\u0000\u0017\u0018\u0002\u0000\b\b\r\u000f\u0001\u0000"+ + "\u001c\u001d\u0001\u0000\u0010\u001a\u0136\u00000\u0001\u0000\u0000\u0000"+ + "\u0002;\u0001\u0000\u0000\u0000\u0004\u007f\u0001\u0000\u0000\u0000\u0006"+ + "\u0084\u0001\u0000\u0000\u0000\b\u0098\u0001\u0000\u0000\u0000\n\u009a"+ + "\u0001\u0000\u0000\u0000\f\u00a2\u0001\u0000\u0000\u0000\u000e\u00a5\u0001"+ + "\u0000\u0000\u0000\u0010\u00bb\u0001\u0000\u0000\u0000\u0012\u00bd\u0001"+ + "\u0000\u0000\u0000\u0014\u00c5\u0001\u0000\u0000\u0000\u0016\u00d1\u0001"+ + "\u0000\u0000\u0000\u0018\u00db\u0001\u0000\u0000\u0000\u001a\u00e3\u0001"+ + "\u0000\u0000\u0000\u001c\u00e7\u0001\u0000\u0000\u0000\u001e\u00f1\u0001"+ + "\u0000\u0000\u0000 \u00f3\u0001\u0000\u0000\u0000\"\u00f9\u0001\u0000"+ + "\u0000\u0000$\u0102\u0001\u0000\u0000\u0000&\u0107\u0001\u0000\u0000\u0000"+ + "(\u010c\u0001\u0000\u0000\u0000*\u010e\u0001\u0000\u0000\u0000,\u0113"+ + "\u0001\u0000\u0000\u0000.\u0115\u0001\u0000\u0000\u000001\u0003\u0002"+ + "\u0001\u000012\u0005\u0000\u0000\u00012\u0001\u0001\u0000\u0000\u0000"+ + "34\u0006\u0001\uffff\uffff\u000045\u0007\u0000\u0000\u00005<\u0003\u0002"+ + "\u0001\t6<\u0003\u0006\u0003\u000078\u0005\"\u0000\u000089\u0003\u0002"+ + "\u0001\u00009:\u0005#\u0000\u0000:<\u0001\u0000\u0000\u0000;3\u0001\u0000"+ + "\u0000\u0000;6\u0001\u0000\u0000\u0000;7\u0001\u0000\u0000\u0000\n\n\u0000\u0000>@\u0005\u0006\u0000\u0000?A\u0003"+ + "\u0012\t\u0000@?\u0001\u0000\u0000\u0000@A\u0001\u0000\u0000\u0000AB\u0001"+ + "\u0000\u0000\u0000Bm\u0003\u0002\u0001\nCD\n\b\u0000\u0000DF\u0007\u0001"+ + "\u0000\u0000EG\u0003\u0012\t\u0000FE\u0001\u0000\u0000\u0000FG\u0001\u0000"+ + "\u0000\u0000GH\u0001\u0000\u0000\u0000Hm\u0003\u0002\u0001\tIJ\n\u0007"+ + "\u0000\u0000JL\u0007\u0000\u0000\u0000KM\u0003\u0012\t\u0000LK\u0001\u0000"+ + "\u0000\u0000LM\u0001\u0000\u0000\u0000MN\u0001\u0000\u0000\u0000Nm\u0003"+ + "\u0002\u0001\bOP\n\u0006\u0000\u0000PR\u0007\u0002\u0000\u0000QS\u0005"+ + "\u0019\u0000\u0000RQ\u0001\u0000\u0000\u0000RS\u0001\u0000\u0000\u0000"+ + "SU\u0001\u0000\u0000\u0000TV\u0003\u0012\t\u0000UT\u0001\u0000\u0000\u0000"+ + "UV\u0001\u0000\u0000\u0000VW\u0001\u0000\u0000\u0000Wm\u0003\u0002\u0001"+ + "\u0007XY\n\u0005\u0000\u0000Y[\u0007\u0003\u0000\u0000Z\\\u0003\u0012"+ + "\t\u0000[Z\u0001\u0000\u0000\u0000[\\\u0001\u0000\u0000\u0000\\]\u0001"+ + "\u0000\u0000\u0000]m\u0003\u0002\u0001\u0006^_\n\u0004\u0000\u0000_a\u0005"+ + "\u0011\u0000\u0000`b\u0003\u0012\t\u0000a`\u0001\u0000\u0000\u0000ab\u0001"+ + "\u0000\u0000\u0000bc\u0001\u0000\u0000\u0000cm\u0003\u0002\u0001\u0005"+ + "de\n\u0001\u0000\u0000ef\u0005 \u0000\u0000fg\u0003\"\u0011\u0000gh\u0003"+ + "\u0004\u0002\u0000hj\u0005!\u0000\u0000ik\u0003\u001e\u000f\u0000ji\u0001"+ + "\u0000\u0000\u0000jk\u0001\u0000\u0000\u0000km\u0001\u0000\u0000\u0000"+ + "l=\u0001\u0000\u0000\u0000lC\u0001\u0000\u0000\u0000lI\u0001\u0000\u0000"+ + "\u0000lO\u0001\u0000\u0000\u0000lX\u0001\u0000\u0000\u0000l^\u0001\u0000"+ + "\u0000\u0000ld\u0001\u0000\u0000\u0000mp\u0001\u0000\u0000\u0000nl\u0001"+ + "\u0000\u0000\u0000no\u0001\u0000\u0000\u0000o\u0003\u0001\u0000\u0000"+ + "\u0000pn\u0001\u0000\u0000\u0000qs\u0005$\u0000\u0000rt\u0003\"\u0011"+ + "\u0000sr\u0001\u0000\u0000\u0000st\u0001\u0000\u0000\u0000t\u0080\u0001"+ + "\u0000\u0000\u0000uv\u0005*\u0000\u0000vw\u0005\u0006\u0000\u0000w\u0080"+ + "\u0003\u0002\u0001\u0000xy\u0005*\u0000\u0000yz\u0007\u0004\u0000\u0000"+ + "z\u0080\u0003\u0002\u0001\u0000{|\u0005*\u0000\u0000|}\u0007\u0000\u0000"+ + "\u0000}\u0080\u0003\u0002\u0001\u0000~\u0080\u0005*\u0000\u0000\u007f"+ + "q\u0001\u0000\u0000\u0000\u007fu\u0001\u0000\u0000\u0000\u007fx\u0001"+ + "\u0000\u0000\u0000\u007f{\u0001\u0000\u0000\u0000\u007f~\u0001\u0000\u0000"+ + "\u0000\u0080\u0005\u0001\u0000\u0000\u0000\u0081\u0085\u0003\b\u0004\u0000"+ + "\u0082\u0085\u0003\u000e\u0007\u0000\u0083\u0085\u0003&\u0013\u0000\u0084"+ + "\u0081\u0001\u0000\u0000\u0000\u0084\u0082\u0001\u0000\u0000\u0000\u0084"+ + "\u0083\u0001\u0000\u0000\u0000\u0085\u0007\u0001\u0000\u0000\u0000\u0086"+ + "\u0087\u0005,\u0000\u0000\u0087\u0089\u0005\"\u0000\u0000\u0088\u008a"+ + "\u0003\n\u0005\u0000\u0089\u0088\u0001\u0000\u0000\u0000\u0089\u008a\u0001"+ + "\u0000\u0000\u0000\u008a\u008b\u0001\u0000\u0000\u0000\u008b\u0099\u0005"+ + "#\u0000\u0000\u008c\u008d\u0005,\u0000\u0000\u008d\u008e\u0005\"\u0000"+ + "\u0000\u008e\u008f\u0003\n\u0005\u0000\u008f\u0090\u0005#\u0000\u0000"+ + "\u0090\u0091\u0003\f\u0006\u0000\u0091\u0099\u0001\u0000\u0000\u0000\u0092"+ + "\u0093\u0005,\u0000\u0000\u0093\u0094\u0003\f\u0006\u0000\u0094\u0095"+ + "\u0005\"\u0000\u0000\u0095\u0096\u0003\n\u0005\u0000\u0096\u0097\u0005"+ + "#\u0000\u0000\u0097\u0099\u0001\u0000\u0000\u0000\u0098\u0086\u0001\u0000"+ + "\u0000\u0000\u0098\u008c\u0001\u0000\u0000\u0000\u0098\u0092\u0001\u0000"+ + "\u0000\u0000\u0099\t\u0001\u0000\u0000\u0000\u009a\u009f\u0003\u0002\u0001"+ + "\u0000\u009b\u009c\u0005%\u0000\u0000\u009c\u009e\u0003\u0002\u0001\u0000"+ + "\u009d\u009b\u0001\u0000\u0000\u0000\u009e\u00a1\u0001\u0000\u0000\u0000"+ + "\u009f\u009d\u0001\u0000\u0000\u0000\u009f\u00a0\u0001\u0000\u0000\u0000"+ + "\u00a0\u000b\u0001\u0000\u0000\u0000\u00a1\u009f\u0001\u0000\u0000\u0000"+ + "\u00a2\u00a3\u0007\u0005\u0000\u0000\u00a3\u00a4\u0003\u0014\n\u0000\u00a4"+ + "\r\u0001\u0000\u0000\u0000\u00a5\u00aa\u0003\u0010\b\u0000\u00a6\u00a7"+ + "\u0005 \u0000\u0000\u00a7\u00a8\u0003\"\u0011\u0000\u00a8\u00a9\u0005"+ + "!\u0000\u0000\u00a9\u00ab\u0001\u0000\u0000\u0000\u00aa\u00a6\u0001\u0000"+ + "\u0000\u0000\u00aa\u00ab\u0001\u0000\u0000\u0000\u00ab\u00ad\u0001\u0000"+ + "\u0000\u0000\u00ac\u00ae\u0003\u001e\u000f\u0000\u00ad\u00ac\u0001\u0000"+ + "\u0000\u0000\u00ad\u00ae\u0001\u0000\u0000\u0000\u00ae\u000f\u0001\u0000"+ + "\u0000\u0000\u00af\u00b5\u0003\u001c\u000e\u0000\u00b0\u00b2\u0005\u001e"+ + "\u0000\u0000\u00b1\u00b3\u0003\u0016\u000b\u0000\u00b2\u00b1\u0001\u0000"+ + "\u0000\u0000\u00b2\u00b3\u0001\u0000\u0000\u0000\u00b3\u00b4\u0001\u0000"+ + "\u0000\u0000\u00b4\u00b6\u0005\u001f\u0000\u0000\u00b5\u00b0\u0001\u0000"+ + "\u0000\u0000\u00b5\u00b6\u0001\u0000\u0000\u0000\u00b6\u00bc\u0001\u0000"+ + "\u0000\u0000\u00b7\u00b8\u0005\u001e\u0000\u0000\u00b8\u00b9\u0003\u0016"+ + "\u000b\u0000\u00b9\u00ba\u0005\u001f\u0000\u0000\u00ba\u00bc\u0001\u0000"+ + "\u0000\u0000\u00bb\u00af\u0001\u0000\u0000\u0000\u00bb\u00b7\u0001\u0000"+ + "\u0000\u0000\u00bc\u0011\u0001\u0000\u0000\u0000\u00bd\u00be\u0007\u0006"+ + "\u0000\u0000\u00be\u00c3\u0003\u0014\n\u0000\u00bf\u00c1\u0007\u0007\u0000"+ + "\u0000\u00c0\u00c2\u0003\u0014\n\u0000\u00c1\u00c0\u0001\u0000\u0000\u0000"+ + "\u00c1\u00c2\u0001\u0000\u0000\u0000\u00c2\u00c4\u0001\u0000\u0000\u0000"+ + "\u00c3\u00bf\u0001\u0000\u0000\u0000\u00c3\u00c4\u0001\u0000\u0000\u0000"+ + "\u00c4\u0013\u0001\u0000\u0000\u0000\u00c5\u00cc\u0005\"\u0000\u0000\u00c6"+ + "\u00c8\u0003\u001a\r\u0000\u00c7\u00c9\u0005%\u0000\u0000\u00c8\u00c7"+ + "\u0001\u0000\u0000\u0000\u00c8\u00c9\u0001\u0000\u0000\u0000\u00c9\u00cb"+ + "\u0001\u0000\u0000\u0000\u00ca\u00c6\u0001\u0000\u0000\u0000\u00cb\u00ce"+ + "\u0001\u0000\u0000\u0000\u00cc\u00ca\u0001\u0000\u0000\u0000\u00cc\u00cd"+ + "\u0001\u0000\u0000\u0000\u00cd\u00cf\u0001\u0000\u0000\u0000\u00ce\u00cc"+ + "\u0001\u0000\u0000\u0000\u00cf\u00d0\u0005#\u0000\u0000\u00d0\u0015\u0001"+ + "\u0000\u0000\u0000\u00d1\u00d8\u0003\u0018\f\u0000\u00d2\u00d4\u0005%"+ + "\u0000\u0000\u00d3\u00d5\u0003\u0018\f\u0000\u00d4\u00d3\u0001\u0000\u0000"+ + "\u0000\u00d4\u00d5\u0001\u0000\u0000\u0000\u00d5\u00d7\u0001\u0000\u0000"+ + "\u0000\u00d6\u00d2\u0001\u0000\u0000\u0000\u00d7\u00da\u0001\u0000\u0000"+ + "\u0000\u00d8\u00d6\u0001\u0000\u0000\u0000\u00d8\u00d9\u0001\u0000\u0000"+ + "\u0000\u00d9\u0017\u0001\u0000\u0000\u0000\u00da\u00d8\u0001\u0000\u0000"+ + "\u0000\u00db\u00de\u0003\u001a\r\u0000\u00dc\u00dd\u0007\b\u0000\u0000"+ + "\u00dd\u00df\u0005&\u0000\u0000\u00de\u00dc\u0001\u0000\u0000\u0000\u00de"+ + "\u00df\u0001\u0000\u0000\u0000\u00df\u0019\u0001\u0000\u0000\u0000\u00e0"+ + "\u00e4\u0003\u001c\u000e\u0000\u00e1\u00e4\u0005&\u0000\u0000\u00e2\u00e4"+ + "\u0003(\u0014\u0000\u00e3\u00e0\u0001\u0000\u0000\u0000\u00e3\u00e1\u0001"+ + "\u0000\u0000\u0000\u00e3\u00e2\u0001\u0000\u0000\u0000\u00e4\u001b\u0001"+ + "\u0000\u0000\u0000\u00e5\u00e8\u0005,\u0000\u0000\u00e6\u00e8\u0003.\u0017"+ + "\u0000\u00e7\u00e5\u0001\u0000\u0000\u0000\u00e7\u00e6\u0001\u0000\u0000"+ + "\u0000\u00e8\u001d\u0001\u0000\u0000\u0000\u00e9\u00eb\u0003 \u0010\u0000"+ + "\u00ea\u00ec\u0003$\u0012\u0000\u00eb\u00ea\u0001\u0000\u0000\u0000\u00eb"+ + "\u00ec\u0001\u0000\u0000\u0000\u00ec\u00f2\u0001\u0000\u0000\u0000\u00ed"+ + "\u00ef\u0003$\u0012\u0000\u00ee\u00f0\u0003 \u0010\u0000\u00ef\u00ee\u0001"+ + "\u0000\u0000\u0000\u00ef\u00f0\u0001\u0000\u0000\u0000\u00f0\u00f2\u0001"+ + "\u0000\u0000\u0000\u00f1\u00e9\u0001\u0000\u0000\u0000\u00f1\u00ed\u0001"+ + "\u0000\u0000\u0000\u00f2\u001f\u0001\u0000\u0000\u0000\u00f3\u00f5\u0005"+ + "\u001a\u0000\u0000\u00f4\u00f6\u0005\u0002\u0000\u0000\u00f5\u00f4\u0001"+ + "\u0000\u0000\u0000\u00f5\u00f6\u0001\u0000\u0000\u0000\u00f6\u00f7\u0001"+ + "\u0000\u0000\u0000\u00f7\u00f8\u0003\"\u0011\u0000\u00f8!\u0001\u0000"+ + "\u0000\u0000\u00f9\u00fa\u0003\u0002\u0001\u0000\u00fa#\u0001\u0000\u0000"+ + "\u0000\u00fb\u00fd\u0005\u001b\u0000\u0000\u00fc\u00fe\u0005\u0002\u0000"+ + "\u0000\u00fd\u00fc\u0001\u0000\u0000\u0000\u00fd\u00fe\u0001\u0000\u0000"+ + "\u0000\u00fe\u00ff\u0001\u0000\u0000\u0000\u00ff\u0103\u0003,\u0016\u0000"+ + "\u0100\u0101\u0005\u001b\u0000\u0000\u0101\u0103\u0007\t\u0000\u0000\u0102"+ + "\u00fb\u0001\u0000\u0000\u0000\u0102\u0100\u0001\u0000\u0000\u0000\u0103"+ + "%\u0001\u0000\u0000\u0000\u0104\u0108\u0003(\u0014\u0000\u0105\u0108\u0003"+ + "*\u0015\u0000\u0106\u0108\u0003,\u0016\u0000\u0107\u0104\u0001\u0000\u0000"+ + "\u0000\u0107\u0105\u0001\u0000\u0000\u0000\u0107\u0106\u0001\u0000\u0000"+ + "\u0000\u0108\'\u0001\u0000\u0000\u0000\u0109\u010d\u0005(\u0000\u0000"+ + "\u010a\u010d\u0005\'\u0000\u0000\u010b\u010d\u0005)\u0000\u0000\u010c"+ + "\u0109\u0001\u0000\u0000\u0000\u010c\u010a\u0001\u0000\u0000\u0000\u010c"+ + "\u010b\u0001\u0000\u0000\u0000\u010d)\u0001\u0000\u0000\u0000\u010e\u010f"+ + "\u0005&\u0000\u0000\u010f+\u0001\u0000\u0000\u0000\u0110\u0114\u0005*"+ + "\u0000\u0000\u0111\u0114\u0005+\u0000\u0000\u0112\u0114\u0003(\u0014\u0000"+ + "\u0113\u0110\u0001\u0000\u0000\u0000\u0113\u0111\u0001\u0000\u0000\u0000"+ + "\u0113\u0112\u0001\u0000\u0000\u0000\u0114-\u0001\u0000\u0000\u0000\u0115"+ + "\u0116\u0007\n\u0000\u0000\u0116/\u0001\u0000\u0000\u0000(;@FLRU[ajln"+ + "s\u007f\u0084\u0089\u0098\u009f\u00aa\u00ad\u00b2\u00b5\u00bb\u00c1\u00c3"+ + "\u00c8\u00cc\u00d4\u00d8\u00de\u00e3\u00e7\u00eb\u00ef\u00f1\u00f5\u00fd"+ + "\u0102\u0107\u010c\u0113"; + 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); + } + } +} diff --git a/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/parser/PromqlBaseParserBaseListener.java b/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/parser/PromqlBaseParserBaseListener.java new file mode 100644 index 0000000000000..4235c474a4f61 --- /dev/null +++ b/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/parser/PromqlBaseParserBaseListener.java @@ -0,0 +1,408 @@ +// ANTLR GENERATED CODE: DO NOT EDIT +package org.elasticsearch.xpack.esql.parser; + +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + + +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 PromqlBaseParserListener}, + * which can be extended to create a listener which only needs to handle a subset + * of the available methods. + */ +@SuppressWarnings("CheckReturnValue") +public class PromqlBaseParserBaseListener implements PromqlBaseParserListener { + /** + * {@inheritDoc} + * + *

The default implementation does nothing.

+ */ + @Override public void enterSingleStatement(PromqlBaseParser.SingleStatementContext ctx) { } + /** + * {@inheritDoc} + * + *

The default implementation does nothing.

+ */ + @Override public void exitSingleStatement(PromqlBaseParser.SingleStatementContext ctx) { } + /** + * {@inheritDoc} + * + *

The default implementation does nothing.

+ */ + @Override public void enterValueExpression(PromqlBaseParser.ValueExpressionContext ctx) { } + /** + * {@inheritDoc} + * + *

The default implementation does nothing.

+ */ + @Override public void exitValueExpression(PromqlBaseParser.ValueExpressionContext ctx) { } + /** + * {@inheritDoc} + * + *

The default implementation does nothing.

+ */ + @Override public void enterSubquery(PromqlBaseParser.SubqueryContext ctx) { } + /** + * {@inheritDoc} + * + *

The default implementation does nothing.

+ */ + @Override public void exitSubquery(PromqlBaseParser.SubqueryContext ctx) { } + /** + * {@inheritDoc} + * + *

The default implementation does nothing.

+ */ + @Override public void enterParenthesized(PromqlBaseParser.ParenthesizedContext ctx) { } + /** + * {@inheritDoc} + * + *

The default implementation does nothing.

+ */ + @Override public void exitParenthesized(PromqlBaseParser.ParenthesizedContext ctx) { } + /** + * {@inheritDoc} + * + *

The default implementation does nothing.

+ */ + @Override public void enterArithmeticBinary(PromqlBaseParser.ArithmeticBinaryContext ctx) { } + /** + * {@inheritDoc} + * + *

The default implementation does nothing.

+ */ + @Override public void exitArithmeticBinary(PromqlBaseParser.ArithmeticBinaryContext ctx) { } + /** + * {@inheritDoc} + * + *

The default implementation does nothing.

+ */ + @Override public void enterArithmeticUnary(PromqlBaseParser.ArithmeticUnaryContext ctx) { } + /** + * {@inheritDoc} + * + *

The default implementation does nothing.

+ */ + @Override public void exitArithmeticUnary(PromqlBaseParser.ArithmeticUnaryContext ctx) { } + /** + * {@inheritDoc} + * + *

The default implementation does nothing.

+ */ + @Override public void enterSubqueryResolution(PromqlBaseParser.SubqueryResolutionContext ctx) { } + /** + * {@inheritDoc} + * + *

The default implementation does nothing.

+ */ + @Override public void exitSubqueryResolution(PromqlBaseParser.SubqueryResolutionContext ctx) { } + /** + * {@inheritDoc} + * + *

The default implementation does nothing.

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

The default implementation does nothing.

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

The default implementation does nothing.

+ */ + @Override public void enterFunction(PromqlBaseParser.FunctionContext ctx) { } + /** + * {@inheritDoc} + * + *

The default implementation does nothing.

+ */ + @Override public void exitFunction(PromqlBaseParser.FunctionContext ctx) { } + /** + * {@inheritDoc} + * + *

The default implementation does nothing.

+ */ + @Override public void enterFunctionParams(PromqlBaseParser.FunctionParamsContext ctx) { } + /** + * {@inheritDoc} + * + *

The default implementation does nothing.

+ */ + @Override public void exitFunctionParams(PromqlBaseParser.FunctionParamsContext ctx) { } + /** + * {@inheritDoc} + * + *

The default implementation does nothing.

+ */ + @Override public void enterGrouping(PromqlBaseParser.GroupingContext ctx) { } + /** + * {@inheritDoc} + * + *

The default implementation does nothing.

+ */ + @Override public void exitGrouping(PromqlBaseParser.GroupingContext ctx) { } + /** + * {@inheritDoc} + * + *

The default implementation does nothing.

+ */ + @Override public void enterSelector(PromqlBaseParser.SelectorContext ctx) { } + /** + * {@inheritDoc} + * + *

The default implementation does nothing.

+ */ + @Override public void exitSelector(PromqlBaseParser.SelectorContext ctx) { } + /** + * {@inheritDoc} + * + *

The default implementation does nothing.

+ */ + @Override public void enterSeriesMatcher(PromqlBaseParser.SeriesMatcherContext ctx) { } + /** + * {@inheritDoc} + * + *

The default implementation does nothing.

+ */ + @Override public void exitSeriesMatcher(PromqlBaseParser.SeriesMatcherContext ctx) { } + /** + * {@inheritDoc} + * + *

The default implementation does nothing.

+ */ + @Override public void enterModifier(PromqlBaseParser.ModifierContext ctx) { } + /** + * {@inheritDoc} + * + *

The default implementation does nothing.

+ */ + @Override public void exitModifier(PromqlBaseParser.ModifierContext ctx) { } + /** + * {@inheritDoc} + * + *

The default implementation does nothing.

+ */ + @Override public void enterLabelList(PromqlBaseParser.LabelListContext ctx) { } + /** + * {@inheritDoc} + * + *

The default implementation does nothing.

+ */ + @Override public void exitLabelList(PromqlBaseParser.LabelListContext ctx) { } + /** + * {@inheritDoc} + * + *

The default implementation does nothing.

+ */ + @Override public void enterLabels(PromqlBaseParser.LabelsContext ctx) { } + /** + * {@inheritDoc} + * + *

The default implementation does nothing.

+ */ + @Override public void exitLabels(PromqlBaseParser.LabelsContext ctx) { } + /** + * {@inheritDoc} + * + *

The default implementation does nothing.

+ */ + @Override public void enterLabel(PromqlBaseParser.LabelContext ctx) { } + /** + * {@inheritDoc} + * + *

The default implementation does nothing.

+ */ + @Override public void exitLabel(PromqlBaseParser.LabelContext ctx) { } + /** + * {@inheritDoc} + * + *

The default implementation does nothing.

+ */ + @Override public void enterLabelName(PromqlBaseParser.LabelNameContext ctx) { } + /** + * {@inheritDoc} + * + *

The default implementation does nothing.

+ */ + @Override public void exitLabelName(PromqlBaseParser.LabelNameContext ctx) { } + /** + * {@inheritDoc} + * + *

The default implementation does nothing.

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

The default implementation does nothing.

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

The default implementation does nothing.

+ */ + @Override public void enterEvaluation(PromqlBaseParser.EvaluationContext ctx) { } + /** + * {@inheritDoc} + * + *

The default implementation does nothing.

+ */ + @Override public void exitEvaluation(PromqlBaseParser.EvaluationContext ctx) { } + /** + * {@inheritDoc} + * + *

The default implementation does nothing.

+ */ + @Override public void enterOffset(PromqlBaseParser.OffsetContext ctx) { } + /** + * {@inheritDoc} + * + *

The default implementation does nothing.

+ */ + @Override public void exitOffset(PromqlBaseParser.OffsetContext ctx) { } + /** + * {@inheritDoc} + * + *

The default implementation does nothing.

+ */ + @Override public void enterDuration(PromqlBaseParser.DurationContext ctx) { } + /** + * {@inheritDoc} + * + *

The default implementation does nothing.

+ */ + @Override public void exitDuration(PromqlBaseParser.DurationContext ctx) { } + /** + * {@inheritDoc} + * + *

The default implementation does nothing.

+ */ + @Override public void enterAt(PromqlBaseParser.AtContext ctx) { } + /** + * {@inheritDoc} + * + *

The default implementation does nothing.

+ */ + @Override public void exitAt(PromqlBaseParser.AtContext ctx) { } + /** + * {@inheritDoc} + * + *

The default implementation does nothing.

+ */ + @Override public void enterConstant(PromqlBaseParser.ConstantContext ctx) { } + /** + * {@inheritDoc} + * + *

The default implementation does nothing.

+ */ + @Override public void exitConstant(PromqlBaseParser.ConstantContext ctx) { } + /** + * {@inheritDoc} + * + *

The default implementation does nothing.

+ */ + @Override public void enterDecimalLiteral(PromqlBaseParser.DecimalLiteralContext ctx) { } + /** + * {@inheritDoc} + * + *

The default implementation does nothing.

+ */ + @Override public void exitDecimalLiteral(PromqlBaseParser.DecimalLiteralContext ctx) { } + /** + * {@inheritDoc} + * + *

The default implementation does nothing.

+ */ + @Override public void enterIntegerLiteral(PromqlBaseParser.IntegerLiteralContext ctx) { } + /** + * {@inheritDoc} + * + *

The default implementation does nothing.

+ */ + @Override public void exitIntegerLiteral(PromqlBaseParser.IntegerLiteralContext ctx) { } + /** + * {@inheritDoc} + * + *

The default implementation does nothing.

+ */ + @Override public void enterHexLiteral(PromqlBaseParser.HexLiteralContext ctx) { } + /** + * {@inheritDoc} + * + *

The default implementation does nothing.

+ */ + @Override public void exitHexLiteral(PromqlBaseParser.HexLiteralContext ctx) { } + /** + * {@inheritDoc} + * + *

The default implementation does nothing.

+ */ + @Override public void enterString(PromqlBaseParser.StringContext ctx) { } + /** + * {@inheritDoc} + * + *

The default implementation does nothing.

+ */ + @Override public void exitString(PromqlBaseParser.StringContext ctx) { } + /** + * {@inheritDoc} + * + *

The default implementation does nothing.

+ */ + @Override public void enterTimeValue(PromqlBaseParser.TimeValueContext ctx) { } + /** + * {@inheritDoc} + * + *

The default implementation does nothing.

+ */ + @Override public void exitTimeValue(PromqlBaseParser.TimeValueContext ctx) { } + /** + * {@inheritDoc} + * + *

The default implementation does nothing.

+ */ + @Override public void enterNonReserved(PromqlBaseParser.NonReservedContext ctx) { } + /** + * {@inheritDoc} + * + *

The default implementation does nothing.

+ */ + @Override public void exitNonReserved(PromqlBaseParser.NonReservedContext 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) { } +} diff --git a/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/parser/PromqlBaseParserBaseVisitor.java b/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/parser/PromqlBaseParserBaseVisitor.java new file mode 100644 index 0000000000000..83ab302486dc2 --- /dev/null +++ b/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/parser/PromqlBaseParserBaseVisitor.java @@ -0,0 +1,233 @@ +// ANTLR GENERATED CODE: DO NOT EDIT +package org.elasticsearch.xpack.esql.parser; + +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import org.antlr.v4.runtime.tree.AbstractParseTreeVisitor; + +/** + * This class provides an empty implementation of {@link PromqlBaseParserVisitor}, + * which can be extended to create a visitor which only needs to handle a subset + * of the available methods. + * + * @param The return type of the visit operation. Use {@link Void} for + * operations with no return type. + */ +@SuppressWarnings("CheckReturnValue") +public class PromqlBaseParserBaseVisitor extends AbstractParseTreeVisitor implements PromqlBaseParserVisitor { + /** + * {@inheritDoc} + * + *

The default implementation returns the result of calling + * {@link #visitChildren} on {@code ctx}.

+ */ + @Override public T visitSingleStatement(PromqlBaseParser.SingleStatementContext ctx) { return visitChildren(ctx); } + /** + * {@inheritDoc} + * + *

The default implementation returns the result of calling + * {@link #visitChildren} on {@code ctx}.

+ */ + @Override public T visitValueExpression(PromqlBaseParser.ValueExpressionContext ctx) { return visitChildren(ctx); } + /** + * {@inheritDoc} + * + *

The default implementation returns the result of calling + * {@link #visitChildren} on {@code ctx}.

+ */ + @Override public T visitSubquery(PromqlBaseParser.SubqueryContext ctx) { return visitChildren(ctx); } + /** + * {@inheritDoc} + * + *

The default implementation returns the result of calling + * {@link #visitChildren} on {@code ctx}.

+ */ + @Override public T visitParenthesized(PromqlBaseParser.ParenthesizedContext ctx) { return visitChildren(ctx); } + /** + * {@inheritDoc} + * + *

The default implementation returns the result of calling + * {@link #visitChildren} on {@code ctx}.

+ */ + @Override public T visitArithmeticBinary(PromqlBaseParser.ArithmeticBinaryContext ctx) { return visitChildren(ctx); } + /** + * {@inheritDoc} + * + *

The default implementation returns the result of calling + * {@link #visitChildren} on {@code ctx}.

+ */ + @Override public T visitArithmeticUnary(PromqlBaseParser.ArithmeticUnaryContext ctx) { return visitChildren(ctx); } + /** + * {@inheritDoc} + * + *

The default implementation returns the result of calling + * {@link #visitChildren} on {@code ctx}.

+ */ + @Override public T visitSubqueryResolution(PromqlBaseParser.SubqueryResolutionContext ctx) { return visitChildren(ctx); } + /** + * {@inheritDoc} + * + *

The default implementation returns the result of calling + * {@link #visitChildren} on {@code ctx}.

+ */ + @Override public T visitValue(PromqlBaseParser.ValueContext ctx) { return visitChildren(ctx); } + /** + * {@inheritDoc} + * + *

The default implementation returns the result of calling + * {@link #visitChildren} on {@code ctx}.

+ */ + @Override public T visitFunction(PromqlBaseParser.FunctionContext ctx) { return visitChildren(ctx); } + /** + * {@inheritDoc} + * + *

The default implementation returns the result of calling + * {@link #visitChildren} on {@code ctx}.

+ */ + @Override public T visitFunctionParams(PromqlBaseParser.FunctionParamsContext ctx) { return visitChildren(ctx); } + /** + * {@inheritDoc} + * + *

The default implementation returns the result of calling + * {@link #visitChildren} on {@code ctx}.

+ */ + @Override public T visitGrouping(PromqlBaseParser.GroupingContext ctx) { return visitChildren(ctx); } + /** + * {@inheritDoc} + * + *

The default implementation returns the result of calling + * {@link #visitChildren} on {@code ctx}.

+ */ + @Override public T visitSelector(PromqlBaseParser.SelectorContext ctx) { return visitChildren(ctx); } + /** + * {@inheritDoc} + * + *

The default implementation returns the result of calling + * {@link #visitChildren} on {@code ctx}.

+ */ + @Override public T visitSeriesMatcher(PromqlBaseParser.SeriesMatcherContext ctx) { return visitChildren(ctx); } + /** + * {@inheritDoc} + * + *

The default implementation returns the result of calling + * {@link #visitChildren} on {@code ctx}.

+ */ + @Override public T visitModifier(PromqlBaseParser.ModifierContext ctx) { return visitChildren(ctx); } + /** + * {@inheritDoc} + * + *

The default implementation returns the result of calling + * {@link #visitChildren} on {@code ctx}.

+ */ + @Override public T visitLabelList(PromqlBaseParser.LabelListContext ctx) { return visitChildren(ctx); } + /** + * {@inheritDoc} + * + *

The default implementation returns the result of calling + * {@link #visitChildren} on {@code ctx}.

+ */ + @Override public T visitLabels(PromqlBaseParser.LabelsContext ctx) { return visitChildren(ctx); } + /** + * {@inheritDoc} + * + *

The default implementation returns the result of calling + * {@link #visitChildren} on {@code ctx}.

+ */ + @Override public T visitLabel(PromqlBaseParser.LabelContext ctx) { return visitChildren(ctx); } + /** + * {@inheritDoc} + * + *

The default implementation returns the result of calling + * {@link #visitChildren} on {@code ctx}.

+ */ + @Override public T visitLabelName(PromqlBaseParser.LabelNameContext ctx) { return visitChildren(ctx); } + /** + * {@inheritDoc} + * + *

The default implementation returns the result of calling + * {@link #visitChildren} on {@code ctx}.

+ */ + @Override public T visitIdentifier(PromqlBaseParser.IdentifierContext ctx) { return visitChildren(ctx); } + /** + * {@inheritDoc} + * + *

The default implementation returns the result of calling + * {@link #visitChildren} on {@code ctx}.

+ */ + @Override public T visitEvaluation(PromqlBaseParser.EvaluationContext ctx) { return visitChildren(ctx); } + /** + * {@inheritDoc} + * + *

The default implementation returns the result of calling + * {@link #visitChildren} on {@code ctx}.

+ */ + @Override public T visitOffset(PromqlBaseParser.OffsetContext ctx) { return visitChildren(ctx); } + /** + * {@inheritDoc} + * + *

The default implementation returns the result of calling + * {@link #visitChildren} on {@code ctx}.

+ */ + @Override public T visitDuration(PromqlBaseParser.DurationContext ctx) { return visitChildren(ctx); } + /** + * {@inheritDoc} + * + *

The default implementation returns the result of calling + * {@link #visitChildren} on {@code ctx}.

+ */ + @Override public T visitAt(PromqlBaseParser.AtContext ctx) { return visitChildren(ctx); } + /** + * {@inheritDoc} + * + *

The default implementation returns the result of calling + * {@link #visitChildren} on {@code ctx}.

+ */ + @Override public T visitConstant(PromqlBaseParser.ConstantContext ctx) { return visitChildren(ctx); } + /** + * {@inheritDoc} + * + *

The default implementation returns the result of calling + * {@link #visitChildren} on {@code ctx}.

+ */ + @Override public T visitDecimalLiteral(PromqlBaseParser.DecimalLiteralContext ctx) { return visitChildren(ctx); } + /** + * {@inheritDoc} + * + *

The default implementation returns the result of calling + * {@link #visitChildren} on {@code ctx}.

+ */ + @Override public T visitIntegerLiteral(PromqlBaseParser.IntegerLiteralContext ctx) { return visitChildren(ctx); } + /** + * {@inheritDoc} + * + *

The default implementation returns the result of calling + * {@link #visitChildren} on {@code ctx}.

+ */ + @Override public T visitHexLiteral(PromqlBaseParser.HexLiteralContext ctx) { return visitChildren(ctx); } + /** + * {@inheritDoc} + * + *

The default implementation returns the result of calling + * {@link #visitChildren} on {@code ctx}.

+ */ + @Override public T visitString(PromqlBaseParser.StringContext ctx) { return visitChildren(ctx); } + /** + * {@inheritDoc} + * + *

The default implementation returns the result of calling + * {@link #visitChildren} on {@code ctx}.

+ */ + @Override public T visitTimeValue(PromqlBaseParser.TimeValueContext ctx) { return visitChildren(ctx); } + /** + * {@inheritDoc} + * + *

The default implementation returns the result of calling + * {@link #visitChildren} on {@code ctx}.

+ */ + @Override public T visitNonReserved(PromqlBaseParser.NonReservedContext ctx) { return visitChildren(ctx); } +} diff --git a/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/parser/PromqlBaseParserListener.java b/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/parser/PromqlBaseParserListener.java new file mode 100644 index 0000000000000..a9bc9e7beff98 --- /dev/null +++ b/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/parser/PromqlBaseParserListener.java @@ -0,0 +1,334 @@ +// ANTLR GENERATED CODE: DO NOT EDIT +package org.elasticsearch.xpack.esql.parser; + +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import org.antlr.v4.runtime.tree.ParseTreeListener; + +/** + * This interface defines a complete listener for a parse tree produced by + * {@link PromqlBaseParser}. + */ +public interface PromqlBaseParserListener extends ParseTreeListener { + /** + * Enter a parse tree produced by {@link PromqlBaseParser#singleStatement}. + * @param ctx the parse tree + */ + void enterSingleStatement(PromqlBaseParser.SingleStatementContext ctx); + /** + * Exit a parse tree produced by {@link PromqlBaseParser#singleStatement}. + * @param ctx the parse tree + */ + void exitSingleStatement(PromqlBaseParser.SingleStatementContext ctx); + /** + * Enter a parse tree produced by the {@code valueExpression} + * labeled alternative in {@link PromqlBaseParser#expression}. + * @param ctx the parse tree + */ + void enterValueExpression(PromqlBaseParser.ValueExpressionContext ctx); + /** + * Exit a parse tree produced by the {@code valueExpression} + * labeled alternative in {@link PromqlBaseParser#expression}. + * @param ctx the parse tree + */ + void exitValueExpression(PromqlBaseParser.ValueExpressionContext ctx); + /** + * Enter a parse tree produced by the {@code subquery} + * labeled alternative in {@link PromqlBaseParser#expression}. + * @param ctx the parse tree + */ + void enterSubquery(PromqlBaseParser.SubqueryContext ctx); + /** + * Exit a parse tree produced by the {@code subquery} + * labeled alternative in {@link PromqlBaseParser#expression}. + * @param ctx the parse tree + */ + void exitSubquery(PromqlBaseParser.SubqueryContext ctx); + /** + * Enter a parse tree produced by the {@code parenthesized} + * labeled alternative in {@link PromqlBaseParser#expression}. + * @param ctx the parse tree + */ + void enterParenthesized(PromqlBaseParser.ParenthesizedContext ctx); + /** + * Exit a parse tree produced by the {@code parenthesized} + * labeled alternative in {@link PromqlBaseParser#expression}. + * @param ctx the parse tree + */ + void exitParenthesized(PromqlBaseParser.ParenthesizedContext ctx); + /** + * Enter a parse tree produced by the {@code arithmeticBinary} + * labeled alternative in {@link PromqlBaseParser#expression}. + * @param ctx the parse tree + */ + void enterArithmeticBinary(PromqlBaseParser.ArithmeticBinaryContext ctx); + /** + * Exit a parse tree produced by the {@code arithmeticBinary} + * labeled alternative in {@link PromqlBaseParser#expression}. + * @param ctx the parse tree + */ + void exitArithmeticBinary(PromqlBaseParser.ArithmeticBinaryContext ctx); + /** + * Enter a parse tree produced by the {@code arithmeticUnary} + * labeled alternative in {@link PromqlBaseParser#expression}. + * @param ctx the parse tree + */ + void enterArithmeticUnary(PromqlBaseParser.ArithmeticUnaryContext ctx); + /** + * Exit a parse tree produced by the {@code arithmeticUnary} + * labeled alternative in {@link PromqlBaseParser#expression}. + * @param ctx the parse tree + */ + void exitArithmeticUnary(PromqlBaseParser.ArithmeticUnaryContext ctx); + /** + * Enter a parse tree produced by {@link PromqlBaseParser#subqueryResolution}. + * @param ctx the parse tree + */ + void enterSubqueryResolution(PromqlBaseParser.SubqueryResolutionContext ctx); + /** + * Exit a parse tree produced by {@link PromqlBaseParser#subqueryResolution}. + * @param ctx the parse tree + */ + void exitSubqueryResolution(PromqlBaseParser.SubqueryResolutionContext ctx); + /** + * Enter a parse tree produced by {@link PromqlBaseParser#value}. + * @param ctx the parse tree + */ + void enterValue(PromqlBaseParser.ValueContext ctx); + /** + * Exit a parse tree produced by {@link PromqlBaseParser#value}. + * @param ctx the parse tree + */ + void exitValue(PromqlBaseParser.ValueContext ctx); + /** + * Enter a parse tree produced by {@link PromqlBaseParser#function}. + * @param ctx the parse tree + */ + void enterFunction(PromqlBaseParser.FunctionContext ctx); + /** + * Exit a parse tree produced by {@link PromqlBaseParser#function}. + * @param ctx the parse tree + */ + void exitFunction(PromqlBaseParser.FunctionContext ctx); + /** + * Enter a parse tree produced by {@link PromqlBaseParser#functionParams}. + * @param ctx the parse tree + */ + void enterFunctionParams(PromqlBaseParser.FunctionParamsContext ctx); + /** + * Exit a parse tree produced by {@link PromqlBaseParser#functionParams}. + * @param ctx the parse tree + */ + void exitFunctionParams(PromqlBaseParser.FunctionParamsContext ctx); + /** + * Enter a parse tree produced by {@link PromqlBaseParser#grouping}. + * @param ctx the parse tree + */ + void enterGrouping(PromqlBaseParser.GroupingContext ctx); + /** + * Exit a parse tree produced by {@link PromqlBaseParser#grouping}. + * @param ctx the parse tree + */ + void exitGrouping(PromqlBaseParser.GroupingContext ctx); + /** + * Enter a parse tree produced by {@link PromqlBaseParser#selector}. + * @param ctx the parse tree + */ + void enterSelector(PromqlBaseParser.SelectorContext ctx); + /** + * Exit a parse tree produced by {@link PromqlBaseParser#selector}. + * @param ctx the parse tree + */ + void exitSelector(PromqlBaseParser.SelectorContext ctx); + /** + * Enter a parse tree produced by {@link PromqlBaseParser#seriesMatcher}. + * @param ctx the parse tree + */ + void enterSeriesMatcher(PromqlBaseParser.SeriesMatcherContext ctx); + /** + * Exit a parse tree produced by {@link PromqlBaseParser#seriesMatcher}. + * @param ctx the parse tree + */ + void exitSeriesMatcher(PromqlBaseParser.SeriesMatcherContext ctx); + /** + * Enter a parse tree produced by {@link PromqlBaseParser#modifier}. + * @param ctx the parse tree + */ + void enterModifier(PromqlBaseParser.ModifierContext ctx); + /** + * Exit a parse tree produced by {@link PromqlBaseParser#modifier}. + * @param ctx the parse tree + */ + void exitModifier(PromqlBaseParser.ModifierContext ctx); + /** + * Enter a parse tree produced by {@link PromqlBaseParser#labelList}. + * @param ctx the parse tree + */ + void enterLabelList(PromqlBaseParser.LabelListContext ctx); + /** + * Exit a parse tree produced by {@link PromqlBaseParser#labelList}. + * @param ctx the parse tree + */ + void exitLabelList(PromqlBaseParser.LabelListContext ctx); + /** + * Enter a parse tree produced by {@link PromqlBaseParser#labels}. + * @param ctx the parse tree + */ + void enterLabels(PromqlBaseParser.LabelsContext ctx); + /** + * Exit a parse tree produced by {@link PromqlBaseParser#labels}. + * @param ctx the parse tree + */ + void exitLabels(PromqlBaseParser.LabelsContext ctx); + /** + * Enter a parse tree produced by {@link PromqlBaseParser#label}. + * @param ctx the parse tree + */ + void enterLabel(PromqlBaseParser.LabelContext ctx); + /** + * Exit a parse tree produced by {@link PromqlBaseParser#label}. + * @param ctx the parse tree + */ + void exitLabel(PromqlBaseParser.LabelContext ctx); + /** + * Enter a parse tree produced by {@link PromqlBaseParser#labelName}. + * @param ctx the parse tree + */ + void enterLabelName(PromqlBaseParser.LabelNameContext ctx); + /** + * Exit a parse tree produced by {@link PromqlBaseParser#labelName}. + * @param ctx the parse tree + */ + void exitLabelName(PromqlBaseParser.LabelNameContext ctx); + /** + * Enter a parse tree produced by {@link PromqlBaseParser#identifier}. + * @param ctx the parse tree + */ + void enterIdentifier(PromqlBaseParser.IdentifierContext ctx); + /** + * Exit a parse tree produced by {@link PromqlBaseParser#identifier}. + * @param ctx the parse tree + */ + void exitIdentifier(PromqlBaseParser.IdentifierContext ctx); + /** + * Enter a parse tree produced by {@link PromqlBaseParser#evaluation}. + * @param ctx the parse tree + */ + void enterEvaluation(PromqlBaseParser.EvaluationContext ctx); + /** + * Exit a parse tree produced by {@link PromqlBaseParser#evaluation}. + * @param ctx the parse tree + */ + void exitEvaluation(PromqlBaseParser.EvaluationContext ctx); + /** + * Enter a parse tree produced by {@link PromqlBaseParser#offset}. + * @param ctx the parse tree + */ + void enterOffset(PromqlBaseParser.OffsetContext ctx); + /** + * Exit a parse tree produced by {@link PromqlBaseParser#offset}. + * @param ctx the parse tree + */ + void exitOffset(PromqlBaseParser.OffsetContext ctx); + /** + * Enter a parse tree produced by {@link PromqlBaseParser#duration}. + * @param ctx the parse tree + */ + void enterDuration(PromqlBaseParser.DurationContext ctx); + /** + * Exit a parse tree produced by {@link PromqlBaseParser#duration}. + * @param ctx the parse tree + */ + void exitDuration(PromqlBaseParser.DurationContext ctx); + /** + * Enter a parse tree produced by {@link PromqlBaseParser#at}. + * @param ctx the parse tree + */ + void enterAt(PromqlBaseParser.AtContext ctx); + /** + * Exit a parse tree produced by {@link PromqlBaseParser#at}. + * @param ctx the parse tree + */ + void exitAt(PromqlBaseParser.AtContext ctx); + /** + * Enter a parse tree produced by {@link PromqlBaseParser#constant}. + * @param ctx the parse tree + */ + void enterConstant(PromqlBaseParser.ConstantContext ctx); + /** + * Exit a parse tree produced by {@link PromqlBaseParser#constant}. + * @param ctx the parse tree + */ + void exitConstant(PromqlBaseParser.ConstantContext ctx); + /** + * Enter a parse tree produced by the {@code decimalLiteral} + * labeled alternative in {@link PromqlBaseParser#number}. + * @param ctx the parse tree + */ + void enterDecimalLiteral(PromqlBaseParser.DecimalLiteralContext ctx); + /** + * Exit a parse tree produced by the {@code decimalLiteral} + * labeled alternative in {@link PromqlBaseParser#number}. + * @param ctx the parse tree + */ + void exitDecimalLiteral(PromqlBaseParser.DecimalLiteralContext ctx); + /** + * Enter a parse tree produced by the {@code integerLiteral} + * labeled alternative in {@link PromqlBaseParser#number}. + * @param ctx the parse tree + */ + void enterIntegerLiteral(PromqlBaseParser.IntegerLiteralContext ctx); + /** + * Exit a parse tree produced by the {@code integerLiteral} + * labeled alternative in {@link PromqlBaseParser#number}. + * @param ctx the parse tree + */ + void exitIntegerLiteral(PromqlBaseParser.IntegerLiteralContext ctx); + /** + * Enter a parse tree produced by the {@code hexLiteral} + * labeled alternative in {@link PromqlBaseParser#number}. + * @param ctx the parse tree + */ + void enterHexLiteral(PromqlBaseParser.HexLiteralContext ctx); + /** + * Exit a parse tree produced by the {@code hexLiteral} + * labeled alternative in {@link PromqlBaseParser#number}. + * @param ctx the parse tree + */ + void exitHexLiteral(PromqlBaseParser.HexLiteralContext ctx); + /** + * Enter a parse tree produced by {@link PromqlBaseParser#string}. + * @param ctx the parse tree + */ + void enterString(PromqlBaseParser.StringContext ctx); + /** + * Exit a parse tree produced by {@link PromqlBaseParser#string}. + * @param ctx the parse tree + */ + void exitString(PromqlBaseParser.StringContext ctx); + /** + * Enter a parse tree produced by {@link PromqlBaseParser#timeValue}. + * @param ctx the parse tree + */ + void enterTimeValue(PromqlBaseParser.TimeValueContext ctx); + /** + * Exit a parse tree produced by {@link PromqlBaseParser#timeValue}. + * @param ctx the parse tree + */ + void exitTimeValue(PromqlBaseParser.TimeValueContext ctx); + /** + * Enter a parse tree produced by {@link PromqlBaseParser#nonReserved}. + * @param ctx the parse tree + */ + void enterNonReserved(PromqlBaseParser.NonReservedContext ctx); + /** + * Exit a parse tree produced by {@link PromqlBaseParser#nonReserved}. + * @param ctx the parse tree + */ + void exitNonReserved(PromqlBaseParser.NonReservedContext ctx); +} diff --git a/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/parser/PromqlBaseParserVisitor.java b/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/parser/PromqlBaseParserVisitor.java new file mode 100644 index 0000000000000..8f7be8a76263c --- /dev/null +++ b/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/parser/PromqlBaseParserVisitor.java @@ -0,0 +1,209 @@ +// ANTLR GENERATED CODE: DO NOT EDIT +package org.elasticsearch.xpack.esql.parser; + +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import org.antlr.v4.runtime.tree.ParseTreeVisitor; + +/** + * This interface defines a complete generic visitor for a parse tree produced + * by {@link PromqlBaseParser}. + * + * @param The return type of the visit operation. Use {@link Void} for + * operations with no return type. + */ +public interface PromqlBaseParserVisitor extends ParseTreeVisitor { + /** + * Visit a parse tree produced by {@link PromqlBaseParser#singleStatement}. + * @param ctx the parse tree + * @return the visitor result + */ + T visitSingleStatement(PromqlBaseParser.SingleStatementContext ctx); + /** + * Visit a parse tree produced by the {@code valueExpression} + * labeled alternative in {@link PromqlBaseParser#expression}. + * @param ctx the parse tree + * @return the visitor result + */ + T visitValueExpression(PromqlBaseParser.ValueExpressionContext ctx); + /** + * Visit a parse tree produced by the {@code subquery} + * labeled alternative in {@link PromqlBaseParser#expression}. + * @param ctx the parse tree + * @return the visitor result + */ + T visitSubquery(PromqlBaseParser.SubqueryContext ctx); + /** + * Visit a parse tree produced by the {@code parenthesized} + * labeled alternative in {@link PromqlBaseParser#expression}. + * @param ctx the parse tree + * @return the visitor result + */ + T visitParenthesized(PromqlBaseParser.ParenthesizedContext ctx); + /** + * Visit a parse tree produced by the {@code arithmeticBinary} + * labeled alternative in {@link PromqlBaseParser#expression}. + * @param ctx the parse tree + * @return the visitor result + */ + T visitArithmeticBinary(PromqlBaseParser.ArithmeticBinaryContext ctx); + /** + * Visit a parse tree produced by the {@code arithmeticUnary} + * labeled alternative in {@link PromqlBaseParser#expression}. + * @param ctx the parse tree + * @return the visitor result + */ + T visitArithmeticUnary(PromqlBaseParser.ArithmeticUnaryContext ctx); + /** + * Visit a parse tree produced by {@link PromqlBaseParser#subqueryResolution}. + * @param ctx the parse tree + * @return the visitor result + */ + T visitSubqueryResolution(PromqlBaseParser.SubqueryResolutionContext ctx); + /** + * Visit a parse tree produced by {@link PromqlBaseParser#value}. + * @param ctx the parse tree + * @return the visitor result + */ + T visitValue(PromqlBaseParser.ValueContext ctx); + /** + * Visit a parse tree produced by {@link PromqlBaseParser#function}. + * @param ctx the parse tree + * @return the visitor result + */ + T visitFunction(PromqlBaseParser.FunctionContext ctx); + /** + * Visit a parse tree produced by {@link PromqlBaseParser#functionParams}. + * @param ctx the parse tree + * @return the visitor result + */ + T visitFunctionParams(PromqlBaseParser.FunctionParamsContext ctx); + /** + * Visit a parse tree produced by {@link PromqlBaseParser#grouping}. + * @param ctx the parse tree + * @return the visitor result + */ + T visitGrouping(PromqlBaseParser.GroupingContext ctx); + /** + * Visit a parse tree produced by {@link PromqlBaseParser#selector}. + * @param ctx the parse tree + * @return the visitor result + */ + T visitSelector(PromqlBaseParser.SelectorContext ctx); + /** + * Visit a parse tree produced by {@link PromqlBaseParser#seriesMatcher}. + * @param ctx the parse tree + * @return the visitor result + */ + T visitSeriesMatcher(PromqlBaseParser.SeriesMatcherContext ctx); + /** + * Visit a parse tree produced by {@link PromqlBaseParser#modifier}. + * @param ctx the parse tree + * @return the visitor result + */ + T visitModifier(PromqlBaseParser.ModifierContext ctx); + /** + * Visit a parse tree produced by {@link PromqlBaseParser#labelList}. + * @param ctx the parse tree + * @return the visitor result + */ + T visitLabelList(PromqlBaseParser.LabelListContext ctx); + /** + * Visit a parse tree produced by {@link PromqlBaseParser#labels}. + * @param ctx the parse tree + * @return the visitor result + */ + T visitLabels(PromqlBaseParser.LabelsContext ctx); + /** + * Visit a parse tree produced by {@link PromqlBaseParser#label}. + * @param ctx the parse tree + * @return the visitor result + */ + T visitLabel(PromqlBaseParser.LabelContext ctx); + /** + * Visit a parse tree produced by {@link PromqlBaseParser#labelName}. + * @param ctx the parse tree + * @return the visitor result + */ + T visitLabelName(PromqlBaseParser.LabelNameContext ctx); + /** + * Visit a parse tree produced by {@link PromqlBaseParser#identifier}. + * @param ctx the parse tree + * @return the visitor result + */ + T visitIdentifier(PromqlBaseParser.IdentifierContext ctx); + /** + * Visit a parse tree produced by {@link PromqlBaseParser#evaluation}. + * @param ctx the parse tree + * @return the visitor result + */ + T visitEvaluation(PromqlBaseParser.EvaluationContext ctx); + /** + * Visit a parse tree produced by {@link PromqlBaseParser#offset}. + * @param ctx the parse tree + * @return the visitor result + */ + T visitOffset(PromqlBaseParser.OffsetContext ctx); + /** + * Visit a parse tree produced by {@link PromqlBaseParser#duration}. + * @param ctx the parse tree + * @return the visitor result + */ + T visitDuration(PromqlBaseParser.DurationContext ctx); + /** + * Visit a parse tree produced by {@link PromqlBaseParser#at}. + * @param ctx the parse tree + * @return the visitor result + */ + T visitAt(PromqlBaseParser.AtContext ctx); + /** + * Visit a parse tree produced by {@link PromqlBaseParser#constant}. + * @param ctx the parse tree + * @return the visitor result + */ + T visitConstant(PromqlBaseParser.ConstantContext ctx); + /** + * Visit a parse tree produced by the {@code decimalLiteral} + * labeled alternative in {@link PromqlBaseParser#number}. + * @param ctx the parse tree + * @return the visitor result + */ + T visitDecimalLiteral(PromqlBaseParser.DecimalLiteralContext ctx); + /** + * Visit a parse tree produced by the {@code integerLiteral} + * labeled alternative in {@link PromqlBaseParser#number}. + * @param ctx the parse tree + * @return the visitor result + */ + T visitIntegerLiteral(PromqlBaseParser.IntegerLiteralContext ctx); + /** + * Visit a parse tree produced by the {@code hexLiteral} + * labeled alternative in {@link PromqlBaseParser#number}. + * @param ctx the parse tree + * @return the visitor result + */ + T visitHexLiteral(PromqlBaseParser.HexLiteralContext ctx); + /** + * Visit a parse tree produced by {@link PromqlBaseParser#string}. + * @param ctx the parse tree + * @return the visitor result + */ + T visitString(PromqlBaseParser.StringContext ctx); + /** + * Visit a parse tree produced by {@link PromqlBaseParser#timeValue}. + * @param ctx the parse tree + * @return the visitor result + */ + T visitTimeValue(PromqlBaseParser.TimeValueContext ctx); + /** + * Visit a parse tree produced by {@link PromqlBaseParser#nonReserved}. + * @param ctx the parse tree + * @return the visitor result + */ + T visitNonReserved(PromqlBaseParser.NonReservedContext ctx); +} diff --git a/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/parser/PromqlParser.java b/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/parser/PromqlParser.java new file mode 100644 index 0000000000000..1ea81cc410db0 --- /dev/null +++ b/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/parser/PromqlParser.java @@ -0,0 +1,150 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +package org.elasticsearch.xpack.esql.parser; + +import org.antlr.v4.runtime.BaseErrorListener; +import org.antlr.v4.runtime.CharStreams; +import org.antlr.v4.runtime.CommonTokenStream; +import org.antlr.v4.runtime.DiagnosticErrorListener; +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; +import org.antlr.v4.runtime.atn.ATNConfigSet; +import org.antlr.v4.runtime.atn.PredictionMode; +import org.antlr.v4.runtime.dfa.DFA; +import org.elasticsearch.logging.LogManager; +import org.elasticsearch.logging.Logger; +import org.elasticsearch.xpack.esql.core.expression.Literal; +import org.elasticsearch.xpack.esql.parser.promql.PromqlAstBuilder; +import org.elasticsearch.xpack.esql.plan.logical.LogicalPlan; + +import java.util.BitSet; +import java.util.EmptyStackException; +import java.util.Locale; +import java.util.function.BiFunction; +import java.util.function.Function; + +import static java.lang.String.format; + +public class PromqlParser { + + private static final Logger log = LogManager.getLogger(PromqlParser.class); + + private final boolean DEBUG = false; + + /** + * Parses an PromQL expression into execution plan + */ + public LogicalPlan createStatement(String query) { + return createStatement(query, null, null, 0, 0); + } + + public LogicalPlan createStatement(String query, Literal start, Literal end, int startLine, int startColumn) { + if (log.isDebugEnabled()) { + log.debug("Parsing as expression: {}", query); + } + + return invokeParser(query, start, end, startLine, startColumn, PromqlBaseParser::singleStatement, PromqlAstBuilder::plan); + } + + private T invokeParser( + String query, + Literal start, + Literal end, + int startLine, + int startColumn, + Function parseFunction, + BiFunction visitor + ) { + try { + PromqlBaseLexer lexer = new PromqlBaseLexer(CharStreams.fromString(query)); + + lexer.removeErrorListeners(); + lexer.addErrorListener(ERROR_LISTENER); + + CommonTokenStream tokenStream = new CommonTokenStream(lexer); + PromqlBaseParser parser = new PromqlBaseParser(tokenStream); + + parser.removeErrorListeners(); + parser.addErrorListener(ERROR_LISTENER); + + parser.getInterpreter().setPredictionMode(PredictionMode.SLL); + + if (DEBUG) { + debug(parser); + tokenStream.fill(); + + for (Token t : tokenStream.getTokens()) { + String symbolicName = PromqlBaseLexer.VOCABULARY.getSymbolicName(t.getType()); + String literalName = PromqlBaseLexer.VOCABULARY.getLiteralName(t.getType()); + log.info(format(Locale.ROOT, " %-15s '%s'", symbolicName == null ? literalName : symbolicName, t.getText())); + } + } + + ParserRuleContext tree = parseFunction.apply(parser); + + if (log.isTraceEnabled()) { + log.trace("Parse tree: {}", tree.toStringTree()); + } + return visitor.apply(new PromqlAstBuilder(start, end, startLine, startColumn), tree); + } catch (StackOverflowError e) { + throw new ParsingException( + "PromQL statement is too large, causing stack overflow when generating the parsing tree: [{}]", + query + ); + } catch (EmptyStackException ese) { + throw new ParsingException("Invalid query [{}]", query); + } + } + + private static void debug(PromqlBaseParser parser) { + + // when debugging, use the exact prediction mode (needed for diagnostics as well) + parser.getInterpreter().setPredictionMode(PredictionMode.LL_EXACT_AMBIG_DETECTION); + + parser.addParseListener(parser.new TraceListener()); + + parser.addErrorListener(new DiagnosticErrorListener(false) { + @Override + public void reportAttemptingFullContext( + Parser recognizer, + DFA dfa, + int startIndex, + int stopIndex, + BitSet conflictingAlts, + ATNConfigSet configs + ) {} + + @Override + public void reportContextSensitivity( + Parser recognizer, + DFA dfa, + int startIndex, + int stopIndex, + int prediction, + ATNConfigSet configs + ) {} + }); + } + + private static final BaseErrorListener ERROR_LISTENER = new BaseErrorListener() { + @Override + public void syntaxError( + Recognizer recognizer, + Object offendingSymbol, + int line, + int charPositionInLine, + String message, + RecognitionException e + ) { + throw new ParsingException(message, e, line, charPositionInLine); + } + }; +} diff --git a/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/parser/promql/AbstractPromqlBuilder.java b/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/parser/promql/AbstractPromqlBuilder.java new file mode 100644 index 0000000000000..6e0c2ac04cff5 --- /dev/null +++ b/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/parser/promql/AbstractPromqlBuilder.java @@ -0,0 +1,73 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +package org.elasticsearch.xpack.esql.parser.promql; + +import org.antlr.v4.runtime.ParserRuleContext; +import org.antlr.v4.runtime.Token; +import org.antlr.v4.runtime.tree.ParseTree; +import org.antlr.v4.runtime.tree.TerminalNode; +import org.elasticsearch.xpack.esql.core.tree.Source; +import org.elasticsearch.xpack.esql.parser.ParserUtils; +import org.elasticsearch.xpack.esql.parser.ParsingException; +import org.elasticsearch.xpack.esql.parser.PromqlBaseParserBaseVisitor; + +class AbstractPromqlBuilder extends PromqlBaseParserBaseVisitor { + private final int startLine, startColumn; + + AbstractPromqlBuilder(int startLine, int startColumn) { + this.startLine = startLine; + this.startColumn = startColumn; + } + + @Override + public Object visit(ParseTree tree) { + return ParserUtils.visit(super::visit, tree); + } + + /** + * Extracts the actual unescaped string (literal) value of a terminal node. + */ + String string(TerminalNode node) { + return node == null ? null : unquote(source(node)); + } + + static String unquoteString(Source source) { + return source == null ? null : unquote(source); + } + + static String unquote(Source source) { + return PromqlParserUtils.unquote(source); + } + + @Override + public Object visitTerminal(TerminalNode node) { + Source source = source(node); + throw new ParsingException(source, "Does not know how to handle {}", source.text()); + } + + protected Source source(TerminalNode terminalNode) { + return PromqlParserUtils.adjustSource(ParserUtils.source(terminalNode), startLine, startColumn); + } + + protected Source source(ParserRuleContext parserRuleContext) { + return PromqlParserUtils.adjustSource(ParserUtils.source(parserRuleContext), startLine, startColumn); + } + + protected Source source(ParseTree parseTree) { + return PromqlParserUtils.adjustSource(ParserUtils.source(parseTree), startLine, startColumn); + } + + protected Source source(Token token) { + return PromqlParserUtils.adjustSource(ParserUtils.source(token), startLine, startColumn); + } + + protected Source source(Token start, Token stop) { + return PromqlParserUtils.adjustSource(ParserUtils.source(start, stop), startLine, startColumn); + } + +} diff --git a/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/parser/promql/PromqlAstBuilder.java b/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/parser/promql/PromqlAstBuilder.java new file mode 100644 index 0000000000000..4c28fcf47e9d7 --- /dev/null +++ b/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/parser/promql/PromqlAstBuilder.java @@ -0,0 +1,40 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +package org.elasticsearch.xpack.esql.parser.promql; + +import org.antlr.v4.runtime.tree.ParseTree; +import org.elasticsearch.xpack.esql.core.expression.Literal; +import org.elasticsearch.xpack.esql.parser.ParsingException; +import org.elasticsearch.xpack.esql.plan.logical.LogicalPlan; + +public class PromqlAstBuilder extends PromqlLogicalPlanBuilder { + + public static final int MAX_EXPRESSION_DEPTH = 200; + + private int expressionDepth = 0; + + public PromqlAstBuilder(Literal start, Literal end, int startLine, int startColumn) { + super(start, end, startLine, startColumn); + } + + public LogicalPlan plan(ParseTree ctx) { + expressionDepth++; + if (expressionDepth > MAX_EXPRESSION_DEPTH) { + throw new ParsingException( + "PromQL statement exceeded the maximum expression depth allowed ({}): [{}]", + MAX_EXPRESSION_DEPTH, + ctx.getParent().getText() + ); + } + try { + return super.plan(ctx); + } finally { + expressionDepth--; + } + } +} diff --git a/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/parser/promql/PromqlExpressionBuilder.java b/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/parser/promql/PromqlExpressionBuilder.java new file mode 100644 index 0000000000000..9f548b686ce2d --- /dev/null +++ b/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/parser/promql/PromqlExpressionBuilder.java @@ -0,0 +1,333 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +package org.elasticsearch.xpack.esql.parser.promql; + +import org.antlr.v4.runtime.ParserRuleContext; +import org.antlr.v4.runtime.tree.ParseTree; +import org.elasticsearch.xpack.esql.core.InvalidArgumentException; +import org.elasticsearch.xpack.esql.core.QlIllegalArgumentException; +import org.elasticsearch.xpack.esql.core.expression.Expression; +import org.elasticsearch.xpack.esql.core.expression.FoldContext; +import org.elasticsearch.xpack.esql.core.expression.Literal; +import org.elasticsearch.xpack.esql.core.tree.Source; +import org.elasticsearch.xpack.esql.core.type.DataType; +import org.elasticsearch.xpack.esql.core.util.StringUtils; +import org.elasticsearch.xpack.esql.parser.ParsingException; +import org.elasticsearch.xpack.esql.parser.PromqlBaseParser.HexLiteralContext; +import org.elasticsearch.xpack.esql.parser.PromqlBaseParser.IntegerLiteralContext; +import org.elasticsearch.xpack.esql.parser.PromqlBaseParser.LabelListContext; +import org.elasticsearch.xpack.esql.parser.PromqlBaseParser.LabelNameContext; +import org.elasticsearch.xpack.esql.parser.PromqlBaseParser.StringContext; +import org.elasticsearch.xpack.esql.plan.logical.LogicalPlan; +import org.elasticsearch.xpack.esql.plan.logical.promql.selector.Evaluation; +import org.elasticsearch.xpack.esql.plan.logical.promql.selector.LiteralSelector; + +import java.time.Duration; +import java.time.Instant; +import java.util.List; +import java.util.Locale; + +import static java.util.Collections.emptyList; +import static org.elasticsearch.xpack.esql.parser.ParserUtils.typedParsing; +import static org.elasticsearch.xpack.esql.parser.ParserUtils.visitList; +import static org.elasticsearch.xpack.esql.parser.PromqlBaseParser.AtContext; +import static org.elasticsearch.xpack.esql.parser.PromqlBaseParser.DecimalLiteralContext; +import static org.elasticsearch.xpack.esql.parser.PromqlBaseParser.DurationContext; +import static org.elasticsearch.xpack.esql.parser.PromqlBaseParser.EvaluationContext; +import static org.elasticsearch.xpack.esql.parser.PromqlBaseParser.OffsetContext; +import static org.elasticsearch.xpack.esql.parser.PromqlBaseParser.TimeValueContext; + +class PromqlExpressionBuilder extends PromqlIdentifierBuilder { + + /** + * Prometheus duration limits based on Go time.Duration (int64 nanoseconds). + * Maximum: ~292.27 years (2^63 - 1 nanoseconds = 9,223,372,036 seconds) + * Minimum: ~-292.27 years (-(2^63) nanoseconds = -9,223,372,037 seconds) + */ + private static final long MAX_DURATION_SECONDS = 9223372036L; + private static final long MIN_DURATION_SECONDS = -9223372037L; + + private final Literal start, end; + + PromqlExpressionBuilder(Literal start, Literal end, int startLine, int startColumn) { + super(startLine, startColumn); + this.start = start; + this.end = end; + } + + protected Expression expression(ParseTree ctx) { + return typedParsing(this, ctx, Expression.class); + } + + protected List expressions(List contexts) { + return visitList(this, contexts, Expression.class); + } + + /** + * Validates that a duration is within Prometheus's acceptable range (~292 years). + * Prometheus uses Go's time.Duration internally, which is an int64 of nanoseconds. + * + * @param source the source location for error reporting + * @param duration the duration to validate + * @throws ParsingException if the duration is out of range + */ + private static void validateDurationRange(Source source, Duration duration) { + long seconds = duration.getSeconds(); + if (seconds > MAX_DURATION_SECONDS || seconds < MIN_DURATION_SECONDS) { + throw new ParsingException(source, "Duration out of range"); + } + } + + @Override + public List visitLabelList(LabelListContext ctx) { + return ctx != null ? visitList(this, ctx.labelName(), String.class) : emptyList(); + } + + @Override + public String visitLabelName(LabelNameContext ctx) { + if (ctx.identifier() != null) { + return visitIdentifier(ctx.identifier()); + } + if (ctx.STRING() != null) { + return string(ctx.STRING()); + } + if (ctx.number() != null) { + Literal l = typedParsing(this, ctx.number(), Literal.class); + return String.valueOf(l.value()); + } + throw new ParsingException(source(ctx), "Expected label name, got [{}]", source(ctx).text()); + } + + @Override + public Evaluation visitEvaluation(EvaluationContext ctx) { + if (ctx == null) { + return Evaluation.NONE; + } + + Literal offset = Literal.NULL; + boolean negativeOffset = false; + Literal at = Literal.NULL; + + AtContext atCtx = ctx.at(); + if (atCtx != null) { + Source source = source(atCtx); + if (atCtx.AT_START() != null) { + if (start == null) { + throw new ParsingException(source, "@ start() can only be used if parameter [start] or [time] is provided"); + } + at = start; + } else if (atCtx.AT_END() != null) { + if (end == null) { + throw new ParsingException(source, "@ end() can only be used if parameter [end] or [time] is provided"); + } + at = end; + } else { + Duration timeValue = visitTimeValue(atCtx.timeValue()); + // the value can have a floating point + long seconds = timeValue.getSeconds(); + int nanos = timeValue.getNano(); + + if (atCtx.MINUS() != null) { + if (seconds == Long.MIN_VALUE) { + throw new ParsingException(source, "Value [{}] cannot be negated due to underflow", seconds); + } + seconds = -seconds; + nanos = -nanos; + } + at = Literal.dateTime(source, Instant.ofEpochSecond(seconds, nanos)); + } + } + OffsetContext offsetContext = ctx.offset(); + if (offsetContext != null) { + offset = visitDuration(offsetContext.duration()); + negativeOffset = offsetContext.MINUS() != null; + } + return new Evaluation(offset, negativeOffset, at); + } + + @Override + public Literal visitDuration(DurationContext ctx) { + if (ctx == null) { + return Literal.NULL; + } + Object o = visit(ctx.expression()); + + // unwrap expressions to get the underlying value + o = switch (o) { + case LogicalPlan plan -> { + // Scalar arithmetic has been folded and wrapped in LiteralSelector + if (plan instanceof LiteralSelector literalSelector) { + yield literalSelector.literal().value(); + } + throw new ParsingException(source(ctx), "Expected duration or numeric value, got [{}]", plan.getClass().getSimpleName()); + } + case Literal l -> l.value(); + case Expression e -> { + // Fallback for Expression (shouldn't happen with new logic) + if (e.foldable()) { + yield e.fold(FoldContext.small()); + } + // otherwise bail out + throw new ParsingException(source(ctx), "Expected a duration, got [{}]", source(ctx).text()); + } + default -> o; + }; + + Duration d = switch (o) { + case Duration duration -> duration; + // Handle numeric scalars interpreted as seconds + case Number num -> { + long seconds = num.longValue(); + if (seconds <= 0) { + throw new ParsingException(source(ctx), "Duration must be positive, got [{}]s", seconds); + } + Duration duration = Duration.ofSeconds(seconds); + // Validate the resulting duration is within acceptable range + validateDurationRange(source(ctx), duration); + yield duration; + } + default -> throw new ParsingException(source(ctx), "Expected a duration, got [{}]", source(ctx).text()); + }; + return Literal.timeDuration(source(ctx), d); + } + + @Override + public Duration visitTimeValue(TimeValueContext ctx) { + if (ctx.number() != null) { + var literal = typedParsing(this, ctx.number(), Literal.class); + Number number = (Number) literal.value(); + if (number instanceof Double d) { + double v = d.doubleValue(); + Source source = literal.source(); + if (Double.isFinite(v) == false) { + throw new ParsingException(source, "Invalid timestamp [{}]", v); + } + + // Check if the value exceeds duration range before conversion + if (v > MAX_DURATION_SECONDS || v < MIN_DURATION_SECONDS) { + throw new ParsingException(source, "Duration out of range"); + } + + // Convert to milliseconds (matching Prometheus behavior) + double millisDouble = v * 1000.0; + if (millisDouble >= Long.MAX_VALUE || millisDouble <= Long.MIN_VALUE) { + throw new ParsingException(source, "Timestamp out of bounds [{}]", v); + } + + // Round to nearest millisecond, supporting sub-millisecond input + long millis = Math.round(millisDouble); + return Duration.ofMillis(millis); + } + + // Handle integer/long values + long longValue = number.longValue(); + if (longValue > MAX_DURATION_SECONDS || longValue < MIN_DURATION_SECONDS) { + throw new ParsingException(literal.source(), "Duration out of range"); + } + return Duration.ofSeconds(longValue); + } + String timeString = null; + Source source; + var timeCtx = ctx.TIME_VALUE_WITH_COLON(); + if (timeCtx != null) { + // drop leading : + timeString = timeCtx.getText().substring(1).trim(); + } else { + timeCtx = ctx.TIME_VALUE(); + timeString = timeCtx.getText(); + } + source = source(timeCtx); + + return parseTimeValue(source, timeString); + } + + @Override + public Literal visitDecimalLiteral(DecimalLiteralContext ctx) { + Source source = source(ctx); + String text = ctx.getText(); + + try { + double value; + String s = text.toLowerCase(Locale.ROOT); + if ("inf".equals(s)) { + value = Double.POSITIVE_INFINITY; + } else if ("nan".equals(s)) { + value = Double.NaN; + } else { + value = Double.parseDouble(text); + } + return Literal.fromDouble(source, value); + } catch (NumberFormatException ne) { + throw new ParsingException(source, "Cannot parse number [{}]", text); + } + } + + @Override + public Literal visitIntegerLiteral(IntegerLiteralContext ctx) { + Source source = source(ctx); + String text = ctx.getText(); + + Number value; + + try { + value = StringUtils.parseIntegral(text); + } catch (InvalidArgumentException siae) { + // if it's too large, then quietly try to parse as a float instead + try { + // use DataTypes.DOUBLE for precise type + return Literal.fromDouble(source, StringUtils.parseDouble(text)); + } catch (QlIllegalArgumentException ignored) {} + + throw new ParsingException(source, siae.getMessage()); + } + + // use type instead for precise type + return new Literal(source, value, value instanceof Integer ? DataType.INTEGER : DataType.LONG); + } + + @Override + public Literal visitHexLiteral(HexLiteralContext ctx) { + Source source = source(ctx); + String text = ctx.getText(); + + DataType type = DataType.LONG; + Object val; + + // remove leading 0x + long value; + try { + value = Long.parseLong(text.substring(2), 16); + } catch (NumberFormatException e) { + throw new ParsingException(source, "Cannot parse hexadecimal expression [{}]", text); + } + + // try to downsize to int + if ((int) value == value) { + type = DataType.INTEGER; + val = (int) value; + } else { + val = value; + } + return new Literal(source, val, type); + } + + @Override + public Literal visitString(StringContext ctx) { + Source source = source(ctx); + return Literal.keyword(source, string(ctx.STRING())); + } + + private static Duration parseTimeValue(Source source, String text) { + Duration duration = PromqlParserUtils.parseDuration(source, text); + if (duration.isZero()) { + throw new ParsingException(source, "Invalid time duration [{}], zero value specified", text); + } + validateDurationRange(source, duration); + return duration; + } +} diff --git a/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/parser/promql/PromqlFoldingUtils.java b/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/parser/promql/PromqlFoldingUtils.java new file mode 100644 index 0000000000000..067036a6f994b --- /dev/null +++ b/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/parser/promql/PromqlFoldingUtils.java @@ -0,0 +1,194 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +package org.elasticsearch.xpack.esql.parser.promql; + +import org.elasticsearch.xpack.esql.core.expression.predicate.operator.arithmetic.Arithmetics; +import org.elasticsearch.xpack.esql.core.tree.Source; +import org.elasticsearch.xpack.esql.parser.ParsingException; +import org.elasticsearch.xpack.esql.plan.logical.promql.operator.arithmetic.VectorBinaryArithmetic.ArithmeticOp; +import org.elasticsearch.xpack.esql.plan.logical.promql.operator.comparison.VectorBinaryComparison.ComparisonOp; + +import java.time.Duration; + +/** + * Utility class for evaluating scalar arithmetic operations at parse time. + * Handles operations between: + * - Numbers (delegates to Arithmetics) + * - Durations and numbers (converts to seconds, computes, converts back) + * - Durations and durations (only for ADD/SUB) + */ +public class PromqlFoldingUtils { + + /** + * Evaluate arithmetic operation between two scalar values at parse time. + * + * @param source Source location for error messages + * @param left Left operand (Number or Duration) + * @param right Right operand (Number or Duration) + * @param operation The arithmetic operation + * @return Result value (Number or Duration) + */ + public static Object evaluate(Source source, Object left, Object right, ArithmeticOp operation) { + // Dispatch to appropriate handler based on operand types + if (left instanceof Duration leftDuration) { + if (right instanceof Duration rightDuration) { + return arithmetics(source, leftDuration, rightDuration, operation); + } else if (right instanceof Number rightNumber) { + return arithmetics(source, leftDuration, rightNumber, operation); + } + } else if (left instanceof Number leftNumber) { + if (right instanceof Duration rightDuration) { + return arithmetics(source, leftNumber, rightDuration, operation); + } else if (right instanceof Number rightNumber) { + return numericArithmetics(source, leftNumber, rightNumber, operation); + } + } + + throw new ParsingException( + source, + "Cannot perform arithmetic between [{}] and [{}]", + left.getClass().getSimpleName(), + right.getClass().getSimpleName() + ); + } + + /** + * Duration op Duration (only ADD and SUB supported). + */ + private static Duration arithmetics(Source source, Duration left, Duration right, ArithmeticOp op) { + Duration result = switch (op) { + case ADD -> left.plus(right); + case SUB -> left.minus(right); + default -> throw new ParsingException(source, "Operation [{}] not supported between two durations", op); + }; + + return result; + } + + /** + * Duration op Number. + * For ADD/SUB: Number interpreted as seconds (PromQL convention). + * For MUL/DIV/MOD/POW: Number is a dimensionless scalar. + */ + private static Duration arithmetics(Source source, Duration duration, Number scalar, ArithmeticOp op) { + long durationSeconds = duration.getSeconds(); + long scalarValue = scalar.longValue(); + + long resultSeconds = switch (op) { + case ADD -> { + yield Math.addExact(durationSeconds, scalarValue); + } + case SUB -> { + yield Math.subtractExact(durationSeconds, scalarValue); + } + case MUL -> { + yield Math.round(durationSeconds * scalar.doubleValue()); + } + case DIV -> { + if (scalarValue == 0) { + throw new ParsingException(source, "Cannot divide duration by zero"); + } + yield Math.round(durationSeconds / scalar.doubleValue()); + } + case MOD -> { + // Modulo operation + if (scalarValue == 0) { + throw new ParsingException(source, "Cannot compute modulo with zero"); + } + yield Math.floorMod(durationSeconds, scalarValue); + } + case POW -> { + // Power operation (duration ^ scalar) + yield Math.round(Math.pow(durationSeconds, scalarValue)); + } + }; + + return Duration.ofSeconds(resultSeconds); + } + + private static Duration arithmetics(Source source, Number scalar, Duration duration, ArithmeticOp op) { + return switch (op) { + case ADD -> arithmetics(source, duration, scalar, ArithmeticOp.ADD); + case SUB -> arithmetics(source, Duration.ofSeconds(scalar.longValue()), duration, ArithmeticOp.SUB); + case MUL -> arithmetics(source, duration, scalar, ArithmeticOp.MUL); + default -> throw new ParsingException(source, "Operation [{}] not supported with scalar on left and duration on right", op); + }; + } + + /** + * Number op Number (pure numeric operations). + * Delegates to Arithmetics for consistent numeric handling. + */ + private static Number numericArithmetics(Source source, Number left, Number right, ArithmeticOp op) { + try { + return switch (op) { + case ADD -> Arithmetics.add(left, right); + case SUB -> Arithmetics.sub(left, right); + case MUL -> Arithmetics.mul(left, right); + case DIV -> Arithmetics.div(left, right); + case MOD -> Arithmetics.mod(left, right); + case POW -> { + // Power not in Arithmetics, compute manually + double result = Math.pow(left.doubleValue(), right.doubleValue()); + // Try to preserve integer types when possible + if (Double.isFinite(result)) { + if (result == (long) result) { + if (result >= Integer.MIN_VALUE && result <= Integer.MAX_VALUE) { + yield (int) result; + } + yield (long) result; + } + } + yield result; + } + }; + } catch (ArithmeticException e) { + throw new ParsingException(source, "Arithmetic error: {}", e.getMessage()); + } + } + + /** + * Evaluate comparison operation between two numbers at parse time. + * + * @param left Left operand (Number) + * @param right Right operand (Number) + * @param operation The comparison operation + * @return true if comparison holds, false otherwise + */ + public static boolean evaluate(Source source, Object left, Object right, ComparisonOp operation) { + if (left instanceof Number ln && right instanceof Number rn) { + // Get double values once, reuse for comparison - avoids extra allocation + double l = ln.doubleValue(); + double r = rn.doubleValue(); + + return switch (operation) { + case EQ -> l == r; + case NEQ -> l != r; + case GT -> l > r; + case GTE -> l >= r; + case LT -> l < r; + case LTE -> l <= r; + }; + } + throw new ParsingException( + source, + "Cannot perform comparison between [{}] and [{}]", + left.getClass().getSimpleName(), + right.getClass().getSimpleName() + ); + } + + /** + * Validate that duration is positive (PromQL requirement). + */ + private static void validatePositiveDuration(Source source, Duration duration) { + if (duration.isNegative() || duration.isZero()) { + throw new ParsingException(source, "Duration must be positive, got [{}]", duration); + } + } +} diff --git a/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/parser/promql/PromqlIdentifierBuilder.java b/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/parser/promql/PromqlIdentifierBuilder.java new file mode 100644 index 0000000000000..bc051ca765ef7 --- /dev/null +++ b/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/parser/promql/PromqlIdentifierBuilder.java @@ -0,0 +1,22 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +package org.elasticsearch.xpack.esql.parser.promql; + +import static org.elasticsearch.xpack.esql.parser.PromqlBaseParser.IdentifierContext; + +abstract class PromqlIdentifierBuilder extends AbstractPromqlBuilder { + + PromqlIdentifierBuilder(int startLine, int startColumn) { + super(startLine, startColumn); + } + + @Override + public String visitIdentifier(IdentifierContext ctx) { + return ctx == null ? null : ctx.getText(); + } +} diff --git a/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/parser/promql/PromqlLogicalPlanBuilder.java b/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/parser/promql/PromqlLogicalPlanBuilder.java new file mode 100644 index 0000000000000..5658ac1f54b82 --- /dev/null +++ b/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/parser/promql/PromqlLogicalPlanBuilder.java @@ -0,0 +1,572 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +package org.elasticsearch.xpack.esql.parser.promql; + +import org.antlr.v4.runtime.ParserRuleContext; +import org.antlr.v4.runtime.Token; +import org.antlr.v4.runtime.tree.ParseTree; +import org.elasticsearch.xpack.esql.core.expression.Expression; +import org.elasticsearch.xpack.esql.core.expression.FoldContext; +import org.elasticsearch.xpack.esql.core.expression.Literal; +import org.elasticsearch.xpack.esql.core.expression.UnresolvedAttribute; +import org.elasticsearch.xpack.esql.core.expression.predicate.operator.arithmetic.Arithmetics; +import org.elasticsearch.xpack.esql.core.tree.Node; +import org.elasticsearch.xpack.esql.core.tree.Source; +import org.elasticsearch.xpack.esql.core.type.DataType; +import org.elasticsearch.xpack.esql.expression.promql.function.PromqlFunctionRegistry; +import org.elasticsearch.xpack.esql.expression.promql.subquery.Subquery; +import org.elasticsearch.xpack.esql.parser.ParsingException; +import org.elasticsearch.xpack.esql.parser.PromqlBaseParser; +import org.elasticsearch.xpack.esql.plan.logical.LogicalPlan; +import org.elasticsearch.xpack.esql.plan.logical.promql.AcrossSeriesAggregate; +import org.elasticsearch.xpack.esql.plan.logical.promql.WithinSeriesAggregate; +import org.elasticsearch.xpack.esql.plan.logical.promql.operator.VectorBinaryOperator.BinaryOp; +import org.elasticsearch.xpack.esql.plan.logical.promql.operator.VectorMatch; +import org.elasticsearch.xpack.esql.plan.logical.promql.operator.arithmetic.VectorBinaryArithmetic; +import org.elasticsearch.xpack.esql.plan.logical.promql.operator.arithmetic.VectorBinaryArithmetic.ArithmeticOp; +import org.elasticsearch.xpack.esql.plan.logical.promql.operator.comparison.VectorBinaryComparison; +import org.elasticsearch.xpack.esql.plan.logical.promql.operator.comparison.VectorBinaryComparison.ComparisonOp; +import org.elasticsearch.xpack.esql.plan.logical.promql.operator.set.VectorBinarySet; +import org.elasticsearch.xpack.esql.plan.logical.promql.selector.Evaluation; +import org.elasticsearch.xpack.esql.plan.logical.promql.selector.InstantSelector; +import org.elasticsearch.xpack.esql.plan.logical.promql.selector.LabelMatcher; +import org.elasticsearch.xpack.esql.plan.logical.promql.selector.LabelMatchers; +import org.elasticsearch.xpack.esql.plan.logical.promql.selector.LiteralSelector; +import org.elasticsearch.xpack.esql.plan.logical.promql.selector.RangeSelector; + +import java.time.Duration; +import java.util.ArrayList; +import java.util.LinkedHashSet; +import java.util.List; +import java.util.Locale; +import java.util.Set; + +import static java.util.Collections.emptyList; +import static org.elasticsearch.xpack.esql.expression.promql.function.FunctionType.ACROSS_SERIES_AGGREGATION; +import static org.elasticsearch.xpack.esql.expression.promql.function.FunctionType.WITHIN_SERIES_AGGREGATION; +import static org.elasticsearch.xpack.esql.parser.ParserUtils.visitList; +import static org.elasticsearch.xpack.esql.parser.PromqlBaseParser.AND; +import static org.elasticsearch.xpack.esql.parser.PromqlBaseParser.ASTERISK; +import static org.elasticsearch.xpack.esql.parser.PromqlBaseParser.CARET; +import static org.elasticsearch.xpack.esql.parser.PromqlBaseParser.EQ; +import static org.elasticsearch.xpack.esql.parser.PromqlBaseParser.GT; +import static org.elasticsearch.xpack.esql.parser.PromqlBaseParser.GTE; +import static org.elasticsearch.xpack.esql.parser.PromqlBaseParser.LT; +import static org.elasticsearch.xpack.esql.parser.PromqlBaseParser.LTE; +import static org.elasticsearch.xpack.esql.parser.PromqlBaseParser.MINUS; +import static org.elasticsearch.xpack.esql.parser.PromqlBaseParser.NEQ; +import static org.elasticsearch.xpack.esql.parser.PromqlBaseParser.OR; +import static org.elasticsearch.xpack.esql.parser.PromqlBaseParser.PERCENT; +import static org.elasticsearch.xpack.esql.parser.PromqlBaseParser.PLUS; +import static org.elasticsearch.xpack.esql.parser.PromqlBaseParser.SLASH; +import static org.elasticsearch.xpack.esql.parser.PromqlBaseParser.UNLESS; +import static org.elasticsearch.xpack.esql.plan.logical.promql.selector.LabelMatcher.NAME; + +public class PromqlLogicalPlanBuilder extends PromqlExpressionBuilder { + + public static final Duration GLOBAL_EVALUATION_INTERVAL = Duration.ofMinutes(1); + + PromqlLogicalPlanBuilder(Literal start, Literal end, int startLine, int startColumn) { + super(start, end, startLine, startColumn); + } + + protected LogicalPlan plan(ParseTree ctx) { + // wrap literal (expressions) into a plan to on demand instead of passing around + // LiteralSelector everywhere + return wrapLiteral(ctx); + } + + @Override + public LogicalPlan visitSingleStatement(PromqlBaseParser.SingleStatementContext ctx) { + return plan(ctx.expression()); + } + + static boolean isRangeVector(LogicalPlan plan) { + return switch (plan) { + case RangeSelector r -> true; + case Subquery s -> true; + default -> false; + }; + } + + static boolean isScalar(LogicalPlan plan) { + return plan instanceof LiteralSelector; + } + + private LogicalPlan wrapLiteral(ParseTree ctx) { + if (ctx == null) { + return null; + } + Source source = source(ctx); + Object result = visit(ctx); + return switch (result) { + case LogicalPlan plan -> plan; + case Literal literal -> new LiteralSelector(source, literal); + case Duration duration -> new LiteralSelector(source, Literal.timeDuration(source, duration)); + case Expression expr -> throw new ParsingException( + source, + "Expected a plan or literal, got expression [{}]", + expr.getClass().getSimpleName() + ); + default -> throw new ParsingException(source, "Expected a plan, got [{}]", result.getClass().getSimpleName()); + }; + } + + private Literal unwrapLiteral(ParserRuleContext ctx) { + Object o = visit(ctx); + return switch (o) { + case Literal literal -> literal; + case Expression expression -> { + if (expression.foldable()) { + yield Literal.of(FoldContext.small(), expression); + } + throw new ParsingException(source(ctx), "Constant expression required, found [{}]", expression.sourceText()); + } + case LiteralSelector selector -> selector.literal(); + default -> throw new ParsingException(source(ctx), "Constant expression required, found [{}]", ctx.getText()); + }; + } + + @Override + public LogicalPlan visitSelector(PromqlBaseParser.SelectorContext ctx) { + Source source = source(ctx); + PromqlBaseParser.SeriesMatcherContext seriesMatcher = ctx.seriesMatcher(); + String id = visitIdentifier(seriesMatcher.identifier()); + List labels = new ArrayList<>(); + Expression series = null; + List labelExpressions = new ArrayList<>(); + + boolean identifierId = (id != null); + + if (id != null) { + labels.add(new LabelMatcher(NAME, id, LabelMatcher.Matcher.EQ)); + // TODO: metric/ts name can be missing (e.g. {label=~"value"}) + series = new UnresolvedAttribute(source(seriesMatcher.identifier()), id); + } + + boolean nonEmptyMatcher = id != null; + Set seenLabelNames = new LinkedHashSet<>(); + + PromqlBaseParser.LabelsContext labelsCtx = seriesMatcher.labels(); + if (labelsCtx != null) { + // if no name is specified, check for non-empty matchers + for (PromqlBaseParser.LabelContext labelCtx : labelsCtx.label()) { + var nameCtx = labelCtx.labelName(); + String labelName = visitLabelName(nameCtx); + if (labelName.contains(":")) { + throw new ParsingException(source(nameCtx), "[:] not allowed in label names [{}]", labelName); + } + + // shortcut for specifying the name (no matcher operator) + if (labelCtx.kind == null) { + if (identifierId) { + throw new ParsingException(source(labelCtx), "Metric name must not be defined twice: [{}] or [{}]", id, labelName); + } + // set id/series from first label-based name + if (id == null) { + id = labelName; + series = new UnresolvedAttribute(source(labelCtx), id); + } + // always add as label matcher + labels.add(new LabelMatcher(NAME, labelName, LabelMatcher.Matcher.EQ)); + // add unresolved attribute on first encounter + if (seenLabelNames.add(NAME)) { + labelExpressions.add(new UnresolvedAttribute(source(nameCtx), NAME)); + } + nonEmptyMatcher = true; + + continue; + } + + String kind = labelCtx.kind.getText(); + LabelMatcher.Matcher matcher = LabelMatcher.Matcher.from(kind); + if (matcher == null) { + throw new ParsingException(source(labelCtx), "Unrecognized label matcher [{}]", kind); + } + + String labelValue = string(labelCtx.STRING()); + Source valueCtx = source(labelCtx.STRING()); + // __name__ with explicit matcher + if (NAME.equals(labelName)) { + if (identifierId) { + throw new ParsingException(source(nameCtx), "Metric name must not be defined twice: [{}] or [{}]", id, labelValue); + } + // set id/series from first label-based name + if (id == null) { + id = labelValue; + series = new UnresolvedAttribute(valueCtx, id); + } + } + + // always add label matcher + LabelMatcher label = new LabelMatcher(labelName, labelValue, matcher); + labels.add(label); + // add unresolved attribute on first encounter + if (seenLabelNames.add(labelName)) { + labelExpressions.add(new UnresolvedAttribute(source(nameCtx), labelName)); + } + + // require at least one non-empty matcher + if (nonEmptyMatcher == false && label.matchesEmpty() == false) { + nonEmptyMatcher = true; + } + } + + if (nonEmptyMatcher == false) { + throw new ParsingException(source(labelsCtx), "Vector selector must contain at least one non-empty matcher"); + } + } + Evaluation evaluation = visitEvaluation(ctx.evaluation()); + Expression range = visitDuration(ctx.duration()); + + final LabelMatchers matchers = new LabelMatchers(labels); + + return range == Literal.NULL + ? new InstantSelector(source, series, labelExpressions, matchers, evaluation) + : new RangeSelector(source, series, labelExpressions, matchers, range, evaluation); + } + + @Override + public LogicalPlan visitArithmeticUnary(PromqlBaseParser.ArithmeticUnaryContext ctx) { + Source source = source(ctx); + LogicalPlan unary = wrapLiteral(ctx.expression()); + + // unary operators do not make sense outside numeric data + if (unary instanceof LiteralSelector literalSelector) { + Literal literal = literalSelector.literal(); + Object value = literal.value(); + DataType dataType = literal.dataType(); + if (dataType.isNumeric() == false || value instanceof Number == false) { + throw new ParsingException( + source, + "Unary expression only allowed on expressions of type numeric or instant vector, got [{}]", + dataType.typeName() + ); + } + // optimize negation in case of literals + if (ctx.operator.getType() == MINUS) { + Number negatedValue = Arithmetics.negate((Number) value); + unary = new LiteralSelector(source, new Literal(unary.source(), negatedValue, dataType)); + } + } + // forbid range selectors + else if (isRangeVector(unary)) { + throw new ParsingException( + source, + "Unary expression only allowed on expressions of type numeric or instant vector, got [{}]", + unary.nodeName() + ); + } + + // For non-literals (vectors), rewrite as 0 - expression + if (ctx.operator.getType() == MINUS) { + LiteralSelector zero = new LiteralSelector(source, Literal.integer(source, 0)); + return new VectorBinaryArithmetic(source, zero, unary, VectorMatch.NONE, ArithmeticOp.SUB); + } + + return unary; + } + + @Override + public LogicalPlan visitArithmeticBinary(PromqlBaseParser.ArithmeticBinaryContext ctx) { + Source source = source(ctx); + LogicalPlan le = wrapLiteral(ctx.left); + LogicalPlan re = wrapLiteral(ctx.right); + + boolean bool = ctx.BOOL() != null; + int opType = ctx.op.getType(); + String opText = ctx.op.getText(); + + // validate operation against expression types + boolean leftIsScalar = isScalar(le); + boolean rightIsScalar = isScalar(re); + + // comparisons against scalars require bool + if (bool == false && leftIsScalar && rightIsScalar) { + switch (opType) { + case EQ: + case NEQ: + case LT: + case LTE: + case GT: + case GTE: + throw new ParsingException(source, "Comparisons [{}] between scalars must use the BOOL modifier", opText); + } + } + // set operations are not allowed on scalars + if (leftIsScalar || rightIsScalar) { + switch (opType) { + case AND: + case UNLESS: + case OR: + throw new ParsingException(source, "Set operator [{}] not allowed in binary scalar expression", opText); + } + } + + BinaryOp binaryOperator = binaryOp(ctx.op); + + // Handle scalar folding once validation passes + if (le instanceof LiteralSelector leftSel && re instanceof LiteralSelector rightSel) { + Literal leftLiteral = leftSel.literal(); + Literal rightLiteral = rightSel.literal(); + + // Extract values + Object leftValue = leftLiteral.value(); + Object rightValue = rightLiteral.value(); + + // arithmetics + if (binaryOperator instanceof ArithmeticOp arithmeticOp) { + Object result = PromqlFoldingUtils.evaluate(source, leftValue, rightValue, arithmeticOp); + DataType resultType = determineResultType(result); + return new LiteralSelector(source, new Literal(source, result, resultType)); + } + + // comparisons + if (binaryOperator instanceof ComparisonOp compOp) { + int result = PromqlFoldingUtils.evaluate(source, leftValue, rightValue, compOp) ? 1 : 0; + return new LiteralSelector(source, Literal.integer(source, result)); + } + + // Set operations fall through to vector handling + } + + VectorMatch modifier = VectorMatch.NONE; + + PromqlBaseParser.ModifierContext modifierCtx = ctx.modifier(); + if (modifierCtx != null) { + // modifiers work only on vectors + if (isRangeVector(le) || isRangeVector(re) || isScalar(le) || isScalar(re)) { + throw new ParsingException(source, "Vector matching allowed only between instant vectors"); + } + + VectorMatch.Filter filter = modifierCtx.ON() != null ? VectorMatch.Filter.ON : VectorMatch.Filter.IGNORING; + List filterList = visitLabelList(modifierCtx.modifierLabels); + VectorMatch.Joining joining = VectorMatch.Joining.NONE; + List groupingList = visitLabelList(modifierCtx.groupLabels); + if (modifierCtx.joining != null) { + joining = modifierCtx.GROUP_LEFT() != null ? VectorMatch.Joining.LEFT : VectorMatch.Joining.RIGHT; + + // grouping not allowed with logic operators + switch (opType) { + case AND: + case UNLESS: + case OR: + throw new ParsingException(source(modifierCtx), "No grouping [{}] allowed for [{}] operator", joining, opText); + } + + // label declared in ON cannot appear in grouping + if (modifierCtx.ON() != null) { + List repeatedLabels = new ArrayList<>(groupingList); + if (filterList.isEmpty() == false && repeatedLabels.retainAll(filterList) && repeatedLabels.isEmpty() == false) { + throw new ParsingException( + source(modifierCtx.ON()), + "Label{} {} must not occur in ON and GROUP clause at once", + repeatedLabels.size() > 1 ? "s" : "", + repeatedLabels + ); + } + + } + } + + modifier = new VectorMatch(filter, new LinkedHashSet<>(filterList), joining, new LinkedHashSet<>(groupingList)); + } + + return switch (binaryOperator) { + case ArithmeticOp arithmeticOp -> new VectorBinaryArithmetic(source, le, re, modifier, arithmeticOp); + case ComparisonOp comparisonOp -> new VectorBinaryComparison(source, le, re, modifier, bool, comparisonOp); + case VectorBinarySet.SetOp setOp -> new VectorBinarySet(source, le, re, modifier, setOp); + default -> throw new ParsingException(source(ctx.op), "Unknown arithmetic {}", opText); + }; + } + + private BinaryOp binaryOp(Token opType) { + return switch (opType.getType()) { + case CARET -> ArithmeticOp.POW; + case ASTERISK -> ArithmeticOp.MUL; + case PERCENT -> ArithmeticOp.MOD; + case SLASH -> ArithmeticOp.DIV; + case MINUS -> ArithmeticOp.SUB; + case PLUS -> ArithmeticOp.ADD; + case EQ -> ComparisonOp.EQ; + case NEQ -> ComparisonOp.NEQ; + case LT -> ComparisonOp.LT; + case LTE -> ComparisonOp.LTE; + case GT -> ComparisonOp.GT; + case GTE -> ComparisonOp.GTE; + case AND -> VectorBinarySet.SetOp.INTERSECT; + case UNLESS -> VectorBinarySet.SetOp.SUBTRACT; + case OR -> VectorBinarySet.SetOp.UNION; + default -> throw new ParsingException(source(opType), "Unknown arithmetic {}", opType.getText()); + }; + } + + /** + * Determine DataType from the result value. + */ + private DataType determineResultType(Object value) { + return switch (value) { + case Duration d -> DataType.TIME_DURATION; + case Integer i -> DataType.INTEGER; + case Long l -> DataType.LONG; + case Double d -> DataType.DOUBLE; + case Number n -> DataType.DOUBLE; // fallback for other Number types + default -> throw new IllegalArgumentException("Unexpected result type: " + value.getClass()); + }; + } + + @Override + public Object visitParenthesized(PromqlBaseParser.ParenthesizedContext ctx) { + return visit(ctx.expression()); + } + + @Override + @SuppressWarnings("rawtypes") + public LogicalPlan visitFunction(PromqlBaseParser.FunctionContext ctx) { + Source source = source(ctx); + String name = ctx.IDENTIFIER().getText().toLowerCase(Locale.ROOT); + + Boolean exists = PromqlFunctionRegistry.INSTANCE.functionExists(name); + if (Boolean.TRUE.equals(exists) == false) { + String message = exists == null ? "Function [{}] not implemented yet" : "Unknown function [{}]"; + throw new ParsingException(source, message, name); + } + + var metadata = PromqlFunctionRegistry.INSTANCE.functionMetadata(name); + + // TODO: the list of params could contain literals so need to handle that + var paramsCtx = ctx.functionParams(); + List params = paramsCtx != null ? visitList(this, paramsCtx.expression(), Node.class) : emptyList(); + + int paramCount = params.size(); + String message = "Invalid number of parameters for function [{}], required [{}], found [{}]"; + if (paramCount < metadata.arity().min()) { + throw new ParsingException(source, message, name, metadata.arity().min(), paramCount); + } + if (paramCount > metadata.arity().max()) { + throw new ParsingException(source, message, name, metadata.arity().max(), paramCount); + } + + // child plan is always the first parameter + LogicalPlan child = (LogicalPlan) params.get(0); + + // PromQl expects early validation of the tree so let's do it here + PromqlBaseParser.GroupingContext groupingContext = ctx.grouping(); + + LogicalPlan plan = null; + // explicit grouping + if (groupingContext != null) { + var grouping = groupingContext.BY() != null ? AcrossSeriesAggregate.Grouping.BY : AcrossSeriesAggregate.Grouping.WITHOUT; + + if (grouping != AcrossSeriesAggregate.Grouping.BY) { + throw new ParsingException(source, "[{}] clause not supported yet", grouping.name().toLowerCase(Locale.ROOT), name); + } + + if (metadata.functionType() != ACROSS_SERIES_AGGREGATION) { + throw new ParsingException( + source, + "[{}] clause not allowed on non-aggregation function [{}]", + grouping.name().toLowerCase(Locale.ROOT), + name + ); + } + + PromqlBaseParser.LabelListContext labelListCtx = groupingContext.labelList(); + List groupingKeys = visitLabelList(labelListCtx); + // TODO: this + List groupings = new ArrayList<>(groupingKeys.size()); + for (int i = 0; i < groupingKeys.size(); i++) { + groupings.add(new UnresolvedAttribute(source(labelListCtx.labelName(i)), groupingKeys.get(i))); + } + plan = new AcrossSeriesAggregate(source, child, name, List.of(), grouping, groupings); + } else { + if (metadata.functionType() == ACROSS_SERIES_AGGREGATION) { + plan = new AcrossSeriesAggregate(source, child, name, List.of(), AcrossSeriesAggregate.Grouping.NONE, List.of()); + } else if (metadata.functionType() == WITHIN_SERIES_AGGREGATION) { + if (isRangeVector(child) == false) { + throw new ParsingException(source, "expected type range vector in call to function [{}], got instant vector", name); + } + + plan = new WithinSeriesAggregate(source, child, name, List.of()); + // instant selector function - definitely no grouping + } + } + // + return plan; + } + + @Override + public Subquery visitSubquery(PromqlBaseParser.SubqueryContext ctx) { + Source source = source(ctx); + LogicalPlan plan = plan(ctx.expression()); + + if (isRangeVector(plan)) { + throw new ParsingException(source, "Subquery is only allowed on instant vector, got {}", plan.nodeName()); + } + + Evaluation evaluation = visitEvaluation(ctx.evaluation()); + Literal rangeEx = visitDuration(ctx.range); + Literal resolution = visitSubqueryResolution(ctx.subqueryResolution()); + + if (resolution == null) { + resolution = Literal.timeDuration(Source.EMPTY, GLOBAL_EVALUATION_INTERVAL); + } + return new Subquery(source(ctx), plan, rangeEx, resolution, evaluation); + } + + /** + * Parse subquery resolution, reusing the same expression folding logic used for duration arithmetic. + */ + public Literal visitSubqueryResolution(PromqlBaseParser.SubqueryResolutionContext ctx) { + if (ctx == null) { + return Literal.NULL; + } + + // Case 1: COLON (resolution=duration)? + // Examples: ":5m", ":(5m + 1m)", etc. + // This reuses visitDuration which already handles arithmetic through expression folding + if (ctx.resolution != null) { + return visitDuration(ctx.resolution); + } + + // Case 2-5: TIME_VALUE_WITH_COLON cases + // Examples: ":5m", ":5m * 2", ":5m ^ 2", ":5m + 1m", etc. + var timeCtx = ctx.TIME_VALUE_WITH_COLON(); + if (timeCtx != null) { + // Parse the base time value (e.g., ":5m" -> "5m") + String timeString = timeCtx.getText().substring(1).trim(); + Source timeSource = source(timeCtx); + Duration baseValue = PromqlParserUtils.parseDuration(timeSource, timeString); + + if (ctx.op == null || ctx.expression() == null) { + return Literal.timeDuration(source(timeCtx), baseValue); + } + + // Evaluate right expression + Object rightValue = unwrapLiteral(ctx.expression()).value(); + + // Perform arithmetic using utility + BinaryOp binaryOp = binaryOp(ctx.op); + Object result; + if (binaryOp instanceof ArithmeticOp operation) { + result = PromqlFoldingUtils.evaluate(source(ctx), baseValue, rightValue, operation); + } else { + throw new ParsingException(source(ctx), "Unsupported binary operator [{}] in time duration", binaryOp); + } + // Result should be Duration + if (result instanceof Duration duration) { + return Literal.timeDuration(source(timeCtx), duration); + } + + throw new ParsingException(source(ctx), "Expected duration result, got [{}]", result.getClass().getSimpleName()); + } + + // Just COLON with no resolution - use default + return Literal.NULL; + } +} diff --git a/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/parser/promql/PromqlParserUtils.java b/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/parser/promql/PromqlParserUtils.java new file mode 100644 index 0000000000000..6f38ed51cc598 --- /dev/null +++ b/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/parser/promql/PromqlParserUtils.java @@ -0,0 +1,293 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +package org.elasticsearch.xpack.esql.parser.promql; + +import org.elasticsearch.core.Tuple; +import org.elasticsearch.xpack.esql.core.tree.Location; +import org.elasticsearch.xpack.esql.core.tree.Source; +import org.elasticsearch.xpack.esql.parser.ParsingException; + +import java.time.Duration; +import java.time.Instant; +import java.time.format.DateTimeParseException; +import java.util.LinkedHashMap; +import java.util.Map; + +import static java.util.Collections.unmodifiableMap; + +public class PromqlParserUtils { + // time units recognized by Prometheus + private static final Map TIME_UNITS; + + static { + // NB: using JDK TimeUnit or ChronoUnits turns out to be verbose + // hence the basic approach used below + // NB2: using LHM to preserve insertion order for consistent strings around keys + Map map = new LinkedHashMap<>(); + map.put("y", 1000L * 60 * 60 * 24 * 365); + map.put("w", 1000L * 60 * 60 * 24 * 7); + map.put("d", 1000L * 60 * 60 * 24); + map.put("h", 1000L * 60 * 60); + map.put("m", 1000L * 60); + map.put("s", 1000L); + map.put("ms", 1L); + TIME_UNITS = unmodifiableMap(map); + } + + private PromqlParserUtils() {} + + public static Duration parseDuration(Source source, String string) { + char[] chars = string.toCharArray(); + + long millis = 0; + + String errorPrefix = "Invalid time duration [{}], "; + int current; + Tuple lastUnit = null; + for (int i = 0; i < chars.length;) { + current = i; + // number - look for digits + while (current < chars.length && Character.isDigit(chars[current])) { + current++; + } + // at least one digit needs to be specified + if (current == i) { + throw new ParsingException(source, errorPrefix + "no number specified at index [{}]", string, current); + } + String token = new String(chars, i, current - i); + int number; + try { + number = Integer.parseInt(token); + } catch (NumberFormatException ex) { + throw new ParsingException(source, errorPrefix + "invalid number [{}]", string, token); + } + i = current; + // unit - look for letters + while (current < chars.length && Character.isLetter(chars[current])) { + current++; + } + // at least one letter needs to be specified + if (current == i) { + throw new ParsingException(source, errorPrefix + "no unit specified at index [{}]", string, current); + } + token = new String(chars, i, current - i); + i = current; + + Long msMultiplier = TIME_UNITS.get(token); + if (msMultiplier == null) { + throw new ParsingException( + source, + errorPrefix + "unrecognized time unit [{}], must be one of {}", + string, + token, + TIME_UNITS.keySet() + ); + } + if (lastUnit != null) { + if (lastUnit.v2() < msMultiplier) { + throw new ParsingException( + source, + errorPrefix + "units must be ordered from the longest to the shortest, found [{}] before [{}]", + string, + lastUnit.v1(), + token + ); + } else if (lastUnit.v2().equals(msMultiplier)) { + throw new ParsingException( + source, + errorPrefix + "a given unit must only appear once, found [{}] multiple times", + string, + token + ); + } + } + lastUnit = new Tuple<>(token, msMultiplier); + + millis += number * msMultiplier; + } + + return Duration.ofMillis(millis); + } + + static String unquote(Source source) { + // remove leading and trailing ' for strings and also eliminate escaped single quotes + if (source == null) { + return null; + } + + String text = source.text(); + boolean unescaped = text.startsWith("`"); + + // remove leading/trailing chars + text = text.substring(1, text.length() - 1); + + if (unescaped) { + return text; + } + StringBuilder sb = new StringBuilder(); + + // https://prometheus.io/docs/prometheus/latest/querying/basics/#string-literals + // Go: https://golang.org/ref/spec#Rune_literals + char[] chars = text.toCharArray(); + for (int i = 0; i < chars.length;) { + if (chars[i] == '\\') { + // ANTLR4 Grammar guarantees there is always a character after the `\` + switch (chars[++i]) { + case 'a': + sb.append('\u0007'); + break; + case 'b': + sb.append('\b'); + break; + case 'f': + sb.append('\f'); + break; + case 'n': + sb.append('\n'); + break; + case 'r': + sb.append('\r'); + break; + case 't': + sb.append('\t'); + break; + case 'v': + sb.append('\u000B'); + break; + case '\\': + sb.append('\\'); + break; + case '\'': + sb.append('\''); + break; + case '"': + sb.append('"'); + break; + case 'x': + case 'u': + case 'U': + // all 3 cases rely on hex characters - only the number of chars between them differ + // get the current chat and move to the next offset + int ch = chars[i++]; + int count = ch == 'U' ? 8 : (ch == 'u' ? 4 : 2); + sb.append(fromRadix(source, chars, i, count, 16)); + i += count - 1; + break; + default: + // octal declaration - eats 3 chars + // there's no escape character, no need to move the offset + count = 3; + sb.append(fromRadix(source, chars, i, count, 8)); + i += count - 1; + } + i++; + } else { + sb.append(chars[i++]); + } + } + return sb.toString(); + } + + // parse the given number of strings to + private static String fromRadix(Source source, char[] chars, int offset, int count, int radix) { + if (offset + count > chars.length) { + throw new ParsingException( + source, + "Incomplete escape sequence at [{}], expected [{}] found [{}]", + offset, + count, + chars.length - offset - 1 // offset starts at 0 + ); + } + + String toParse = new String(chars, offset, count); + int code; + try { + code = Integer.parseInt(toParse, radix); + } catch (NumberFormatException ex) { + throw new ParsingException(source, "Invalid unicode character code [{}]", toParse); + } + + // For \x escapes (2-digit hex), validate UTF-8 compliance + // Single-byte UTF-8 characters must be in range 0x00-0x7F + if (radix == 16 && count == 2) { + if (code >= 0x80 && code <= 0xFF) { + throw new ParsingException( + source, + "Invalid unicode character code [\\x{}], single-byte UTF-8 characters must be in range 0x00-0x7F", + toParse + ); + } + } + + return String.valueOf(Character.toChars(code)); + } + + /** + * Adjusts the location of the source by the line and column offsets. + * @see #adjustLocation(Location, int, int) + */ + public static Source adjustSource(Source source, int startLine, int startColumn) { + return new Source(adjustLocation(source.source(), startLine, startColumn), source.text()); + } + + /** + * Adjusts the location by the line and column offsets. + * The PromQL query inside the PROMQL command is parsed separately, + * so its line and column numbers need to be adjusted to match their + * position inside the full ES|QL query. + */ + public static Location adjustLocation(Location location, int startLine, int startColumn) { + int lineNumber = location.getLineNumber(); + int columnNumber = location.getColumnNumber(); + return new Location(adjustLine(lineNumber, startLine), adjustColumn(lineNumber, columnNumber, startColumn)); + } + + /** + * Adjusts the line and column numbers of the given {@code ParsingException} + * by the provided offsets. + * The PromQL query inside the PROMQL command is parsed separately, + * so its line and column numbers need to be adjusted to match their + * position inside the full ES|QL query. + */ + public static ParsingException adjustParsingException(ParsingException pe, int promqlStartLine, int promqlStartColumn) { + ParsingException adjusted = new ParsingException( + pe.getErrorMessage(), + pe.getCause() instanceof Exception ? (Exception) pe.getCause() : null, + adjustLine(pe.getLineNumber(), promqlStartLine), + adjustColumn(pe.getLineNumber(), pe.getColumnNumber(), promqlStartColumn) + ); + adjusted.setStackTrace(pe.getStackTrace()); + return adjusted; + } + + private static int adjustLine(int lineNumber, int startLine) { + return lineNumber + startLine - 1; + } + + private static int adjustColumn(int lineNumber, int columnNumber, int startColumn) { + // the column offset only applies to the first line of the PROMQL command + return lineNumber == 1 ? columnNumber + startColumn - 1 : columnNumber; + } + + /* + * Parses a Prometheus date which can be either a float representing epoch seconds or an RFC3339 date string. + */ + public static Instant parseDate(Source source, String value) { + try { + return Instant.ofEpochMilli((long) (Double.parseDouble(value) * 1000)); + } catch (NumberFormatException ignore) { + // Not a float, try parsing as date string + } + try { + return Instant.parse(value); + } catch (DateTimeParseException e) { + throw new ParsingException(source, "Invalid date format [{}]", value); + } + } +} diff --git a/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/plan/logical/BinaryPlan.java b/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/plan/logical/BinaryPlan.java index dbd22dd297f88..31368c4b32d52 100644 --- a/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/plan/logical/BinaryPlan.java +++ b/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/plan/logical/BinaryPlan.java @@ -31,9 +31,13 @@ public LogicalPlan right() { return right; } - public abstract AttributeSet leftReferences(); + public AttributeSet leftReferences() { + return left.references(); + } - public abstract AttributeSet rightReferences(); + public AttributeSet rightReferences() { + return right.references(); + } @Override public final BinaryPlan replaceChildren(List newChildren) { diff --git a/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/plan/logical/promql/AcrossSeriesAggregate.java b/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/plan/logical/promql/AcrossSeriesAggregate.java new file mode 100644 index 0000000000000..06b12acc99468 --- /dev/null +++ b/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/plan/logical/promql/AcrossSeriesAggregate.java @@ -0,0 +1,84 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +package org.elasticsearch.xpack.esql.plan.logical.promql; + +import org.elasticsearch.xpack.esql.core.capabilities.Resolvables; +import org.elasticsearch.xpack.esql.core.expression.Expression; +import org.elasticsearch.xpack.esql.core.tree.NodeInfo; +import org.elasticsearch.xpack.esql.core.tree.Source; +import org.elasticsearch.xpack.esql.plan.logical.LogicalPlan; + +import java.util.List; +import java.util.Objects; + +public class AcrossSeriesAggregate extends PromqlFunctionCall { + + public enum Grouping { + BY, + WITHOUT, + NONE + } + + private final Grouping grouping; + private final List groupings; + + public AcrossSeriesAggregate( + Source source, + LogicalPlan child, + String functionName, + List parameters, + Grouping grouping, + List groupings + ) { + super(source, child, functionName, parameters); + this.grouping = grouping; + this.groupings = groupings; + } + + public Grouping grouping() { + return grouping; + } + + public List groupings() { + return groupings; + } + + @Override + public boolean expressionsResolved() { + return Resolvables.resolved(groupings) && super.expressionsResolved(); + } + + @Override + protected NodeInfo info() { + return NodeInfo.create(this, AcrossSeriesAggregate::new, child(), functionName(), parameters(), grouping(), groupings()); + } + + @Override + public AcrossSeriesAggregate replaceChild(LogicalPlan newChild) { + return new AcrossSeriesAggregate(source(), newChild, functionName(), parameters(), grouping(), groupings()); + } + + // @Override + // public String telemetryLabel() { + // return "PROMQL_ACROSS_SERIES_AGGREGATION"; + // } + + @Override + public boolean equals(Object o) { + if (super.equals(o)) { + AcrossSeriesAggregate that = (AcrossSeriesAggregate) o; + return grouping == that.grouping && Objects.equals(groupings, that.groupings); + } + return false; + } + + @Override + public int hashCode() { + return Objects.hash(super.hashCode(), grouping, groupings); + } +} diff --git a/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/plan/logical/promql/PlaceholderRelation.java b/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/plan/logical/promql/PlaceholderRelation.java new file mode 100644 index 0000000000000..3bb3b728fd94c --- /dev/null +++ b/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/plan/logical/promql/PlaceholderRelation.java @@ -0,0 +1,66 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +package org.elasticsearch.xpack.esql.plan.logical.promql; + +import org.elasticsearch.common.io.stream.StreamOutput; +import org.elasticsearch.xpack.esql.core.expression.Attribute; +import org.elasticsearch.xpack.esql.core.tree.NodeInfo; +import org.elasticsearch.xpack.esql.core.tree.Source; +import org.elasticsearch.xpack.esql.plan.logical.LeafPlan; +import org.elasticsearch.xpack.esql.plan.logical.LogicalPlan; + +import java.io.IOException; +import java.util.List; + +/** + * Marker node used inside PromQL as the children of all selectors. When embedded inside ESQL, the relationship can be replaced with the + * subplan. + */ +public class PlaceholderRelation extends LeafPlan { + + public static final LogicalPlan INSTANCE = new PlaceholderRelation(Source.EMPTY); + + public PlaceholderRelation(Source source) { + super(source); + } + + @Override + public boolean expressionsResolved() { + return true; + } + + @Override + protected NodeInfo info() { + return NodeInfo.create(this); + } + + @Override + public int hashCode() { + return PlaceholderRelation.class.hashCode(); + } + + @Override + public boolean equals(Object obj) { + return obj instanceof PlaceholderRelation; + } + + @Override + public List output() { + return List.of(); + } + + @Override + public String getWriteableName() { + throw new UnsupportedOperationException("does not support serialization"); + } + + @Override + public void writeTo(StreamOutput out) throws IOException { + throw new UnsupportedOperationException("does not support serialization"); + } +} diff --git a/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/plan/logical/promql/PromqlCommand.java b/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/plan/logical/promql/PromqlCommand.java new file mode 100644 index 0000000000000..6a3a4acab67a1 --- /dev/null +++ b/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/plan/logical/promql/PromqlCommand.java @@ -0,0 +1,197 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +package org.elasticsearch.xpack.esql.plan.logical.promql; + +import org.elasticsearch.common.io.stream.StreamOutput; +import org.elasticsearch.xpack.esql.capabilities.PostAnalysisVerificationAware; +import org.elasticsearch.xpack.esql.capabilities.TelemetryAware; +import org.elasticsearch.xpack.esql.common.Failures; +import org.elasticsearch.xpack.esql.core.expression.Expression; +import org.elasticsearch.xpack.esql.core.expression.Literal; +import org.elasticsearch.xpack.esql.core.tree.NodeInfo; +import org.elasticsearch.xpack.esql.core.tree.Source; +import org.elasticsearch.xpack.esql.expression.function.TimestampAware; +import org.elasticsearch.xpack.esql.expression.promql.subquery.Subquery; +import org.elasticsearch.xpack.esql.plan.logical.LogicalPlan; +import org.elasticsearch.xpack.esql.plan.logical.UnaryPlan; +import org.elasticsearch.xpack.esql.plan.logical.promql.selector.RangeSelector; +import org.elasticsearch.xpack.esql.plan.logical.promql.selector.Selector; + +import java.io.IOException; +import java.time.Duration; +import java.util.Objects; + +import static org.elasticsearch.xpack.esql.common.Failure.fail; + +/** + * Container plan for embedded PromQL queries. + * Gets eliminated by the analyzer once the query is validated. + */ +public class PromqlCommand extends UnaryPlan implements TelemetryAware, PostAnalysisVerificationAware, TimestampAware { + + private final LogicalPlan promqlPlan; + private final Literal start; + private final Literal end; + private final Literal step; + // TODO: this should be made available through the planner + private final Expression timestamp; + + // Range query constructor + public PromqlCommand( + Source source, + LogicalPlan child, + LogicalPlan promqlPlan, + Literal start, + Literal end, + Literal step, + Expression timestamp + ) { + super(source, child); + this.promqlPlan = promqlPlan; + this.start = start; + this.end = end; + this.step = step; + this.timestamp = timestamp; + } + + @Override + protected NodeInfo info() { + return NodeInfo.create(this, PromqlCommand::new, child(), promqlPlan(), start(), end(), step(), timestamp()); + } + + @Override + public PromqlCommand replaceChild(LogicalPlan newChild) { + return new PromqlCommand(source(), newChild, promqlPlan(), start(), end(), step(), timestamp()); + } + + public PromqlCommand withPromqlPlan(LogicalPlan newPromqlPlan) { + return new PromqlCommand(source(), child(), newPromqlPlan, start(), end(), step(), timestamp()); + } + + @Override + public boolean expressionsResolved() { + return promqlPlan.resolved() && timestamp.resolved(); + } + + @Override + public String telemetryLabel() { + return "PROMQL"; + } + + @Override + public String getWriteableName() { + throw new UnsupportedOperationException("serialization not supported"); + } + + @Override + public void writeTo(StreamOutput out) throws IOException { + throw new UnsupportedOperationException("serialization not supported"); + } + + public LogicalPlan promqlPlan() { + return promqlPlan; + } + + public Literal start() { + return start; + } + + public Literal end() { + return end; + } + + public Literal step() { + return step; + } + + public boolean isInstantQuery() { + return step.value() == null; + } + + public boolean isRangeQuery() { + return step.value() != null; + } + + @Override + public int hashCode() { + return Objects.hash(child(), promqlPlan, start, end, step, timestamp); + } + + @Override + public boolean equals(Object obj) { + if (super.equals(obj)) { + + PromqlCommand other = (PromqlCommand) obj; + return Objects.equals(child(), other.child()) + && Objects.equals(promqlPlan, other.promqlPlan) + && Objects.equals(start, other.start) + && Objects.equals(end, other.end) + && Objects.equals(step, other.step) + && Objects.equals(timestamp, other.timestamp); + } + + return false; + } + + @Override + public String nodeString() { + StringBuilder sb = new StringBuilder(); + sb.append(nodeName()); + sb.append(" start=[").append(start); + sb.append("] end=[").append(end); + sb.append("] step=[").append(step); + sb.append("] promql=[<>\n"); + sb.append(promqlPlan.toString()); + sb.append("\n<>]]"); + return sb.toString(); + } + + @Override + public void postAnalysisVerification(Failures failures) { + LogicalPlan p = promqlPlan(); + if (p instanceof AcrossSeriesAggregate == false) { + failures.add(fail(p, "only aggregations across timeseries are supported at this time (found [{}])", p.sourceText())); + } + p.forEachDown(lp -> { + if (lp instanceof Selector s) { + if (s.labelMatchers().nameLabel().matcher().isRegex()) { + failures.add(fail(s, "regex label selectors on __name__ are not supported at this time [{}]", s.sourceText())); + } + if (s.evaluation() != null) { + if (s.evaluation().offset().value() != null && s.evaluation().offsetDuration().isZero() == false) { + failures.add(fail(s, "offset modifiers are not supported at this time [{}]", s.sourceText())); + } + if (s.evaluation().at().value() != null) { + failures.add(fail(s, "@ modifiers are not supported at this time [{}]", s.sourceText())); + } + } + } + if (lp instanceof Subquery) { + failures.add(fail(lp, "subqueries are not supported at this time [{}]", lp.sourceText())); + } + if (step().value() != null && lp instanceof RangeSelector rs) { + Duration rangeDuration = (Duration) rs.range().fold(null); + if (rangeDuration.equals(step().value()) == false) { + failures.add( + fail( + rs.range(), + "the duration for range vector selector [{}] " + + "must be equal to the query's step for range queries at this time", + rs.range().sourceText() + ) + ); + } + } + }); + } + + @Override + public Expression timestamp() { + return timestamp; + } +} diff --git a/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/plan/logical/promql/PromqlFunctionCall.java b/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/plan/logical/promql/PromqlFunctionCall.java new file mode 100644 index 0000000000000..76be00e9b06b3 --- /dev/null +++ b/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/plan/logical/promql/PromqlFunctionCall.java @@ -0,0 +1,113 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +package org.elasticsearch.xpack.esql.plan.logical.promql; + +import org.elasticsearch.common.io.stream.StreamOutput; +import org.elasticsearch.xpack.esql.core.capabilities.Resolvables; +import org.elasticsearch.xpack.esql.core.expression.Attribute; +import org.elasticsearch.xpack.esql.core.expression.Expression; +import org.elasticsearch.xpack.esql.core.expression.ReferenceAttribute; +import org.elasticsearch.xpack.esql.core.tree.NodeInfo; +import org.elasticsearch.xpack.esql.core.tree.Source; +import org.elasticsearch.xpack.esql.core.type.DataType; +import org.elasticsearch.xpack.esql.plan.logical.LogicalPlan; +import org.elasticsearch.xpack.esql.plan.logical.UnaryPlan; + +import java.io.IOException; +import java.util.List; +import java.util.Objects; + +/** + * Represents a PromQL function call in the logical plan. + * + * This is a surrogate logical plan that encapsulates a PromQL function invocation + * and delegates to the PromqlFunctionRegistry for validation and ESQL function construction. + */ +public class PromqlFunctionCall extends UnaryPlan { + // implements TelemetryAware { + + private final String functionName; + private final List parameters; + private List output; + + public PromqlFunctionCall(Source source, LogicalPlan child, String functionName, List parameters) { + super(source, child); + this.functionName = functionName; + this.parameters = parameters != null ? parameters : List.of(); + } + + @Override + public void writeTo(StreamOutput out) throws IOException { + throw new UnsupportedOperationException("PromqlFunctionCall does not support serialization"); + } + + @Override + public String getWriteableName() { + throw new UnsupportedOperationException("PromqlFunctionCall does not support serialization"); + } + + @Override + protected NodeInfo info() { + return NodeInfo.create(this, PromqlFunctionCall::new, child(), functionName, parameters); + } + + @Override + public PromqlFunctionCall replaceChild(LogicalPlan newChild) { + return new PromqlFunctionCall(source(), newChild, functionName, parameters); + } + + public String functionName() { + return functionName; + } + + public List parameters() { + return parameters; + } + + @Override + public List output() { + if (output == null) { + output = List.of( + new ReferenceAttribute(source(), "promql$labels", DataType.KEYWORD), + new ReferenceAttribute(source(), "promql$timestamp", DataType.DATETIME), + new ReferenceAttribute(source(), "promql$value", DataType.DOUBLE) + ); + } + return output; + } + + @Override + public boolean expressionsResolved() { + return Resolvables.resolved(parameters); + } + + // @Override + // public String telemetryLabel() { + // return "PROMQL_FUNCTION_CALL"; + // } + + @Override + public int hashCode() { + return Objects.hash(child(), functionName, parameters); + } + + @Override + public boolean equals(Object obj) { + if (this == obj) { + return true; + } + if (obj == null || getClass() != obj.getClass()) { + return false; + } + + PromqlFunctionCall other = (PromqlFunctionCall) obj; + return Objects.equals(child(), other.child()) + && Objects.equals(functionName, other.functionName) + && Objects.equals(parameters, other.parameters); + } +} diff --git a/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/plan/logical/promql/WithinSeriesAggregate.java b/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/plan/logical/promql/WithinSeriesAggregate.java new file mode 100644 index 0000000000000..6b266a0fc802a --- /dev/null +++ b/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/plan/logical/promql/WithinSeriesAggregate.java @@ -0,0 +1,102 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +package org.elasticsearch.xpack.esql.plan.logical.promql; + +import org.elasticsearch.xpack.esql.core.expression.Alias; +import org.elasticsearch.xpack.esql.core.expression.Expression; +import org.elasticsearch.xpack.esql.core.expression.NamedExpression; +import org.elasticsearch.xpack.esql.core.expression.ReferenceAttribute; +import org.elasticsearch.xpack.esql.core.expression.function.Function; +import org.elasticsearch.xpack.esql.core.tree.NodeInfo; +import org.elasticsearch.xpack.esql.core.tree.Source; +import org.elasticsearch.xpack.esql.core.type.DataType; +import org.elasticsearch.xpack.esql.expression.promql.function.PromqlFunctionRegistry; +import org.elasticsearch.xpack.esql.plan.logical.LogicalPlan; +import org.elasticsearch.xpack.esql.plan.logical.SurrogateLogicalPlan; +import org.elasticsearch.xpack.esql.plan.logical.TimeSeriesAggregate; + +import java.util.ArrayList; +import java.util.List; + +/** + * Represents a PromQL aggregate function call that operates on range vectors. + * + * This is a surrogate logical plan for PromQL range vector functions that translate + * to ESQL TimeSeriesAggregate operations. It extends PromqlFunctionCall and implements + * the surrogate pattern to transform PromQL aggregations into ESQL time-series aggregates. + * + * Range vector functions supported: + * - Counter functions: rate(), irate(), increase(), delta(), idelta() + * - Aggregation functions: avg_over_time(), sum_over_time(), min_over_time(), max_over_time(), count_over_time() + * - Selection functions: first_over_time(), last_over_time() + * - Presence functions: present_over_time(), absent_over_time() + * - Cardinality functions: count_distinct_over_time() + * + * During planning, surrogate() transforms this node into: + * TimeSeriesAggregate( + * child: RangeSelector (or other time-series source), + * groupings: [_tsid], + * aggregates: [function_result, _tsid] + * ) + * + * Example transformations: + * rate(http_requests[5m]) + * → TimeSeriesAggregate(groupBy: _tsid, agg: Rate(value, @timestamp)) + * + * avg_over_time(cpu_usage[1h]) + * → TimeSeriesAggregate(groupBy: _tsid, agg: AvgOverTime(value)) + */ +public class WithinSeriesAggregate extends PromqlFunctionCall implements SurrogateLogicalPlan { + + public WithinSeriesAggregate(Source source, LogicalPlan child, String functionName, List parameters) { + super(source, child, functionName, parameters); + } + + @Override + protected NodeInfo info() { + return NodeInfo.create(this, WithinSeriesAggregate::new, child(), functionName(), parameters()); + } + + @Override + public WithinSeriesAggregate replaceChild(LogicalPlan newChild) { + return new WithinSeriesAggregate(source(), newChild, functionName(), parameters()); + } + + @Override + public LogicalPlan surrogate() { + LogicalPlan childPlan = child(); + + ReferenceAttribute timestampField = new ReferenceAttribute(source(), "@timestamp", DataType.DATETIME); + ReferenceAttribute valueField = new ReferenceAttribute(source(), "value", DataType.DOUBLE); + ReferenceAttribute tsidField = new ReferenceAttribute(source(), "_tsid", DataType.KEYWORD); + + List functionParams = new ArrayList<>(); + functionParams.add(valueField); + functionParams.add(timestampField); + functionParams.addAll(parameters()); + + Function esqlFunction = PromqlFunctionRegistry.INSTANCE.buildEsqlFunction(functionName(), source(), functionParams); + + String internalName = functionName() + "_$result"; + Alias functionAlias = new Alias(source(), internalName, esqlFunction); + + List groupings = new ArrayList<>(); + groupings.add(tsidField); + + List aggregates = new ArrayList<>(); + aggregates.add(functionAlias); + aggregates.add(tsidField); + + return new TimeSeriesAggregate(source(), childPlan, groupings, aggregates, null); + } + + // @Override + // public String telemetryLabel() { + // return "PROMQL_WITHIN_SERIES_AGGREGATION"; + // } +} diff --git a/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/plan/logical/promql/operator/VectorBinaryOperator.java b/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/plan/logical/promql/operator/VectorBinaryOperator.java new file mode 100644 index 0000000000000..d253457740e3b --- /dev/null +++ b/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/plan/logical/promql/operator/VectorBinaryOperator.java @@ -0,0 +1,183 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +package org.elasticsearch.xpack.esql.plan.logical.promql.operator; + +import org.elasticsearch.common.io.stream.StreamOutput; +import org.elasticsearch.xpack.esql.core.expression.Attribute; +import org.elasticsearch.xpack.esql.core.expression.Expression; +import org.elasticsearch.xpack.esql.core.expression.ReferenceAttribute; +import org.elasticsearch.xpack.esql.core.expression.function.Function; +import org.elasticsearch.xpack.esql.core.tree.Source; +import org.elasticsearch.xpack.esql.core.type.DataType; +import org.elasticsearch.xpack.esql.plan.logical.BinaryPlan; +import org.elasticsearch.xpack.esql.plan.logical.LogicalPlan; +import org.elasticsearch.xpack.esql.plan.logical.promql.selector.LabelMatcher; + +import java.io.IOException; +import java.util.ArrayList; +import java.util.HashSet; +import java.util.List; +import java.util.Objects; +import java.util.Set; + +public abstract class VectorBinaryOperator extends BinaryPlan { + + private final VectorMatch match; + private final boolean dropMetricName; + private final BinaryOp binaryOp; + private List output; + + /** + * Underlying binary operation (e.g. +, -, *, /, etc.) being performed + * on the actual values of the vectors. + */ + public interface BinaryOp { + String name(); + + ScalarFunctionFactory asFunction(); + } + + public interface ScalarFunctionFactory { + Function create(Source source, Expression left, Expression right); + } + + protected VectorBinaryOperator( + Source source, + LogicalPlan left, + LogicalPlan right, + VectorMatch match, + boolean dropMetricName, + BinaryOp binaryOp + ) { + super(source, left, right); + this.match = match; + this.dropMetricName = dropMetricName; + this.binaryOp = binaryOp; + } + + public VectorMatch match() { + return match; + } + + public boolean dropMetricName() { + return dropMetricName; + } + + public BinaryOp binaryOp() { + return binaryOp; + } + + @Override + public List output() { + if (output == null) { + output = computeOutputAttributes(); + } + return output; + } + + private List computeOutputAttributes() { + // TODO: this isn't tested and should be revised + List leftAttrs = left().output(); + List rightAttrs = right().output(); + + Set leftLabels = extractLabelNames(leftAttrs); + Set rightLabels = extractLabelNames(rightAttrs); + + Set outputLabels; + + if (match != null) { + if (match.filter() == VectorMatch.Filter.ON) { + outputLabels = new HashSet<>(match.filterLabels()); + } else if (match.filter() == VectorMatch.Filter.IGNORING) { + outputLabels = new HashSet<>(leftLabels); + outputLabels.addAll(rightLabels); + outputLabels.removeAll(match.filterLabels()); + } else { + outputLabels = new HashSet<>(leftLabels); + outputLabels.retainAll(rightLabels); + } + } else { + outputLabels = new HashSet<>(leftLabels); + outputLabels.retainAll(rightLabels); + } + + if (dropMetricName) { + outputLabels.remove(LabelMatcher.NAME); + } + + List result = new ArrayList<>(); + for (String label : outputLabels) { + Attribute attr = findAttribute(label, leftAttrs, rightAttrs); + if (attr != null) { + result.add(attr); + } + } + + result.add(new ReferenceAttribute(source(), "value", DataType.DOUBLE)); + return result; + } + + private Set extractLabelNames(List attrs) { + Set labels = new HashSet<>(); + for (Attribute attr : attrs) { + String name = attr.name(); + if (name.equals("value") == false) { + labels.add(name); + } + } + return labels; + } + + private Attribute findAttribute(String name, List left, List right) { + for (Attribute attr : left) { + if (attr.name().equals(name)) { + return attr; + } + } + for (Attribute attr : right) { + if (attr.name().equals(name)) { + return attr; + } + } + return null; + } + + @Override + public abstract VectorBinaryOperator replaceChildren(LogicalPlan newLeft, LogicalPlan newRight); + + @Override + public boolean expressionsResolved() { + return true; + } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + if (super.equals(o)) { + VectorBinaryOperator that = (VectorBinaryOperator) o; + return dropMetricName == that.dropMetricName && Objects.equals(match, that.match) && Objects.equals(binaryOp, that.binaryOp); + } + return false; + } + + @Override + public int hashCode() { + return Objects.hash(super.hashCode(), match, dropMetricName, binaryOp); + } + + @Override + public String getWriteableName() { + throw new UnsupportedOperationException("PromQL plans should not be serialized"); + } + + @Override + public void writeTo(StreamOutput out) throws IOException { + throw new UnsupportedOperationException("PromQL plans should not be serialized"); + } +} diff --git a/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/plan/logical/promql/operator/VectorMatch.java b/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/plan/logical/promql/operator/VectorMatch.java new file mode 100644 index 0000000000000..5b488d29778bf --- /dev/null +++ b/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/plan/logical/promql/operator/VectorMatch.java @@ -0,0 +1,87 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +package org.elasticsearch.xpack.esql.plan.logical.promql.operator; + +import java.util.Locale; +import java.util.Objects; +import java.util.Set; + +import static java.util.Collections.emptySet; +import static org.elasticsearch.xpack.esql.core.util.StringUtils.EMPTY; + +public class VectorMatch { + + public enum Filter { + IGNORING, + ON, + NONE + } + + public enum Joining { + LEFT, + RIGHT, + NONE + } + + public static final VectorMatch NONE = new VectorMatch(Filter.NONE, emptySet(), Joining.NONE, emptySet()); + + private final Filter filter; + private final Set filterLabels; + + private final Joining joining; + private final Set groupingLabels; + + public VectorMatch(Filter filter, Set filterLabels, Joining joining, Set groupingLabels) { + this.filter = filter; + this.filterLabels = filterLabels; + this.joining = joining; + this.groupingLabels = groupingLabels; + } + + public Filter filter() { + return filter; + } + + public Set filterLabels() { + return filterLabels; + } + + public Joining grouping() { + return joining; + } + + public Set groupingLabels() { + return groupingLabels; + } + + @Override + public boolean equals(Object o) { + if (super.equals(o)) { + VectorMatch that = (VectorMatch) o; + return filter == that.filter + && Objects.equals(filterLabels, that.filterLabels) + && joining == that.joining + && Objects.equals(groupingLabels, that.groupingLabels); + } + return false; + } + + @Override + public int hashCode() { + return Objects.hash(filter, filterLabels, joining, groupingLabels); + } + + @Override + public String toString() { + String filterString = filter != Filter.NONE ? filter.name().toLowerCase(Locale.ROOT) + "(" + filterLabels + ")" : EMPTY; + String groupingString = joining != Joining.NONE + ? " " + joining.name().toLowerCase(Locale.ROOT) + (groupingLabels.isEmpty() == false ? "(" + groupingLabels + ")" : EMPTY) + " " + : EMPTY; + return filterString + groupingString; + } +} diff --git a/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/plan/logical/promql/operator/arithmetic/VectorBinaryArithmetic.java b/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/plan/logical/promql/operator/arithmetic/VectorBinaryArithmetic.java new file mode 100644 index 0000000000000..27055a1d59608 --- /dev/null +++ b/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/plan/logical/promql/operator/arithmetic/VectorBinaryArithmetic.java @@ -0,0 +1,65 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +package org.elasticsearch.xpack.esql.plan.logical.promql.operator.arithmetic; + +import org.elasticsearch.xpack.esql.core.tree.NodeInfo; +import org.elasticsearch.xpack.esql.core.tree.Source; +import org.elasticsearch.xpack.esql.expression.function.scalar.math.Pow; +import org.elasticsearch.xpack.esql.expression.predicate.operator.arithmetic.Add; +import org.elasticsearch.xpack.esql.expression.predicate.operator.arithmetic.Div; +import org.elasticsearch.xpack.esql.expression.predicate.operator.arithmetic.Mod; +import org.elasticsearch.xpack.esql.expression.predicate.operator.arithmetic.Mul; +import org.elasticsearch.xpack.esql.expression.predicate.operator.arithmetic.Sub; +import org.elasticsearch.xpack.esql.plan.logical.LogicalPlan; +import org.elasticsearch.xpack.esql.plan.logical.promql.operator.VectorBinaryOperator; +import org.elasticsearch.xpack.esql.plan.logical.promql.operator.VectorMatch; + +public class VectorBinaryArithmetic extends VectorBinaryOperator { + + public enum ArithmeticOp implements BinaryOp { + ADD, + SUB, + MUL, + DIV, + MOD, + POW; + + @Override + public ScalarFunctionFactory asFunction() { + return switch (this) { + case ADD -> Add::new; + case SUB -> Sub::new; + case MUL -> Mul::new; + case DIV -> Div::new; + case MOD -> Mod::new; + case POW -> Pow::new; + }; + } + } + + private final ArithmeticOp op; + + public VectorBinaryArithmetic(Source source, LogicalPlan left, LogicalPlan right, VectorMatch match, ArithmeticOp op) { + super(source, left, right, match, true, op); + this.op = op; + } + + public ArithmeticOp op() { + return op; + } + + @Override + public VectorBinaryOperator replaceChildren(LogicalPlan newLeft, LogicalPlan newRight) { + return new VectorBinaryArithmetic(source(), newLeft, newRight, match(), op()); + } + + @Override + protected NodeInfo info() { + return NodeInfo.create(this, VectorBinaryArithmetic::new, left(), right(), match(), op()); + } +} diff --git a/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/plan/logical/promql/operator/comparison/VectorBinaryComparison.java b/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/plan/logical/promql/operator/comparison/VectorBinaryComparison.java new file mode 100644 index 0000000000000..0afbc281c4d62 --- /dev/null +++ b/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/plan/logical/promql/operator/comparison/VectorBinaryComparison.java @@ -0,0 +1,94 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +package org.elasticsearch.xpack.esql.plan.logical.promql.operator.comparison; + +import org.elasticsearch.xpack.esql.core.tree.NodeInfo; +import org.elasticsearch.xpack.esql.core.tree.Source; +import org.elasticsearch.xpack.esql.expression.predicate.operator.comparison.Equals; +import org.elasticsearch.xpack.esql.expression.predicate.operator.comparison.GreaterThan; +import org.elasticsearch.xpack.esql.expression.predicate.operator.comparison.GreaterThanOrEqual; +import org.elasticsearch.xpack.esql.expression.predicate.operator.comparison.LessThan; +import org.elasticsearch.xpack.esql.expression.predicate.operator.comparison.LessThanOrEqual; +import org.elasticsearch.xpack.esql.expression.predicate.operator.comparison.NotEquals; +import org.elasticsearch.xpack.esql.plan.logical.LogicalPlan; +import org.elasticsearch.xpack.esql.plan.logical.promql.operator.VectorBinaryOperator; +import org.elasticsearch.xpack.esql.plan.logical.promql.operator.VectorMatch; + +import java.util.Objects; + +public class VectorBinaryComparison extends VectorBinaryOperator { + + public enum ComparisonOp implements BinaryOp { + EQ, + NEQ, + GT, + GTE, + LT, + LTE; + + @Override + public ScalarFunctionFactory asFunction() { + return switch (this) { + case EQ -> Equals::new; + case NEQ -> NotEquals::new; + case GT -> GreaterThan::new; + case GTE -> GreaterThanOrEqual::new; + case LT -> LessThan::new; + case LTE -> LessThanOrEqual::new; + }; + } + } + + private final ComparisonOp op; + private final boolean boolMode; + + public VectorBinaryComparison( + Source source, + LogicalPlan left, + LogicalPlan right, + VectorMatch match, + boolean boolMode, + ComparisonOp op + ) { + super(source, left, right, match, boolMode == false, op); + this.op = op; + this.boolMode = boolMode; + } + + public ComparisonOp op() { + return op; + } + + public boolean boolMode() { + return boolMode; + } + + @Override + public VectorBinaryOperator replaceChildren(LogicalPlan newLeft, LogicalPlan newRight) { + return new VectorBinaryComparison(source(), newLeft, newRight, match(), boolMode, op()); + } + + @Override + protected NodeInfo info() { + return NodeInfo.create(this, VectorBinaryComparison::new, left(), right(), match(), boolMode(), op()); + } + + @Override + public boolean equals(Object o) { + if (super.equals(o)) { + VectorBinaryComparison that = (VectorBinaryComparison) o; + return boolMode == that.boolMode; + } + return false; + } + + @Override + public int hashCode() { + return Objects.hash(super.hashCode(), boolMode); + } +} diff --git a/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/plan/logical/promql/operator/set/VectorBinarySet.java b/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/plan/logical/promql/operator/set/VectorBinarySet.java new file mode 100644 index 0000000000000..f2c0c73a8d33d --- /dev/null +++ b/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/plan/logical/promql/operator/set/VectorBinarySet.java @@ -0,0 +1,49 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +package org.elasticsearch.xpack.esql.plan.logical.promql.operator.set; + +import org.elasticsearch.xpack.esql.core.tree.NodeInfo; +import org.elasticsearch.xpack.esql.core.tree.Source; +import org.elasticsearch.xpack.esql.plan.logical.LogicalPlan; +import org.elasticsearch.xpack.esql.plan.logical.promql.operator.VectorBinaryOperator; +import org.elasticsearch.xpack.esql.plan.logical.promql.operator.VectorMatch; + +public class VectorBinarySet extends VectorBinaryOperator { + + public enum SetOp implements BinaryOp { + INTERSECT, + SUBTRACT, + UNION; + + @Override + public ScalarFunctionFactory asFunction() { + throw new UnsupportedOperationException("not yet implemented"); + } + } + + private final SetOp op; + + public VectorBinarySet(Source source, LogicalPlan left, LogicalPlan right, VectorMatch match, SetOp op) { + super(source, left, right, match, true, op); + this.op = op; + } + + public SetOp op() { + return op; + } + + @Override + public VectorBinarySet replaceChildren(LogicalPlan newLeft, LogicalPlan newRight) { + return new VectorBinarySet(source(), newLeft, newRight, match(), op()); + } + + @Override + protected NodeInfo info() { + return NodeInfo.create(this, VectorBinarySet::new, left(), right(), match(), op()); + } +} diff --git a/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/plan/logical/promql/selector/Evaluation.java b/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/plan/logical/promql/selector/Evaluation.java new file mode 100644 index 0000000000000..e50013fe0da9f --- /dev/null +++ b/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/plan/logical/promql/selector/Evaluation.java @@ -0,0 +1,92 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +package org.elasticsearch.xpack.esql.plan.logical.promql.selector; + +import org.elasticsearch.xpack.esql.core.expression.Literal; +import org.elasticsearch.xpack.esql.core.tree.Source; +import org.elasticsearch.xpack.esql.core.type.DataType; + +import java.time.Duration; +import java.util.Objects; + +/** + * Evaluation context for a PromQL selector, including the evaluation time and any offset to apply. + * The evaluation time is passed through the promql API while the rest of the parameters through the query + * directly. + * + * <implicit> offset <optional_offset> @ <optional_at> + */ +public class Evaluation { + public static final Evaluation NONE = new Evaluation( + new Literal(Source.EMPTY, Duration.ZERO, DataType.TIME_DURATION), + false, + Literal.NULL + ); + + private final Literal offset; + private final boolean offsetNegative; + private final Literal at; + + public Evaluation(Literal offset, boolean offsetNegative, Literal at) { + this.offset = offset; + this.offsetNegative = offsetNegative; + this.at = at; + } + + public Literal offset() { + return offset; + } + + public Duration offsetDuration() { + return (Duration) offset.value(); + } + + public boolean offsetNegative() { + return offsetNegative; + } + + public Literal at() { + return at; + } + + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } + Evaluation that = (Evaluation) o; + return offsetNegative == that.offsetNegative && Objects.equals(offset, that.offset) && Objects.equals(at, that.at); + } + + @Override + public int hashCode() { + return Objects.hash(offset, offsetNegative, at); + } + + @Override + public String toString() { + StringBuilder sb = new StringBuilder(); + if (offset != null && offsetDuration().isZero() == false) { + sb.append("offset "); + if (offsetNegative) { + sb.append("-"); + } + sb.append(offset); + } + if (at != null) { + if (sb.isEmpty() == false) { + sb.append(" "); + } + sb.append("@ ").append(at); + } + return sb.toString(); + } +} diff --git a/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/plan/logical/promql/selector/InstantSelector.java b/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/plan/logical/promql/selector/InstantSelector.java new file mode 100644 index 0000000000000..6955ff5b81366 --- /dev/null +++ b/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/plan/logical/promql/selector/InstantSelector.java @@ -0,0 +1,104 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +package org.elasticsearch.xpack.esql.plan.logical.promql.selector; + +import org.elasticsearch.xpack.esql.core.expression.Attribute; +import org.elasticsearch.xpack.esql.core.expression.Expression; +import org.elasticsearch.xpack.esql.core.expression.ReferenceAttribute; +import org.elasticsearch.xpack.esql.core.tree.NodeInfo; +import org.elasticsearch.xpack.esql.core.tree.Source; +import org.elasticsearch.xpack.esql.core.type.DataType; +import org.elasticsearch.xpack.esql.plan.logical.LogicalPlan; +import org.elasticsearch.xpack.esql.plan.logical.promql.PlaceholderRelation; + +import java.util.List; + +/** + * Represents a PromQL instant vector selector. + * + * An instant vector selects time series based on metric name and label matchers, + * returning the most recent sample at the evaluation timestamp. This corresponds to PromQL syntax: + * metric_name{label="value"} offset 5m @ timestamp + * + * Examples: + * http_requests_total + * cpu_usage{host="web-1"} + * memory_used{env=~"prod.*"} offset 10m + * up{job="prometheus"} @ 1609746000 + * + * The instant vector selects a single sample per matching time series at the + * evaluation time (with optional offset/@ modifiers), representing the current state. + * + * Conceptually an instant selector is a range selector with a null range. + */ +public class InstantSelector extends Selector { + + public InstantSelector(Source source, Expression series, List labels, LabelMatchers labelMatchers, Evaluation evaluation) { + this(source, PlaceholderRelation.INSTANCE, series, labels, labelMatchers, evaluation); + } + + public InstantSelector( + Source source, + LogicalPlan child, + Expression series, + List labels, + LabelMatchers labelMatchers, + Evaluation evaluation + ) { + super(source, child, series, labels, labelMatchers, evaluation); + } + + @Override + protected NodeInfo info() { + return NodeInfo.create(this, InstantSelector::new, child(), series(), labels(), labelMatchers(), evaluation()); + } + + @Override + public InstantSelector replaceChild(LogicalPlan newChild) { + return new InstantSelector(source(), newChild, series(), labels(), labelMatchers(), evaluation()); + } + + // @Override + // public String telemetryLabel() { + // return "PROMQL_SELECTOR_INSTANT"; + // } + + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } + return super.equals(o); + } + + /** + * InstantSelector outputs three columns representing time series data: + * 1. labels - The metric name and all label key-value pairs + * 2. timestamp - The sample timestamp in milliseconds since epoch + * 3. value - The metric value + */ + @Override + public List output() { + if (output == null) { + output = List.of( + new ReferenceAttribute(source(), "promql$labels", DataType.KEYWORD), + new ReferenceAttribute(source(), "promql$timestamp", DataType.DATETIME), + new ReferenceAttribute(source(), "promql$value", DataType.DOUBLE) + ); + } + return output; + } + + @Override + public int hashCode() { + return super.hashCode(); + } +} diff --git a/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/plan/logical/promql/selector/LabelMatcher.java b/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/plan/logical/promql/selector/LabelMatcher.java new file mode 100644 index 0000000000000..17468e78108ed --- /dev/null +++ b/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/plan/logical/promql/selector/LabelMatcher.java @@ -0,0 +1,149 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +package org.elasticsearch.xpack.esql.plan.logical.promql.selector; + +import org.apache.lucene.util.automaton.Automata; +import org.apache.lucene.util.automaton.Automaton; +import org.apache.lucene.util.automaton.Operations; +import org.apache.lucene.util.automaton.RegExp; +import org.elasticsearch.lucene.util.automaton.MinimizationOperations; +import org.elasticsearch.xpack.esql.core.QlIllegalArgumentException; + +import java.util.Objects; + +import static org.elasticsearch.xpack.esql.core.util.StringUtils.EMPTY; +import static org.elasticsearch.xpack.esql.plan.logical.promql.selector.LabelMatcher.Matcher.NEQ; +import static org.elasticsearch.xpack.esql.plan.logical.promql.selector.LabelMatcher.Matcher.NREG; + +/** + * PromQL label matcher between a label name, a value pattern and match type (=, !=, =~, !~). + * + * Examples: + * {job="api"} → [LabelMatcher("job", "api", EQ)] + * {status=~"5.."} → [LabelMatcher("status", "5..", REG)] + * {env!~"test|dev"} → [LabelMatcher("env", "test|dev", NREG)] + */ +public class LabelMatcher { + + public static final String NAME = "__name__"; + + public enum Matcher { + EQ("=", false), + NEQ("!=", false), + REG("=~", true), + NREG("!~", true); + + public static Matcher from(String value) { + switch (value) { + case "=": + return EQ; + case "!=": + return NEQ; + case "=~": + return REG; + case "!~": + return NREG; + default: + return null; + } + } + + private final String value; + private final boolean isRegex; + + Matcher(String value, boolean isRegex) { + this.value = value; + this.isRegex = isRegex; + } + + public boolean isRegex() { + return isRegex; + } + } + + private final String name; + private final String value; + private final Matcher matcher; + + private Automaton automaton; + + public LabelMatcher(String name, String value, Matcher matcher) { + this.name = name; + this.value = value; + this.matcher = matcher; + } + + public String name() { + return name; + } + + public String value() { + return value; + } + + public Matcher matcher() { + return matcher; + } + + public Automaton automaton() { + if (automaton == null) { + automaton = automaton(value, matcher); + } + return automaton; + } + + // TODO: externalize this to allow pluggable strategies (such as caching across labels/requests) + private static Automaton automaton(String value, Matcher matcher) { + Automaton automaton; + try { + automaton = matcher.isRegex ? new RegExp(value).toAutomaton() : Automata.makeString(value); + automaton = MinimizationOperations.minimize(automaton, Operations.DEFAULT_DETERMINIZE_WORK_LIMIT); + } catch (IllegalArgumentException ex) { + throw new QlIllegalArgumentException(ex, "Cannot parse regex {}", value); + } + // negate if needed + if (matcher == NEQ || matcher == NREG) { + automaton = Operations.complement(automaton, Operations.DEFAULT_DETERMINIZE_WORK_LIMIT); + } + return automaton; + } + + public boolean matchesAll() { + return Operations.isTotal(automaton()); + } + + public boolean matchesNone() { + return Operations.isEmpty(automaton()); + } + + public boolean matchesEmpty() { + return Operations.run(automaton(), EMPTY); + } + + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } + LabelMatcher label = (LabelMatcher) o; + return matcher == label.matcher && Objects.equals(name, label.name) && Objects.equals(value, label.value); + } + + @Override + public int hashCode() { + return Objects.hash(name, value, matcher); + } + + @Override + public String toString() { + return name + matcher.value + value; + } +} diff --git a/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/plan/logical/promql/selector/LabelMatchers.java b/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/plan/logical/promql/selector/LabelMatchers.java new file mode 100644 index 0000000000000..96e98a1e14aae --- /dev/null +++ b/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/plan/logical/promql/selector/LabelMatchers.java @@ -0,0 +1,78 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +package org.elasticsearch.xpack.esql.plan.logical.promql.selector; + +import org.elasticsearch.common.util.Maps; + +import java.util.List; +import java.util.Map; +import java.util.Objects; + +import static java.util.Collections.emptyList; +import static java.util.Collections.emptyMap; + +/** + * Immutable collection of label matchers for a PromQL selector. + */ +public class LabelMatchers { + /** + * Empty label matchers for literal selectors and other cases with no label constraints. + */ + public static final LabelMatchers EMPTY = new LabelMatchers(emptyList()); + + private final List labelMatchers; + private final Map nameToMatcher; + + public LabelMatchers(List labelMatchers) { + Objects.requireNonNull(labelMatchers, "label matchers cannot be null"); + this.labelMatchers = labelMatchers; + int size = labelMatchers.size(); + if (size == 0) { + nameToMatcher = emptyMap(); + } else { + nameToMatcher = Maps.newLinkedHashMapWithExpectedSize(size); + for (LabelMatcher lm : labelMatchers) { + nameToMatcher.put(lm.name(), lm); + } + } + } + + public List matchers() { + return labelMatchers; + } + + public LabelMatcher nameLabel() { + return nameToMatcher.get(LabelMatcher.NAME); + } + + public boolean isEmpty() { + return labelMatchers.isEmpty(); + } + + @Override + public int hashCode() { + return Objects.hash(labelMatchers); + } + + @Override + public boolean equals(Object obj) { + if (this == obj) { + return true; + } + if (obj == null || getClass() != obj.getClass()) { + return false; + } + LabelMatchers other = (LabelMatchers) obj; + return Objects.equals(labelMatchers, other.labelMatchers); + } + + @Override + public String toString() { + return labelMatchers.toString(); + } +} diff --git a/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/plan/logical/promql/selector/LiteralSelector.java b/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/plan/logical/promql/selector/LiteralSelector.java new file mode 100644 index 0000000000000..cbcb8eb4a6caf --- /dev/null +++ b/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/plan/logical/promql/selector/LiteralSelector.java @@ -0,0 +1,110 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +package org.elasticsearch.xpack.esql.plan.logical.promql.selector; + +import org.elasticsearch.xpack.esql.core.expression.Attribute; +import org.elasticsearch.xpack.esql.core.expression.Literal; +import org.elasticsearch.xpack.esql.core.expression.ReferenceAttribute; +import org.elasticsearch.xpack.esql.core.tree.NodeInfo; +import org.elasticsearch.xpack.esql.core.tree.Source; +import org.elasticsearch.xpack.esql.core.type.DataType; +import org.elasticsearch.xpack.esql.plan.logical.LogicalPlan; +import org.elasticsearch.xpack.esql.plan.logical.promql.PlaceholderRelation; + +import java.util.List; +import java.util.Objects; + +import static java.util.Collections.emptyList; + +/** + * Represents a PromQL literal scalar value wrapped as a vector selector. + * + * In PromQL, literal numeric values can be used as instant vectors where each + * sample in the result has the same scalar value with no labels. This corresponds + * to PromQL syntax like: + * 42 + * 3.14 + * -5.5 + * + * Examples: + * http_requests_total + 10 // Add 10 to each sample + * cpu_usage * 100 // Multiply by 100 + * rate(requests[5m]) > 0.5 // Compare against threshold + * + * The literal selector produces a single-value vector with no labels, allowing + * literals to participate in vector operations and binary expressions. + */ +public class LiteralSelector extends Selector { + private final Literal literal; + + public LiteralSelector(Source source, Literal literal) { + this(source, PlaceholderRelation.INSTANCE, literal); + } + + public LiteralSelector(Source source, LogicalPlan child, Literal literal) { + super(source, child, literal, emptyList(), LabelMatchers.EMPTY, Evaluation.NONE); + this.literal = literal; + } + + public Literal literal() { + return literal; + } + + @Override + protected NodeInfo info() { + return NodeInfo.create(this, LiteralSelector::new, child(), literal); + } + + @Override + public LiteralSelector replaceChild(LogicalPlan newChild) { + return new LiteralSelector(source(), newChild, literal); + } + + // @Override + public String telemetryLabel() { + return "PROMQL_SELECTOR_LITERAL"; + } + + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } + if (super.equals(o) == false) { + return false; + } + LiteralSelector that = (LiteralSelector) o; + return Objects.equals(literal, that.literal); + } + + /** + * LiteralSelector outputs three columns representing a scalar vector: + * 0. labels - Empty (no labels for scalar values) + * 1. timestamp - The evaluation timestamp + * 2. value - The literal scalar value + */ + @Override + public List output() { + if (output == null) { + output = List.of( + new ReferenceAttribute(source(), "promql$labels", DataType.KEYWORD), + new ReferenceAttribute(source(), "promql$timestamp", DataType.DATETIME), + new ReferenceAttribute(source(), "promql$value", DataType.DOUBLE) + ); + } + return output; + } + + @Override + public int hashCode() { + return Objects.hash(super.hashCode(), literal); + } +} diff --git a/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/plan/logical/promql/selector/RangeSelector.java b/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/plan/logical/promql/selector/RangeSelector.java new file mode 100644 index 0000000000000..f4d51ea92be87 --- /dev/null +++ b/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/plan/logical/promql/selector/RangeSelector.java @@ -0,0 +1,123 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +package org.elasticsearch.xpack.esql.plan.logical.promql.selector; + +import org.elasticsearch.xpack.esql.core.expression.Attribute; +import org.elasticsearch.xpack.esql.core.expression.Expression; +import org.elasticsearch.xpack.esql.core.expression.ReferenceAttribute; +import org.elasticsearch.xpack.esql.core.tree.NodeInfo; +import org.elasticsearch.xpack.esql.core.tree.Source; +import org.elasticsearch.xpack.esql.core.type.DataType; +import org.elasticsearch.xpack.esql.plan.logical.LogicalPlan; +import org.elasticsearch.xpack.esql.plan.logical.promql.PlaceholderRelation; + +import java.util.List; +import java.util.Objects; + +/** + * Represents a PromQL range vector selector. + * + * A range vector selects time series based on metric name and label matchers, + * with a lookback time range. This corresponds to PromQL syntax: + * metric_name{label="value"}[duration] offset 5m @ timestamp + * + * Examples: + * http_requests_total[5m] + * cpu_usage{host="web-1"}[1h] + * memory_used{env=~"prod.*"}[30m] offset 10m + * + * The range vector selects all samples within the specified duration for each + * matching time series, preparing data for range functions like rate() or avg_over_time(). + */ +public class RangeSelector extends Selector { + // Time_Period or Duration + private final Expression range; + + public RangeSelector( + Source source, + Expression series, + List labels, + LabelMatchers labelMatchers, + Expression range, + Evaluation evaluation + ) { + this(source, PlaceholderRelation.INSTANCE, series, labels, labelMatchers, range, evaluation); + } + + public RangeSelector( + Source source, + LogicalPlan child, + Expression series, + List labels, + LabelMatchers labelMatchers, + Expression range, + Evaluation evaluation + ) { + super(source, child, series, labels, labelMatchers, evaluation); + this.range = range; + } + + public Expression range() { + return range; + } + + @Override + protected NodeInfo info() { + return NodeInfo.create(this, RangeSelector::new, child(), series(), labels(), labelMatchers(), range, evaluation()); + } + + @Override + public RangeSelector replaceChild(LogicalPlan newChild) { + return new RangeSelector(source(), newChild, series(), labels(), labelMatchers(), range, evaluation()); + } + + // @Override + // public String telemetryLabel() { + // return "PROMQL_SELECTOR_RANGE"; + // } + + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } + if (super.equals(o) == false) { + return false; + } + RangeSelector that = (RangeSelector) o; + return Objects.equals(range, that.range); + } + + /** + * RangeSelector outputs three columns representing time series data: + * 0. range - the step instance for the given interval + * 1. labels - The metric name and all label key-value pairs + * 2. timestamp - The sample timestamp in milliseconds since epoch + * 3. value - The metric value + */ + @Override + public List output() { + if (output == null) { + output = List.of( + new ReferenceAttribute(source(), "promql$range", DataType.DATETIME), + new ReferenceAttribute(source(), "promql$labels", DataType.KEYWORD), + new ReferenceAttribute(source(), "promql$timestamp", DataType.DATETIME), + new ReferenceAttribute(source(), "promql$value", DataType.DOUBLE) + ); + } + return output; + } + + @Override + public int hashCode() { + return Objects.hash(super.hashCode(), range); + } +} diff --git a/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/plan/logical/promql/selector/Selector.java b/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/plan/logical/promql/selector/Selector.java new file mode 100644 index 0000000000000..b3eca00565fb7 --- /dev/null +++ b/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/plan/logical/promql/selector/Selector.java @@ -0,0 +1,103 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +package org.elasticsearch.xpack.esql.plan.logical.promql.selector; + +import org.elasticsearch.common.io.stream.StreamOutput; +import org.elasticsearch.xpack.esql.core.capabilities.Resolvables; +import org.elasticsearch.xpack.esql.core.expression.Attribute; +import org.elasticsearch.xpack.esql.core.expression.Expression; +import org.elasticsearch.xpack.esql.core.tree.Source; +import org.elasticsearch.xpack.esql.plan.logical.LogicalPlan; +import org.elasticsearch.xpack.esql.plan.logical.UnaryPlan; +import org.elasticsearch.xpack.esql.plan.logical.promql.PlaceholderRelation; + +import java.io.IOException; +import java.util.List; +import java.util.Objects; + +/** + * Base class representing a PromQL vector selector. + * A vector selector is defined by a set of label matchers and a point in time evaluation context. + */ +public abstract class Selector extends UnaryPlan { + // implements TelemetryAware + + // in Promql this is the __name__ label however for now, this gets mapped to an exact field + private final Expression series; + private final List labels; + private final LabelMatchers labelMatchers; + private final Evaluation evaluation; + protected List output; + + Selector(Source source, Expression series, List labels, LabelMatchers labelMatchers, Evaluation evaluation) { + this(source, PlaceholderRelation.INSTANCE, series, labels, labelMatchers, evaluation); + } + + Selector( + Source source, + LogicalPlan child, + Expression series, + List labels, + LabelMatchers labelMatchers, + Evaluation evaluation + ) { + super(source, child); + this.series = series; + this.labels = labels; + this.labelMatchers = labelMatchers; + this.evaluation = evaluation; + } + + public Expression series() { + return series; + } + + public List labels() { + return labels; + } + + public LabelMatchers labelMatchers() { + return labelMatchers; + } + + public Evaluation evaluation() { + return evaluation; + } + + @Override + public boolean expressionsResolved() { + return series.resolved() && Resolvables.resolved(labels); + } + + @Override + public boolean equals(Object o) { + if (super.equals(o)) { + Selector selector = (Selector) o; + return Objects.equals(evaluation, selector.evaluation) + && Objects.equals(labelMatchers, selector.labelMatchers) + && Objects.equals(series, selector.series) + && Objects.equals(labels, selector.labels); + } + return false; + } + + @Override + public int hashCode() { + return Objects.hash(super.hashCode(), series, labels, labelMatchers, evaluation); + } + + @Override + public String getWriteableName() { + throw new UnsupportedOperationException("should not serialize"); + } + + @Override + public void writeTo(StreamOutput out) throws IOException { + throw new UnsupportedOperationException("should not serialize"); + } +} diff --git a/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/telemetry/FeatureMetric.java b/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/telemetry/FeatureMetric.java index 125a104aee0c9..13537a977ee31 100644 --- a/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/telemetry/FeatureMetric.java +++ b/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/telemetry/FeatureMetric.java @@ -40,6 +40,7 @@ import org.elasticsearch.xpack.esql.plan.logical.inference.Rerank; import org.elasticsearch.xpack.esql.plan.logical.join.LookupJoin; import org.elasticsearch.xpack.esql.plan.logical.local.EsqlProject; +import org.elasticsearch.xpack.esql.plan.logical.promql.PromqlCommand; import org.elasticsearch.xpack.esql.plan.logical.show.ShowInfo; import java.util.BitSet; @@ -77,7 +78,8 @@ public enum FeatureMetric { FUSE(Fuse.class::isInstance), COMPLETION(Completion.class::isInstance), SAMPLE(Sample.class::isInstance), - SUBQUERY(Subquery.class::isInstance); + SUBQUERY(Subquery.class::isInstance), + PROMQL(PromqlCommand.class::isInstance); /** * List here plans we want to exclude from telemetry diff --git a/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/CsvTests.java b/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/CsvTests.java index fd7cbfb6fa723..8841be5023343 100644 --- a/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/CsvTests.java +++ b/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/CsvTests.java @@ -359,6 +359,10 @@ public final void test() throws Throwable { "CSV tests cannot currently handle CHUNK function", testCase.requiredCapabilities.contains(EsqlCapabilities.Cap.CHUNK_FUNCTION.capabilityName()) ); + assumeFalse( + "can't use PromQL in csv tests", + testCase.requiredCapabilities.contains(EsqlCapabilities.Cap.PROMQL_V0.capabilityName()) + ); if (Build.current().isSnapshot()) { assertThat( diff --git a/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/analysis/VerifierTests.java b/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/analysis/VerifierTests.java index 1de00620b898b..12b904a5cbd28 100644 --- a/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/analysis/VerifierTests.java +++ b/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/analysis/VerifierTests.java @@ -3375,7 +3375,7 @@ private String error(String query, Object... params) { return error(query, defaultAnalyzer, VerificationException.class, params); } - private String error(String query, Analyzer analyzer, Object... params) { + public static String error(String query, Analyzer analyzer, Object... params) { return error(query, analyzer, VerificationException.class, params); } @@ -3383,7 +3383,7 @@ private String error(String query, TransportVersion transportVersion, Object... return error(query, transportVersion, VerificationException.class, params); } - private String error(String query, Analyzer analyzer, Class exception, Object... params) { + public static String error(String query, Analyzer analyzer, Class exception, Object... params) { List parameters = new ArrayList<>(); for (Object param : params) { if (param == null) { diff --git a/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/analysis/promql/PromqlVerifierTests.java b/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/analysis/promql/PromqlVerifierTests.java new file mode 100644 index 0000000000000..828d10fc3af2f --- /dev/null +++ b/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/analysis/promql/PromqlVerifierTests.java @@ -0,0 +1,140 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +package org.elasticsearch.xpack.esql.analysis.promql; + +import org.elasticsearch.test.ESTestCase; +import org.elasticsearch.xpack.esql.action.PromqlFeatures; +import org.elasticsearch.xpack.esql.analysis.Analyzer; +import org.elasticsearch.xpack.esql.analysis.AnalyzerTestUtils; +import org.junit.BeforeClass; + +import java.util.List; + +import static org.elasticsearch.xpack.esql.EsqlTestUtils.withDefaultLimitWarning; +import static org.elasticsearch.xpack.esql.analysis.VerifierTests.error; +import static org.hamcrest.Matchers.equalTo; +import static org.junit.Assume.assumeTrue; + +public class PromqlVerifierTests extends ESTestCase { + + private final Analyzer tsdb = AnalyzerTestUtils.analyzer(AnalyzerTestUtils.tsdbIndexResolution()); + + @BeforeClass + public static void checkPromqlEnabled() { + assumeTrue("requires snapshot build with promql feature enabled", PromqlFeatures.isEnabled()); + } + + public void testPromqlMissingAcrossSeriesAggregation() { + assertThat( + error(""" + TS test | PROMQL step 5m ( + rate(network.bytes_in[5m]) + )""", tsdb), + equalTo("2:3: only aggregations across timeseries are supported at this time (found [rate(network.bytes_in[5m])])") + ); + } + + public void testPromqlStepAndRangeMisaligned() { + assertThat( + error(""" + TS test | PROMQL step 1m ( + avg(rate(network.bytes_in[5m])) + )""", tsdb), + equalTo("2:29: the duration for range vector selector [5m] must be equal to the query's step for range queries at this time") + ); + } + + public void testPromqlIllegalNameLabelMatcher() { + assertThat( + error("TS test | PROMQL step 5m (avg({__name__=~\"*.foo.*\"}))", tsdb), + equalTo("1:31: regex label selectors on __name__ are not supported at this time [{__name__=~\"*.foo.*\"}]") + ); + } + + public void testPromqlSubquery() { + assertThat( + error("TS test | PROMQL step 5m (avg(rate(network.bytes_in[5m:])))", tsdb), + equalTo("1:36: subqueries are not supported at this time [network.bytes_in[5m:]]") + ); + assertThat( + error("TS test | PROMQL step 5m (avg(rate(network.bytes_in[5m:1m])))", tsdb), + equalTo("1:36: subqueries are not supported at this time [network.bytes_in[5m:1m]]") + ); + } + + @AwaitsFix( + bugUrl = "Doesn't parse: line 1:27: Invalid query '1+1'[ArithmeticBinaryContext] given; " + + "expected LogicalPlan but found VectorBinaryArithmetic" + ) + public void testPromqlArithmetricOperators() { + assertThat( + error("TS test | PROMQL step 5m (1+1)", tsdb), + equalTo("1:27: arithmetic operators are not supported at this time [foo]") + ); + assertThat( + error("TS test | PROMQL step 5m (foo+1)", tsdb), + equalTo("1:27: arithmetic operators are not supported at this time [foo]") + ); + assertThat( + error("TS test | PROMQL step 5m (1+foo)", tsdb), + equalTo("1:27: arithmetic operators are not supported at this time [foo]") + ); + assertThat( + error("TS test | PROMQL step 5m (foo+bar)", tsdb), + equalTo("1:27: arithmetic operators are not supported at this time [foo]") + ); + } + + @AwaitsFix( + bugUrl = "Doesn't parse: line 1:27: Invalid query 'method_code_http_errors_rate5m{code=\"500\"}'" + + "[ValueExpressionContext] given; expected Expression but found InstantSelector" + ) + public void testPromqlVectorMatching() { + assertThat( + error( + "TS test | PROMQL step 5m (method_code_http_errors_rate5m{code=\"500\"} / ignoring(code) method_http_requests_rate5m)", + tsdb + ), + equalTo("") + ); + assertThat( + error( + "TS test | PROMQL step 5m (method_code_http_errors_rate5m / ignoring(code) group_left method_http_requests_rate5m)", + tsdb + ), + equalTo("") + ); + } + + public void testPromqlModifier() { + assertThat( + error("TS test | PROMQL step 5m (avg(rate(network.bytes_in[5m] offset 5m)))", tsdb), + equalTo("1:36: offset modifiers are not supported at this time [network.bytes_in[5m] offset 5m]") + ); + /* TODO + assertThat( + error("TS test | PROMQL step 5m (foo @ start())", tsdb), + equalTo("1:27: @ modifiers are not supported at this time [foo @ start()]") + );*/ + } + + @AwaitsFix( + bugUrl = "Doesn't parse: line 1:27: Invalid query 'foo and bar'[LogicalBinaryContext] given; " + + "expected Expression but found InstantSelector" + ) + public void testLogicalSetBinaryOperators() { + assertThat(error("TS test | PROMQL step 5m (foo and bar)", tsdb), equalTo("")); + assertThat(error("TS test | PROMQL step 5m (foo or bar)", tsdb), equalTo("")); + assertThat(error("TS test | PROMQL step 5m (foo unless bar)", tsdb), equalTo("")); + } + + @Override + protected List filteredWarnings() { + return withDefaultLimitWarning(super.filteredWarnings()); + } +} diff --git a/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/optimizer/promql/PromqlLogicalPlanOptimizerTests.java b/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/optimizer/promql/PromqlLogicalPlanOptimizerTests.java new file mode 100644 index 0000000000000..0f2f4fba25fef --- /dev/null +++ b/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/optimizer/promql/PromqlLogicalPlanOptimizerTests.java @@ -0,0 +1,575 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +package org.elasticsearch.xpack.esql.optimizer.promql; + +import org.elasticsearch.TransportVersion; +import org.elasticsearch.index.IndexMode; +import org.elasticsearch.xpack.esql.EsqlTestUtils; +import org.elasticsearch.xpack.esql.action.PromqlFeatures; +import org.elasticsearch.xpack.esql.analysis.Analyzer; +import org.elasticsearch.xpack.esql.analysis.AnalyzerContext; +import org.elasticsearch.xpack.esql.core.expression.Alias; +import org.elasticsearch.xpack.esql.core.expression.FoldContext; +import org.elasticsearch.xpack.esql.core.expression.predicate.regex.RegexMatch; +import org.elasticsearch.xpack.esql.core.tree.Source; +import org.elasticsearch.xpack.esql.expression.function.EsqlFunctionRegistry; +import org.elasticsearch.xpack.esql.expression.function.grouping.Bucket; +import org.elasticsearch.xpack.esql.expression.function.scalar.string.StartsWith; +import org.elasticsearch.xpack.esql.expression.predicate.logical.And; +import org.elasticsearch.xpack.esql.expression.predicate.nulls.IsNotNull; +import org.elasticsearch.xpack.esql.expression.predicate.operator.comparison.In; +import org.elasticsearch.xpack.esql.expression.predicate.operator.comparison.NotEquals; +import org.elasticsearch.xpack.esql.index.EsIndex; +import org.elasticsearch.xpack.esql.index.IndexResolution; +import org.elasticsearch.xpack.esql.optimizer.AbstractLogicalPlanOptimizerTests; +import org.elasticsearch.xpack.esql.plan.IndexPattern; +import org.elasticsearch.xpack.esql.plan.logical.Aggregate; +import org.elasticsearch.xpack.esql.plan.logical.EsRelation; +import org.elasticsearch.xpack.esql.plan.logical.Eval; +import org.elasticsearch.xpack.esql.plan.logical.Filter; +import org.elasticsearch.xpack.esql.plan.logical.LogicalPlan; +import org.elasticsearch.xpack.esql.plan.logical.Project; +import org.elasticsearch.xpack.esql.plan.logical.TimeSeriesAggregate; +import org.elasticsearch.xpack.esql.plan.logical.TopN; +import org.junit.BeforeClass; + +import java.time.Duration; +import java.time.Instant; +import java.time.temporal.ChronoUnit; +import java.util.List; +import java.util.Map; + +import static java.util.Collections.emptyMap; +import static org.elasticsearch.xpack.esql.EsqlTestUtils.TEST_VERIFIER; +import static org.elasticsearch.xpack.esql.EsqlTestUtils.as; +import static org.elasticsearch.xpack.esql.EsqlTestUtils.emptyInferenceResolution; +import static org.elasticsearch.xpack.esql.EsqlTestUtils.loadMapping; +import static org.hamcrest.Matchers.equalTo; +import static org.hamcrest.Matchers.hasSize; +import static org.hamcrest.Matchers.instanceOf; +import static org.junit.Assume.assumeTrue; + +// @TestLogging(value = "org.elasticsearch.xpack.esql:TRACE", reason = "debug tests") +public class PromqlLogicalPlanOptimizerTests extends AbstractLogicalPlanOptimizerTests { + + private static final String PARAM_FORMATTING = "%1$s"; + + private static Analyzer tsAnalyzer; + + @BeforeClass + public static void initTest() { + assumeTrue("requires snapshot build with promql feature enabled", PromqlFeatures.isEnabled()); + + var timeSeriesMapping = loadMapping("k8s-mappings.json"); + var timeSeriesIndex = IndexResolution.valid(new EsIndex("k8s", timeSeriesMapping, Map.of("k8s", IndexMode.TIME_SERIES))); + tsAnalyzer = new Analyzer( + new AnalyzerContext( + EsqlTestUtils.TEST_CFG, + new EsqlFunctionRegistry(), + Map.of(new IndexPattern(Source.EMPTY, "k8s"), timeSeriesIndex), + emptyMap(), + enrichResolution, + emptyInferenceResolution(), + TransportVersion.current() + ), + TEST_VERIFIER + ); + } + + public void testExplainPromql() { + // TS metrics-hostmetricsreceiver.otel-default + // | WHERE @timestamp >= \"{{from | minus .benchmark.duration}}\" AND @timestamp <=\"{{from}}\" + // | STATS AVG(AVG_OVER_TIME(`metrics.system.memory.utilization`)) BY host.name, TBUCKET(1h) | LIMIT 10000" + var plan = planPromql(""" + EXPLAIN ( + TS k8s + | promql step 5m ( avg by (pod) (avg_over_time(network.bytes_in{pod=~"host-0|host-1|host-2"}[1h])) ) + | LIMIT 1000 + ) + """); + + logger.trace(plan); + } + + public void testExplainPromqlSimple() { + // TS metrics-hostmetricsreceiver.otel-default + // | WHERE @timestamp >= \"{{from | minus .benchmark.duration}}\" AND @timestamp <=\"{{from}}\" + // | STATS AVG(AVG_OVER_TIME(`metrics.system.memory.utilization`)) BY host.name, TBUCKET(1h) | LIMIT 10000" + var plan = planPromql(""" + TS k8s + | WHERE TRANGE($now-1h, $now) + | STATS AVG(AVG_OVER_TIME(network.bytes_in)) BY TBUCKET(1h) + """); + + logger.trace(plan); + } + + /** + * Explain the following logical plan + * + * Project[[avg by (pod) (avg_over_time(network.bytes_in{pod=~"host-0|host-1|host-2"}[1h])){r}#72, pod{r}#48, TBUCKET{r}# + * 73]] + * \_TopN[[Order[TBUCKET{r}#73,ASC,FIRST]],1000[INTEGER],false] + * \_Eval[[$$SUM$avg by (pod) (avg_over_time(network.bytes_in{pod=~"host-0|host-1|host-2"}[1h]))$0{r$}#81 / $$COUNT$avg + * by (pod) (avg_over_time(network.bytes_in{pod=~"host-0|host-1|host-2"}[1h]))$1{r$}#82 AS avg by (pod) + * (avg_over_time(network.bytes_in{pod=~"host-0|host-1|host-2"}[1h]))#72, UNPACKDIMENSION(grouppod_$1{r}#78) AS pod#48]] + * \_Aggregate[[packpod_$1{r}#77, TBUCKET{r}#73],[SUM(AVGOVERTIME_$1{r}#75,true[BOOLEAN],PT0S[TIME_DURATION],compensated[KEYWO + * RD]) AS $$SUM$avg by (pod) (avg_over_time(network.bytes_in{pod=~"host-0|host-1|host-2"}[1h]))$0#81, + * COUNT(AVGOVERTIME_$1{r}#75,true[BOOLEAN],PT0S[TIME_DURATION]) AS $$COUNT$avg by (pod) + * (avg_over_time(network.bytes_in{pod=~"host-0|host-1|host-2"}[1h]))$1#82, packpod_$1{r}#77 AS grouppod_$1#78, + * TBUCKET{r}#73 AS TBUCKET#73]] + * \_Eval[[$$SUM$AVGOVERTIME_$1$0{r$}#79 / $$COUNT$AVGOVERTIME_$1$1{r$}#80 AS AVGOVERTIME_$1#75, PACKDIMENSION(pod{r}#76 + * ) AS packpod_$1#77]] + * \_TimeSeriesAggregate[[_tsid{m}#74, TBUCKET{r}#73], + * [SUM(network.bytes_in{f}#60,true[BOOLEAN],PT0S[TIME_DURATION],lossy[KEYWORD]) AS $ + * $SUM$AVGOVERTIME_$1$0#79, COUNT(network.bytes_in{f}#60,true[BOOLEAN],PT0S[TIME_DURATION]) AS $$COUNT$AVGOVERTIME_$1$1#80, + * VALUES(pod{f}#48,true[BOOLEAN],PT0S[TIME_DURATION]) AS pod#76, TBUCKET{r}#73], + * BUCKET(@timestamp{f}#46,PT1H[TIME_DURATION])] + * \_Eval[[BUCKET(@timestamp{f}#46,PT1H[TIME_DURATION]) AS TBUCKET#73]] + * \_Filter[ISNOTNULL(network.bytes_in{f}#60) AND IN(host-0[KEYWORD],host-1[KEYWORD],host-2[KEYWORD],pod{f}#48)] + * \_EsRelation[k8s][@timestamp{f}#46, client.ip{f}#50, cluster{f}#47, e..] + */ + public void testAvgAvgOverTimeOutput() { + // TS metrics-hostmetricsreceiver.otel-default + // | WHERE @timestamp >= \"{{from | minus .benchmark.duration}}\" AND @timestamp <=\"{{from}}\" + // | STATS AVG(AVG_OVER_TIME(`metrics.system.memory.utilization`)) BY host.name, TBUCKET(1h) | LIMIT 10000" + var plan = planPromql(""" + TS k8s + | promql step 1h ( avg by (pod) (avg_over_time(network.bytes_in{pod=~"host-0|host-1|host-2"}[1h])) ) + | LIMIT 1000 + """); + + logger.trace(plan); + + var project = as(plan, Project.class); + assertThat(project.projections(), hasSize(3)); + + var topN = as(project.child(), TopN.class); + assertThat(topN.order(), hasSize(1)); + + var evalOuter = as(topN.child(), Eval.class); + + var aggregate = as(evalOuter.child(), Aggregate.class); + assertThat(aggregate.groupings(), hasSize(2)); + + var evalMiddle = as(aggregate.child(), Eval.class); + + var tsAggregate = as(evalMiddle.child(), TimeSeriesAggregate.class); + assertThat(tsAggregate.groupings(), hasSize(2)); + + // verify TBUCKET duration plus reuse + var evalBucket = as(tsAggregate.child(), Eval.class); + assertThat(evalBucket.fields(), hasSize(1)); + var bucketAlias = as(evalBucket.fields().get(0), Alias.class); + var bucket = as(bucketAlias.child(), Bucket.class); + + var bucketSpan = bucket.buckets(); + assertThat(bucketSpan.fold(FoldContext.small()), equalTo(Duration.ofHours(1))); + + var tbucketId = bucketAlias.toAttribute().id(); + + // Verify TBUCKET is used as timeBucket in TimeSeriesAggregate + // FIXME: looks like we're creating multiple time buckets (one in Eval, one in TSAggregate) + + // var timeBucket = tsAggregate.timeBucket(); + // assertNotNull(timeBucket); + // assertThat(Expressions.attribute(timeBucket).id(), equalTo(tbucketId)); + + // assertThat(Expressions.attribute(tsAggregate.groupings().get(0)).id(), equalTo(tbucketId)); + + // assertThat(Expressions.attribute(aggregate.groupings().get(1)).id(), equalTo(tbucketId)); + + // var orderAttr = Expressions.attribute(topN.order().get(0).child()); + // assertThat(orderAttr.id(), equalTo(tbucketId)); + + // assertThat(Expressions.attribute(project.projections().get(2)).id(), equalTo(tbucketId)); + + // Filter should contain: ISNOTNULL(network.bytes_in) AND IN(host-0, host-1, host-2, pod) + var filter = as(evalBucket.child(), Filter.class); + var condition = filter.condition(); + assertThat(condition, instanceOf(And.class)); + var and = (And) condition; + + // Verify AND contains IsNotNull + boolean hasIsNotNull = and.anyMatch(IsNotNull.class::isInstance); + assertThat(hasIsNotNull, equalTo(true)); + + // Verify AND contains In + boolean hasIn = and.anyMatch(In.class::isInstance); + assertThat(hasIn, equalTo(true)); + + var inConditions = condition.collect(In.class::isInstance); + assertThat(inConditions, hasSize(1)); + var in = (In) inConditions.get(0); + assertThat(in.list(), hasSize(3)); + + as(filter.child(), EsRelation.class); + } + + /** + * Expect the following logical plan + * + * Project[[AVG(AVG_OVER_TIME(network.bytes_in)){r}#86, pod{r}#90, TBUCKET(1h){r}#84]] + * \_Eval[[UNPACKDIMENSION(grouppod_$1{r}#121) AS pod#90, $$SUM$AVG(AVG_OVER_TIME(network.bytes_in))$0{r$}#115 / $$COUNT + * $AVG(AVG_OVER_TIME(network.bytes_in))$1{r$}#116 AS AVG(AVG_OVER_TIME(network.bytes_in))#86]] + * \_Limit[1000[INTEGER],false,false] + * \_Aggregate[[packpod_$1{r}#120, BUCKET{r}#84],[SUM(AVGOVERTIME_$1{r}#118,true[BOOLEAN],PT0S[TIME_DURATION],compensated[KEYW + * ORD]) AS $$SUM$AVG(AVG_OVER_TIME(network.bytes_in))$0#115, COUNT(AVGOVERTIME_$1{r}#118,true[BOOLEAN],PT0S[TIME_DURATION]) AS + * $$COUNT$AVG(AVG_OVER_TIME(network.bytes_in))$1#116, packpod_$1{r}#120 AS grouppod_$1#121, BUCKET{r}#84 AS TBUCKET(1h)#84]] + * \_Eval[[$$SUM$AVGOVERTIME_$1$0{r$}#122 / $$COUNT$AVGOVERTIME_$1$1{r$}#123 AS AVGOVERTIME_$1#118, PACKDIMENSION(pod{r} + * #119) AS packpod_$1#120]] + * \_TimeSeriesAggregate[[_tsid{m}#117, BUCKET{r}#84],[SUM(network.bytes_in{f}#102,true[BOOLEAN], + * PT0S[TIME_DURATION],lossy[KEYWORD]) AS + * $$SUM$AVGOVERTIME_$1$0#122, COUNT(network.bytes_in{f}#102,true[BOOLEAN],PT0S[TIME_DURATION]) AS $$COUNT$AVGOVERTIME_$1$1#123, + * VALUES(pod{f}#90,true[BOOLEAN],PT0S[TIME_DURATION]) AS pod#119, BUCKET{r}#84], + * BUCKET(@timestamp{f}#88,PT1H[TIME_DURATION])] + * \_Eval[[BUCKET(@timestamp{f}#88,PT1H[TIME_DURATION]) AS TBUCKET(1h)#84]] + * \_EsRelation[k8s][@timestamp{f}#88, client.ip{f}#92, cluster{f}#89, e..] + */ + public void testTSAvgAvgOverTimeOutput() { + // TS metrics-hostmetricsreceiver.otel-default + // | STATS AVG(AVG_OVER_TIME(`metrics.system.memory.utilization`)) BY host.name, TBUCKET(1h) | LIMIT 10000" + var plan = planPromql(""" + TS k8s + | STATS AVG(AVG_OVER_TIME(network.bytes_in)) BY pod, TBUCKET(1h) + | LIMIT 1000 + """); + + logger.trace(plan); + } + + /** + * Expect the logical plan + * + * Project[[avg(avg_over_time(network.bytes_in)){r}#353, TBUCKET(1h){r}#351]] + * \_Eval[[$$SUM$avg(avg_over_time(network.bytes_in))$0{r$}#382 / $$COUNT$avg(avg_over_time(network.bytes_in))$1{r$}#383 + * AS avg(avg_over_time(network.bytes_in))#353]] + * \_Limit[1000[INTEGER],false,false] + * \_Aggregate[[BUCKET{r}#351],[SUM(AVGOVERTIME_$1{r}#385,true[BOOLEAN],PT0S[TIME_DURATION],compensated[KEYWORD]) AS $$SUM$avg + * (avg_over_time(network.bytes_in))$0#382, COUNT(AVGOVERTIME_$1{r}#385,true[BOOLEAN],PT0S[TIME_DURATION]) AS + * $$COUNT$avg(avg_over_time(network.bytes_in))$1#383, BUCKET{r}#351 AS TBUCKET(1h)#351]] + * \_Eval[[$$SUM$AVGOVERTIME_$1$0{r$}#386 / $$COUNT$AVGOVERTIME_$1$1{r$}#387 AS AVGOVERTIME_$1#385]] + * \_TimeSeriesAggregate[[_tsid{m}#384, BUCKET{r}#351],[SUM(network.bytes_in{f}#369,true[BOOLEAN],PT0S[TIME_DURATION], + * lossy[KEYWORD]) AS + * $$SUM$AVGOVERTIME_$1$0#386, COUNT(network.bytes_in{f}#369,true[BOOLEAN],PT0S[TIME_DURATION]) AS $$COUNT$AVGOVERTIME_$1$1#387, + * BUCKET{r}#351], + * BUCKET(@timestamp{f}#355,PT1H[TIME_DURATION])] + * \_Eval[[BUCKET(@timestamp{f}#355,PT1H[TIME_DURATION]) AS TBUCKET(1h)#351]] + * \_EsRelation[k8s][@timestamp{f}#355, client.ip{f}#359, cluster{f}#356, ..] + */ + public void testTSAvgWithoutByDimension() { + // TS metrics-hostmetricsreceiver.otel-default + // | STATS AVG(AVG_OVER_TIME(`metrics.system.memory.utilization`)) BY TBUCKET(1h) | LIMIT 10000" + var plan = planPromql(""" + TS k8s + | STATS avg(avg_over_time(network.bytes_in)) BY TBUCKET(1h) + | LIMIT 1000 + """); + + logger.trace(plan); + + } + + /** + * Expect the following logical plan + * + * Project[[avg(avg_over_time(network.bytes_in[1h])){r}#190, TBUCKET{r}#191]] + * \_TopN[[Order[TBUCKET{r}#191,ASC,FIRST]],1000[INTEGER],false] + * \_Eval[[$$SUM$avg(avg_over_time(network.bytes_in[1h]))$0{r$}#196 / $$COUNT$avg(avg_over_time(network.bytes_in[1h]))$1 + * {r$}#197 AS avg(avg_over_time(network.bytes_in[1h]))#190]] + * \_Aggregate[[TBUCKET{r}#191],[SUM(AVGOVERTIME_$1{r}#193,true[BOOLEAN],PT0S[TIME_DURATION],compensated[KEYWORD]) AS $$SUM$av + * g(avg_over_time(network.bytes_in[1h]))$0#196, COUNT(AVGOVERTIME_$1{r}#193,true[BOOLEAN],PT0S[TIME_DURATION]) AS + * $$COUNT$avg(avg_over_time(network.bytes_in[1h]))$1#197, TBUCKET{r}#191 AS TBUCKET#191]] + * \_Eval[[$$SUM$AVGOVERTIME_$1$0{r$}#194 / $$COUNT$AVGOVERTIME_$1$1{r$}#195 AS AVGOVERTIME_$1#193]] + * \_TimeSeriesAggregate[[_tsid{m}#192, TBUCKET{r}#191], + * [SUM(network.bytes_in{f}#178,true[BOOLEAN],PT0S[TIME_DURATION],lossy[KEYWORD]) A + * S $$SUM$AVGOVERTIME_$1$0#194, COUNT(network.bytes_in{f}#178,true[BOOLEAN],PT0S[TIME_DURATION]) AS + * $$COUNT$AVGOVERTIME_$1$1#195, TBUCKET{r}#191], + * BUCKET(@timestamp{f}#164,PT1H[TIME_DURATION])] + * \_Eval[[BUCKET(@timestamp{f}#164,PT1H[TIME_DURATION]) AS TBUCKET#191]] + * \_Filter[ISNOTNULL(network.bytes_in{f}#178)] + * \_EsRelation[k8s][@timestamp{f}#164, client.ip{f}#168, cluster{f}#165, ..] + */ + public void testPromqlAvgWithoutByDimension() { + // TS metrics-hostmetricsreceiver.otel-default + // | STATS AVG(AVG_OVER_TIME(`metrics.system.memory.utilization`)) BY TBUCKET(1h) | LIMIT 10000" + var plan = planPromql(""" + TS k8s + | promql step 1h ( + avg(avg_over_time(network.bytes_in[1h])) + ) + | LIMIT 1000 + """); + + logger.trace(plan); + } + + /** + * Expect the following logical plan + * + * Project[[max by (pod) (avg_over_time(network.bytes_in[1h])){r}#342, pod{r}#318, TBUCKET{r}#343]] + * \_TopN[[Order[TBUCKET{r}#343,ASC,FIRST]],1000[INTEGER],false] + * \_Eval[[UNPACKDIMENSION(grouppod_$1{r}#348) AS pod#318]] + * \_Aggregate[[packpod_$1{r}#347, TBUCKET{r}#343],[MAX(AVGOVERTIME_$1{r}#345,true[BOOLEAN],PT0S[TIME_DURATION]) AS max by (po + * d) (avg_over_time(network.bytes_in[1h]))#342, packpod_$1{r}#347 AS grouppod_$1#348, TBUCKET{r}#343 AS TBUCKET#343]] + * \_Eval[[$$SUM$AVGOVERTIME_$1$0{r$}#349 / $$COUNT$AVGOVERTIME_$1$1{r$}#350 AS AVGOVERTIME_$1#345, PACKDIMENSION(pod{r} + * #346) AS packpod_$1#347]] + * \_TimeSeriesAggregate[[_tsid{m}#344, TBUCKET{r}#343], + * [SUM(network.bytes_in{f}#330,true[BOOLEAN],PT0S[TIME_DURATION],lossy[KEYWORD]) A + * S $$SUM$AVGOVERTIME_$1$0#349, COUNT(network.bytes_in{f}#330,true[BOOLEAN],PT0S[TIME_DURATION]) AS $$COUNT$AVGOVERTIME_$1$1#350, + * VALUES(pod{f}#318,true[BOOLEAN],PT0S[TIME_DURATION]) AS pod#346, TBUCKET{r}#343], + * BUCKET(@timestamp{f}#316,PT1H[TIME_DURATION])] + * \_Eval[[BUCKET(@timestamp{f}#316,PT1H[TIME_DURATION]) AS TBUCKET#343]] + * \_Filter[ISNOTNULL(network.bytes_in{f}#330)] + * \_EsRelation[k8s][@timestamp{f}#316, client.ip{f}#320, cluster{f}#317, ..] + */ + public void testRangeSelector() { + // TS metrics-hostmetricsreceiver.otel-default + // | WHERE @timestamp >= \"{{from | minus .benchmark.duration}}\" AND @timestamp <=\"{{from}}\" + // | STATS AVG(AVG_OVER_TIME(`metrics.system.memory.utilization`)) BY host.name, TBUCKET(1h) | LIMIT 10000" + var plan = planPromql(""" + TS k8s + | promql step 1h ( max by (pod) (avg_over_time(network.bytes_in[1h])) ) + """); + + logger.trace(plan); + } + + @AwaitsFix(bugUrl = "Invalid call to dataType on an unresolved object ?RATE_$1") + public void testRate() { + // TS metrics-hostmetricsreceiver.otel-default + // | WHERE @timestamp >= \"{{from | minus .benchmark.duration}}\" AND @timestamp <= \"{{from}}\" + // | STATS AVG(RATE(`metrics.system.cpu.time`)) BY host.name, TBUCKET(1h) | LIMIT 10000" + String testQuery = """ + TS k8s + | promql step 1h ( + avg by (pod) (rate(network.bytes_in[1h])) + ) + """; + + var plan = planPromql(testQuery); + logger.trace(plan); + } + + /** + * Expect the following logical plan + * + * Project[[avg(avg_over_time(network.bytes_in[5m])){r}#423, TBUCKET{r}#424]] + * \_TopN[[Order[TBUCKET{r}#424,ASC,FIRST]],1000[INTEGER],false] + * \_Eval[[$$SUM$avg(avg_over_time(network.bytes_in[5m]))$0{r$}#429 / $$COUNT$avg(avg_over_time(network.bytes_in[5m]))$1 + * {r$}#430 AS avg(avg_over_time(network.bytes_in[5m]))#423]] + * \_Aggregate[[TBUCKET{r}#424],[SUM(AVGOVERTIME_$1{r}#426,true[BOOLEAN],PT0S[TIME_DURATION],compensated[KEYWORD]) AS $$SUM$av + * g(avg_over_time(network.bytes_in[5m]))$0#429, COUNT(AVGOVERTIME_$1{r}#426,true[BOOLEAN],PT0S[TIME_DURATION]) AS + * $$COUNT$avg(avg_over_time(network.bytes_in[5m]))$1#430, TBUCKET{r}#424 AS TBUCKET#424]] + * \_Eval[[$$SUM$AVGOVERTIME_$1$0{r$}#427 / $$COUNT$AVGOVERTIME_$1$1{r$}#428 AS AVGOVERTIME_$1#426]] + * \_TimeSeriesAggregate[[_tsid{m}#425, TBUCKET{r}#424], + * [SUM(network.bytes_in{f}#411,true[BOOLEAN],PT0S[TIME_DURATION],lossy[KEYWORD]) A + * S $$SUM$AVGOVERTIME_$1$0#427, COUNT(network.bytes_in{f}#411,true[BOOLEAN],PT0S[TIME_DURATION]) AS + * $$COUNT$AVGOVERTIME_$1$1#428, TBUCKET{r}#424], + * BUCKET(@timestamp{f}#397,PT5M[TIME_DURATION])] + * \_Eval[[BUCKET(@timestamp{f}#397,PT5M[TIME_DURATION]) AS TBUCKET#424]] + * \_Filter[ISNOTNULL(network.bytes_in{f}#411)] + * \_EsRelation[k8s][@timestamp{f}#397, client.ip{f}#401, cluster{f}#398, ..] + */ + public void testStartEndStep() { + String testQuery = """ + TS k8s + | promql start $now-1h end $now step 5m ( + avg(avg_over_time(network.bytes_in[5m])) + ) + """; + + var plan = planPromql(testQuery); + List collect = plan.collect(Bucket.class::isInstance); + logger.trace(plan); + } + + /** + * Expect the following logical plan + * + * Project[[max by (pod) (avg_over_time(network.bytes_in{pod=~"host-0|host-1|host-2"}[5m])){r}#33, pod{r}#9, TBUCKET{r}#3 + * 4]] + * \_TopN[[Order[TBUCKET{r}#34,ASC,FIRST]],1000[INTEGER],false] + * \_Eval[[UNPACKDIMENSION(grouppod_$1{r}#39) AS pod#9]] + * \_Aggregate[[packpod_$1{r}#38, TBUCKET{r}#34],[MAX(AVGOVERTIME_$1{r}#36,true[BOOLEAN],PT0S[TIME_DURATION]) AS max by (pod) + * (avg_over_time(network.bytes_in{pod=~"host-0|host-1|host-2"}[5m]))#33, packpod_$1{r}#38 AS grouppod_$1#39, + * TBUCKET{r}#34 AS TBUCKET#34]] + * \_Eval[[$$SUM$AVGOVERTIME_$1$0{r$}#40 / $$COUNT$AVGOVERTIME_$1$1{r$}#41 AS AVGOVERTIME_$1#36, PACKDIMENSION(pod{r}#37 + * ) AS packpod_$1#38]] + * \_TimeSeriesAggregate[[_tsid{m}#35, TBUCKET{r}#34], + * [SUM(network.bytes_in{f}#21,true[BOOLEAN],PT0S[TIME_DURATION],lossy[KEYWORD]) AS $ + * $SUM$AVGOVERTIME_$1$0#40, COUNT(network.bytes_in{f}#21,true[BOOLEAN],PT0S[TIME_DURATION]) AS $$COUNT$AVGOVERTIME_$1$1#41, + * VALUES(pod{f}#9,true[BOOLEAN],PT0S[TIME_DURATION]) AS pod#37, TBUCKET{r}#34], + * BUCKET(@timestamp{f}#7,PT5M[TIME_DURATION])] + * \_Eval[[BUCKET(@timestamp{f}#7,PT5M[TIME_DURATION]) AS TBUCKET#34]] + * \_Filter[ISNOTNULL(network.bytes_in{f}#21) AND IN(host-0[KEYWORD],host-1[KEYWORD],host-2[KEYWORD],pod{f}#9)] + * \_EsRelation[k8s][@timestamp{f}#7, client.ip{f}#11, cluster{f}#8, eve..] + */ + public void testLabelSelector() { + // TS metrics-hostmetricsreceiver.otel-default | WHERE @timestamp >= \"{{from | minus .benchmark.duration}}\" AND @timestamp <= + // \"{{from}}\" + // | WHERE host.name IN(\"host-0\", \"host-1\", \"host-2\") + // | STATS AVG(AVG_OVER_TIME(`system.cpu.load_average.1m`)) BY host.name, TBUCKET(5m) | LIMIT 10000" + String testQuery = """ + TS k8s + | promql time $now ( + max by (pod) (avg_over_time(network.bytes_in{pod=~"host-0|host-1|host-2"}[5m])) + ) + """; + + var plan = planPromql(testQuery); + var filters = plan.collect(Filter.class::isInstance); + assertThat(filters, hasSize(1)); + var filter = (Filter) filters.getFirst(); + assertThat(filter.condition().anyMatch(In.class::isInstance), equalTo(true)); + logger.trace(plan); + } + + public void testLabelSelectorPrefix() { + // TS metrics-hostmetricsreceiver.otel-default | WHERE @timestamp >= \"{{from | minus .benchmark.duration}}\" AND @timestamp <= + // \"{{from}}\" + // | WHERE host.name LIKE \"host-*\" + // STATS AVG(AVG_OVER_TIME(`metrics.system.cpu.load_average.1m`)) BY host.name, TBUCKET(5 minutes)" + String testQuery = """ + TS k8s + | promql time $now ( + avg by (pod) (avg_over_time(network.bytes_in{pod=~"host-.*"}[5m])) + ) + """; + + var plan = planPromql(testQuery); + var filters = plan.collect(Filter.class::isInstance); + assertThat(filters, hasSize(1)); + var filter = (Filter) filters.getFirst(); + assertThat(filter.condition().anyMatch(StartsWith.class::isInstance), equalTo(true)); + assertThat(filter.condition().anyMatch(NotEquals.class::isInstance), equalTo(false)); + logger.trace(plan); + } + + public void testLabelSelectorProperPrefix() { + var plan = planPromql(""" + TS k8s + | promql time $now ( + avg(avg_over_time(network.bytes_in{pod=~"host-.+"}[1h])) + ) + """); + + var filters = plan.collect(Filter.class::isInstance); + assertThat(filters, hasSize(1)); + var filter = (Filter) filters.getFirst(); + assertThat(filter.condition().anyMatch(StartsWith.class::isInstance), equalTo(true)); + assertThat(filter.condition().anyMatch(NotEquals.class::isInstance), equalTo(true)); + } + + /** + * Expect the following logical plan + * + * Project[[avg(avg_over_time(network.bytes_in{pod=~"[a-z]+"}[1h])){r}#305, TBUCKET{r}#306]] + * \_TopN[[Order[TBUCKET{r}#306,ASC,FIRST]],1000[INTEGER],false] + * \_Eval[[$$SUM$avg(avg_over_time(network.bytes_in{pod=~"[a-z]+"}[1h]))$0{r$}#311 / $$COUNT$avg(avg_over_time(network.b + * ytes_in{pod=~"[a-z]+"}[1h]))$1{r$}#312 AS avg(avg_over_time(network.bytes_in{pod=~"[a-z]+"}[1h]))#305]] + * \_Aggregate[[TBUCKET{r}#306],[SUM(AVGOVERTIME_$1{r}#308,true[BOOLEAN],PT0S[TIME_DURATION],compensated[KEYWORD]) AS $$SUM$av + * g(avg_over_time(network.bytes_in{pod=~"[a-z]+"}[1h]))$0#311, COUNT(AVGOVERTIME_$1{r}#308,true[BOOLEAN],PT0S[TIME_DURATION]) AS + * $$COUNT$avg(avg_over_time(network.bytes_in{pod=~"[a-z]+"}[1h]))$1#312, TBUCKET{r}#306 AS TBUCKET#306]] + * \_Eval[[$$SUM$AVGOVERTIME_$1$0{r$}#309 / $$COUNT$AVGOVERTIME_$1$1{r$}#310 AS AVGOVERTIME_$1#308]] + * \_TimeSeriesAggregate[[_tsid{m}#307, TBUCKET{r}#306], + * [SUM(network.bytes_in{f}#293,true[BOOLEAN],PT0S[TIME_DURATION],lossy[KEYWORD]) A + * S $$SUM$AVGOVERTIME_$1$0#309, COUNT(network.bytes_in{f}#293,true[BOOLEAN],PT0S[TIME_DURATION]) AS + * $$COUNT$AVGOVERTIME_$1$1#310, TBUCKET{r}#306], + * BUCKET(@timestamp{f}#279,PT5M[TIME_DURATION])] + * \_Eval[[BUCKET(@timestamp{f}#279,PT5M[TIME_DURATION]) AS TBUCKET#306]] + * \_Filter[ISNOTNULL(network.bytes_in{f}#293) AND RLIKE(pod{f}#281, "[a-z]+", false)] + * \_EsRelation[k8s][@timestamp{f}#279, client.ip{f}#283, cluster{f}#280, ..] + */ + public void testLabelSelectorRegex() { + var plan = planPromql(""" + TS k8s + | promql time $now ( + avg(avg_over_time(network.bytes_in{pod=~"[a-z]+"}[1h])) + ) + """); + + var filters = plan.collect(Filter.class::isInstance); + assertThat(filters, hasSize(1)); + var filter = (Filter) filters.getFirst(); + assertThat(filter.condition().anyMatch(RegexMatch.class::isInstance), equalTo(true)); + } + + @AwaitsFix(bugUrl = "This should never be called before the attribute is resolved") + public void testFsUsageTop5() { + // TS metrics-hostmetricsreceiver.otel-default | WHERE @timestamp >= \"{{from | minus .benchmark.duration}}\" AND @timestamp <= + // \"{{from}}\" + // | WHERE attributes.state IN (\"used\", \"free\") + // | STATS sums = SUM(LAST_OVER_TIME(system.filesystem.usage)) by host.name, attributes.mountpoint + // | STATS top = TOP(sums, 5, \"desc\") by host.name, attributes.mountpoint + // | LIMIT 5 + + // topk(5, sum by (host.name, mountpoint) (last_over_time(system.filesystem.usage{state=~"used|free"}[5m]))) + String testQuery = """ + TS k8s + | promql step 5m ( + sum by (host.name, mountpoint) (last_over_time(system.filesystem.usage{state=~"used|free"}[5m])) + ) + """; + + var plan = planPromql(testQuery); + logger.trace(plan); + } + + @AwaitsFix(bugUrl = "only aggregations across timeseries are supported at this time (found [foo or bar])") + public void testGrammar() { + // TS metrics-hostmetricsreceiver.otel-default | WHERE @timestamp >= \"{{from | minus .benchmark.duration}}\" AND @timestamp <= + // \"{{from}}\" + // | WHERE attributes.state IN (\"used\", \"free\") + // | STATS sums = SUM(LAST_OVER_TIME(system.filesystem.usage)) by host.name, attributes.mountpoint + // | STATS top = TOP(sums, 5, \"desc\") by host.name, attributes.mountpoint + // | LIMIT 5 + + // topk(5, sum by (host.name, mountpoint) (last_over_time(system.filesystem.usage{state=~"used|free"}[5m]))) + String testQuery = """ + TS k8s + | promql step 5m ( + foo or bar + ) + """; + + var plan = planPromql(testQuery); + logger.trace(plan); + } + + // public void testPromqlArithmetricOperators() { + // // TODO doesn't parse + // // line 1:27: Invalid query '1+1'[ArithmeticBinaryContext] given; expected LogicalPlan but found VectorBinaryArithmetic + // assertThat( + // error("TS test | PROMQL step 5m (1+1)", tsdb), + // equalTo("1:1: arithmetic operators are not supported at this time [foo]") + // ); + // assertThat( + // error("TS test | PROMQL step 5m ( foo and bar )", tsdb), + // equalTo("1:1: arithmetic operators are not supported at this time [foo]") + // ); + // assertThat( + // error("TS test | PROMQL step 5m (1+foo)", tsdb), + // equalTo("1:1: arithmetic operators are not supported at this time [foo]") + // ); + // assertThat( + // error("TS test | PROMQL step 5m (foo+bar)", tsdb), + // equalTo("1:1: arithmetic operators are not supported at this time [foo]") + // ); + // } + + protected LogicalPlan planPromql(String query) { + query = query.replace("$now-1h", '"' + Instant.now().minus(1, ChronoUnit.HOURS).toString() + '"'); + query = query.replace("$now", '"' + Instant.now().toString() + '"'); + var analyzed = tsAnalyzer.analyze(parser.createStatement(query)); + logger.trace(analyzed); + var optimized = logicalOptimizer.optimize(analyzed); + logger.trace(optimized); + return optimized; + } +} diff --git a/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/optimizer/rules/logical/promql/AutomatonUtilsTests.java b/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/optimizer/rules/logical/promql/AutomatonUtilsTests.java new file mode 100644 index 0000000000000..e0b6c970594ee --- /dev/null +++ b/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/optimizer/rules/logical/promql/AutomatonUtilsTests.java @@ -0,0 +1,254 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +package org.elasticsearch.xpack.esql.optimizer.rules.logical.promql; + +import org.elasticsearch.test.ESTestCase; +import org.elasticsearch.xpack.esql.action.PromqlFeatures; +import org.elasticsearch.xpack.esql.optimizer.rules.logical.promql.AutomatonUtils.PatternFragment; +import org.junit.BeforeClass; + +import java.util.List; + +import static org.elasticsearch.xpack.esql.optimizer.rules.logical.promql.AutomatonUtils.PatternFragment.Type.EXACT; +import static org.elasticsearch.xpack.esql.optimizer.rules.logical.promql.AutomatonUtils.PatternFragment.Type.PREFIX; +import static org.elasticsearch.xpack.esql.optimizer.rules.logical.promql.AutomatonUtils.PatternFragment.Type.PROPER_PREFIX; +import static org.elasticsearch.xpack.esql.optimizer.rules.logical.promql.AutomatonUtils.PatternFragment.Type.PROPER_SUFFIX; +import static org.elasticsearch.xpack.esql.optimizer.rules.logical.promql.AutomatonUtils.PatternFragment.Type.REGEX; +import static org.elasticsearch.xpack.esql.optimizer.rules.logical.promql.AutomatonUtils.PatternFragment.Type.SUFFIX; +import static org.elasticsearch.xpack.esql.optimizer.rules.logical.promql.AutomatonUtils.extractFragments; +import static org.hamcrest.Matchers.equalTo; +import static org.hamcrest.Matchers.hasSize; +import static org.hamcrest.Matchers.notNullValue; +import static org.hamcrest.Matchers.nullValue; +import static org.junit.Assume.assumeTrue; + +public class AutomatonUtilsTests extends ESTestCase { + + @BeforeClass + public static void checkPromqlEnabled() { + assumeTrue("requires snapshot build with promql feature enabled", PromqlFeatures.isEnabled()); + } + + public void testExtractFragments_ExactString() { + // Single exact string (no wildcards) + List fragments = extractFragments("api"); + + assertThat(fragments, notNullValue()); + assertThat(fragments, hasSize(1)); + assertFragment(fragments.get(0), EXACT, "api"); + } + + public void testExtractFragments_Prefix() { + // Prefix pattern: prefix.* + List fragments = extractFragments("prod-.*"); + + assertThat(fragments, notNullValue()); + assertThat(fragments, hasSize(1)); + assertFragment(fragments.get(0), PREFIX, "prod-"); + } + + public void testExtractFragments_Suffix() { + // Suffix pattern: .*suffix + List fragments = extractFragments(".*-prod"); + + assertThat(fragments, notNullValue()); + assertThat(fragments, hasSize(1)); + assertFragment(fragments.get(0), SUFFIX, "-prod"); + } + + public void testExtractFragments_MixedAlternation() { + // Mixed alternation: prefix|exact|suffix + List fragments = extractFragments("prod-.*|staging|.*-dev"); + + assertThat(fragments, notNullValue()); + assertThat(fragments, hasSize(3)); + + Object[][] expected = { { PREFIX, "prod-" }, { EXACT, "staging" }, { SUFFIX, "-dev" } }; + + assertFragments(fragments, expected); + } + + public void testExtractFragments_ProperPrefixSuffixAlternation() { + List fragments = extractFragments("prod-.+|.+-dev"); + + assertThat(fragments, notNullValue()); + assertThat(fragments, hasSize(2)); + + Object[][] expected = { { PROPER_PREFIX, "prod-" }, { PROPER_SUFFIX, "-dev" } }; + + assertFragments(fragments, expected); + } + + public void testExtractFragments_HomogeneousExactAlternation() { + // All exact values + List fragments = extractFragments("api|web|service"); + + assertThat(fragments, notNullValue()); + assertThat(fragments, hasSize(3)); + + Object[][] expected = { { EXACT, "api" }, { EXACT, "web" }, { EXACT, "service" } }; + + assertFragments(fragments, expected); + } + + public void testExtractFragments_HomogeneousPrefixAlternation() { + // All prefixes + List fragments = extractFragments("prod-.*|staging-.*|dev-.*"); + + assertThat(fragments, notNullValue()); + assertThat(fragments, hasSize(3)); + + Object[][] expected = { { PREFIX, "prod-" }, { PREFIX, "staging-" }, { PREFIX, "dev-" } }; + + assertFragments(fragments, expected); + } + + public void testExtractFragments_HomogeneousSuffixAlternation() { + // All suffixes + List fragments = extractFragments(".*-prod|.*-staging|.*-dev"); + + assertThat(fragments, notNullValue()); + assertThat(fragments, hasSize(3)); + + Object[][] expected = { { SUFFIX, "-prod" }, { SUFFIX, "-staging" }, { SUFFIX, "-dev" } }; + + assertFragments(fragments, expected); + } + + public void testExtractFragments_WithAnchors() { + // Pattern with anchors should be normalized + List fragments = extractFragments("^prod-.*|staging|.*-dev$"); + + assertThat(fragments, notNullValue()); + assertThat(fragments, hasSize(3)); + + Object[][] expected = { { PREFIX, "prod-" }, { EXACT, "staging" }, { SUFFIX, "-dev" } }; + + assertFragments(fragments, expected); + } + + public void testExtractFragments_ContainsPattern() { + // Contains pattern (.*substring.*) should return REGEX type + List fragments = extractFragments(".*error.*"); + + assertThat(fragments, notNullValue()); + assertThat(fragments, hasSize(1)); + assertFragment(fragments.get(0), REGEX, ".*error.*"); + } + + public void testExtractFragments_ComplexRegex() { + // Complex regex with character classes should return REGEX type + List fragments = extractFragments("[0-9]+"); + + assertThat(fragments, notNullValue()); + assertThat(fragments, hasSize(1)); + assertFragment(fragments.get(0), REGEX, "[0-9]+"); + } + + public void testExtractFragments_MixedWithRegex() { + // Mixed alternation with some REGEX fragments: exact|prefix|regex|suffix + List fragments = extractFragments("api|prod-.*|[0-9]+|.*-dev"); + + assertThat(fragments, notNullValue()); + assertThat(fragments, hasSize(4)); + + Object[][] expected = { { EXACT, "api" }, { PREFIX, "prod-" }, { REGEX, "[0-9]+" }, { SUFFIX, "-dev" } }; + + assertFragments(fragments, expected); + } + + public void testExtractFragments_ComplexPrefixPattern() { + // Prefix with complex part should return REGEX + List fragments = extractFragments("test[0-9]+.*"); + + assertThat(fragments, notNullValue()); + assertThat(fragments, hasSize(1)); + assertFragment(fragments.get(0), REGEX, "test[0-9]+.*"); + } + + public void testExtractFragments_ComplexSuffixPattern() { + // Suffix with complex part should return REGEX + List fragments = extractFragments(".*[a-z]{3}"); + + assertThat(fragments, notNullValue()); + assertThat(fragments, hasSize(1)); + assertFragment(fragments.get(0), REGEX, ".*[a-z]{3}"); + } + + public void testExtractFragments_NonMatchingPattern_NestedGroups() { + // Nested groups should return null + List fragments = extractFragments("(a(b|c))"); + + assertThat(fragments, nullValue()); + } + + public void testExtractFragments_NonMatchingPattern_EscapedPipe() { + // Escaped pipe should return null (too complex) + List fragments = extractFragments("a\\|b"); + + assertThat(fragments, nullValue()); + } + + public void testExtractFragments_RegexMetacharactersInAlternation() { + // Pattern with regex metacharacters - should classify correctly + List fragments = extractFragments("test.*|prod[0-9]"); + + assertThat(fragments, notNullValue()); + assertThat(fragments, hasSize(2)); + + Object[][] expected = { { PREFIX, "test" }, { REGEX, "prod[0-9]" } }; + + assertFragments(fragments, expected); + } + + public void testExtractFragments_NullPattern() { + // Null pattern should return null + List fragments = extractFragments(null); + + assertThat(fragments, nullValue()); + } + + public void testExtractFragments_EmptyPattern() { + // Empty pattern should return single EXACT fragment with empty value + List fragments = extractFragments(""); + + assertThat(fragments, notNullValue()); + assertThat(fragments, hasSize(1)); + assertFragment(fragments.get(0), EXACT, ""); + } + + public void testExtractFragments_TooManyAlternations() { + // Create a pattern with more than MAX_IN_VALUES (256) alternations + StringBuilder pattern = new StringBuilder(); + for (int i = 0; i < 300; i++) { + if (i > 0) { + pattern.append("|"); + } + pattern.append("a").append(i); + } + + List fragments = extractFragments(pattern.toString()); + + // Should return null because it exceeds MAX_IN_VALUES + assertThat(fragments, nullValue()); + } + + private void assertFragment(PatternFragment fragment, PatternFragment.Type expectedType, String expectedValue) { + assertThat(fragment.type(), equalTo(expectedType)); + assertThat(fragment.value(), equalTo(expectedValue)); + } + + private void assertFragments(List fragments, Object[][] expected) { + assertThat(fragments, hasSize(expected.length)); + for (int i = 0; i < expected.length; i++) { + PatternFragment.Type expectedType = (PatternFragment.Type) expected[i][0]; + String expectedValue = (String) expected[i][1]; + assertFragment(fragments.get(i), expectedType, expectedValue); + } + } +} diff --git a/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/parser/promql/PromqlAstTests.java b/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/parser/promql/PromqlAstTests.java new file mode 100644 index 0000000000000..21e70ee02f5de --- /dev/null +++ b/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/parser/promql/PromqlAstTests.java @@ -0,0 +1,134 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +package org.elasticsearch.xpack.esql.parser.promql; + +import org.elasticsearch.core.Tuple; +import org.elasticsearch.logging.LogManager; +import org.elasticsearch.logging.Logger; +import org.elasticsearch.test.ESTestCase; +import org.elasticsearch.xpack.esql.EsqlTestUtils; +import org.elasticsearch.xpack.esql.action.PromqlFeatures; +import org.elasticsearch.xpack.esql.core.QlClientException; +import org.elasticsearch.xpack.esql.core.expression.Literal; +import org.elasticsearch.xpack.esql.core.tree.Source; +import org.elasticsearch.xpack.esql.core.type.DataType; +import org.elasticsearch.xpack.esql.parser.ParsingException; +import org.elasticsearch.xpack.esql.parser.PromqlParser; +import org.junit.BeforeClass; + +import java.io.BufferedReader; +import java.net.URL; +import java.time.Instant; +import java.util.ArrayList; +import java.util.List; + +import static java.util.Arrays.asList; +import static org.elasticsearch.common.logging.LoggerMessageFormat.format; +import static org.hamcrest.Matchers.empty; +import static org.hamcrest.Matchers.not; + +/** + * Test for checking the overall grammar by throwing a number of valid queries at the parser to see whether any exception is raised. + * In time, the queries themselves get to be checked against the actual execution model and eventually against the expected results. + */ +// @TestLogging(reason = "debug", value = "org.elasticsearch.xpack.esql.parser.promql:TRACE") +public class PromqlAstTests extends ESTestCase { + + private static final Logger log = LogManager.getLogger(PromqlAstTests.class); + + @BeforeClass + public static void checkPromqlEnabled() { + assumeTrue("requires snapshot build with promql feature enabled", PromqlFeatures.isEnabled()); + } + + public void testValidQueries() throws Exception { + testValidQueries("/promql/grammar/queries-valid.promql"); + } + + @AwaitsFix(bugUrl = "functionality not implemented yet") + public void testValidQueriesNotYetWorkingDueToMissingFunctionality() throws Exception { + testValidQueries("/promql/grammar/queries-valid-extra.promql"); + } + + private void testValidQueries(String url) throws Exception { + List> lines = readQueries(url); + for (Tuple line : lines) { + String q = line.v1(); + try { + PromqlParser parser = new PromqlParser(); + Literal now = new Literal(Source.EMPTY, Instant.now(), DataType.DATETIME); + var plan = parser.createStatement(q, now, now, 0, 0); + log.trace("{}", plan); + } catch (ParsingException pe) { + fail(format(null, "Error parsing line {}:{} '{}' [{}]", line.v2(), pe.getColumnNumber(), pe.getErrorMessage(), q)); + } catch (Exception e) { + fail(format(null, "Unexpected exception for line {}: [{}] \n {}", line.v2(), line.v1(), e)); + } + } + } + + public void testUnsupportedQueries() throws Exception { + List> lines = readQueries("/promql/grammar/queries-invalid.promql"); + for (Tuple line : lines) { + String q = line.v1(); + try { + log.trace("Testing invalid query {}", q); + PromqlParser parser = new PromqlParser(); + Exception pe = expectThrowsAnyOf( + asList(QlClientException.class, UnsupportedOperationException.class), + () -> parser.createStatement(q) + ); + parser.createStatement(q); + log.trace("{}", pe.getMessage()); + } catch (QlClientException | UnsupportedOperationException ex) { + // Expected + } + } + } + + @AwaitsFix(bugUrl = "placeholder for individual queries") + public void testSingleQuery() throws Exception { + // rate(http_requests_total[5m])[30m:1m+1^2%1] + String query = """ + bar + on(foo) bla / on(baz, buz) group_right(test) blub + """; + var plan = new PromqlParser().createStatement(query); + log.info("{}", plan); + } + + static List> readQueries(String source) throws Exception { + var urls = EsqlTestUtils.classpathResources(source); + assertThat(urls, not(empty())); + List> queries = new ArrayList<>(); + + StringBuilder query = new StringBuilder(); + for (URL url : urls) { + try (BufferedReader reader = EsqlTestUtils.reader(url)) { + String line; + int lineNumber = 1; + + while ((line = reader.readLine()) != null) { + // ignore comments + if (line.isEmpty() == false && line.startsWith("//") == false) { + query.append(line); + + if (line.endsWith(";")) { + query.setLength(query.length() - 1); + queries.add(new Tuple<>(query.toString(), lineNumber)); + query.setLength(0); + } else { + query.append("\n"); + } + } + lineNumber++; + } + } + } + return queries; + } +} diff --git a/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/parser/promql/PromqlFoldingUtilsTests.java b/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/parser/promql/PromqlFoldingUtilsTests.java new file mode 100644 index 0000000000000..82aedc692d30c --- /dev/null +++ b/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/parser/promql/PromqlFoldingUtilsTests.java @@ -0,0 +1,200 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +package org.elasticsearch.xpack.esql.parser.promql; + +import org.elasticsearch.test.ESTestCase; +import org.elasticsearch.xpack.esql.action.PromqlFeatures; +import org.elasticsearch.xpack.esql.core.tree.Source; +import org.elasticsearch.xpack.esql.parser.ParsingException; +import org.elasticsearch.xpack.esql.plan.logical.promql.operator.arithmetic.VectorBinaryArithmetic.ArithmeticOp; +import org.elasticsearch.xpack.esql.plan.logical.promql.operator.comparison.VectorBinaryComparison.ComparisonOp; +import org.junit.BeforeClass; + +import java.time.Duration; + +import static org.elasticsearch.xpack.esql.plan.logical.promql.operator.arithmetic.VectorBinaryArithmetic.ArithmeticOp.ADD; +import static org.elasticsearch.xpack.esql.plan.logical.promql.operator.arithmetic.VectorBinaryArithmetic.ArithmeticOp.DIV; +import static org.elasticsearch.xpack.esql.plan.logical.promql.operator.arithmetic.VectorBinaryArithmetic.ArithmeticOp.MOD; +import static org.elasticsearch.xpack.esql.plan.logical.promql.operator.arithmetic.VectorBinaryArithmetic.ArithmeticOp.MUL; +import static org.elasticsearch.xpack.esql.plan.logical.promql.operator.arithmetic.VectorBinaryArithmetic.ArithmeticOp.POW; +import static org.elasticsearch.xpack.esql.plan.logical.promql.operator.arithmetic.VectorBinaryArithmetic.ArithmeticOp.SUB; +import static org.elasticsearch.xpack.esql.plan.logical.promql.operator.comparison.VectorBinaryComparison.ComparisonOp.EQ; +import static org.elasticsearch.xpack.esql.plan.logical.promql.operator.comparison.VectorBinaryComparison.ComparisonOp.GT; +import static org.elasticsearch.xpack.esql.plan.logical.promql.operator.comparison.VectorBinaryComparison.ComparisonOp.GTE; +import static org.elasticsearch.xpack.esql.plan.logical.promql.operator.comparison.VectorBinaryComparison.ComparisonOp.LT; +import static org.elasticsearch.xpack.esql.plan.logical.promql.operator.comparison.VectorBinaryComparison.ComparisonOp.LTE; +import static org.elasticsearch.xpack.esql.plan.logical.promql.operator.comparison.VectorBinaryComparison.ComparisonOp.NEQ; +import static org.hamcrest.Matchers.containsString; +import static org.junit.Assume.assumeTrue; + +public class PromqlFoldingUtilsTests extends ESTestCase { + + @BeforeClass + public static void checkPromqlEnabled() { + assumeTrue("requires snapshot build with promql feature enabled", PromqlFeatures.isEnabled()); + } + + private static Duration sec(int seconds) { + return Duration.ofSeconds(seconds); + } + + // Utility method for compact one-liner tests + private void evaluate(Object left, ArithmeticOp op, Object right, Object expected) { + Object result = PromqlFoldingUtils.evaluate(Source.EMPTY, left, right, op); + assertEquals(expected, result); + } + + // Utility method for compact one-liner tests + private boolean evaluate(Object left, ComparisonOp op, Object right) { + return PromqlFoldingUtils.evaluate(Source.EMPTY, left, right, op); + } + + private void error(Object left, ArithmeticOp op, Object right, String errorMessage) { + ParsingException exception = expectThrows(ParsingException.class, () -> PromqlFoldingUtils.evaluate(Source.EMPTY, left, right, op)); + assertThat(exception.getErrorMessage(), containsString(errorMessage)); + } + + // Number op Number tests + public void testNumberAddition() { + evaluate(5, ADD, 3, 8); + evaluate(5L, ADD, 3L, 8L); + evaluate(5.5, ADD, 3.5, 9.0); + } + + public void testNumberSubtraction() { + evaluate(5, SUB, 3, 2); + evaluate(5L, SUB, 3L, 2L); + evaluate(5.5, SUB, 3.5, 2.0); + } + + public void testNumberMultiplication() { + evaluate(5, MUL, 3, 15); + evaluate(5L, MUL, 3L, 15L); + evaluate(5.5, MUL, 2.0, 11.0); + } + + public void testNumberDivision() { + evaluate(10, DIV, 2, 5); + evaluate(10L, DIV, 2L, 5L); + evaluate(10.0, DIV, 2.0, 5.0); + } + + public void testNumberModulo() { + evaluate(10, MOD, 3, 1); + evaluate(10L, MOD, 3L, 1L); + } + + public void testNumberPower() { + evaluate(2, POW, 3, 8); // integer result + evaluate(2.5, POW, 2.0, 6.25); // double result + } + + // Duration op Duration tests + public void testDurationAddition() { + evaluate(sec(60), ADD, sec(30), sec(90)); + } + + public void testDurationSubtraction() { + evaluate(sec(60), SUB, sec(30), sec(30)); + } + + public void testDurationInvalidOperations() { + error(sec(60), MUL, sec(30), "not supported between two durations"); + error(sec(60), DIV, sec(30), "not supported between two durations"); + } + + // Duration op Number tests (Number interpreted as seconds for ADD/SUB, dimensionless for MUL/DIV/MOD/POW) + public void testDurationAddNumber() { + evaluate(sec(60), ADD, 30, sec(90)); + evaluate(sec(60), ADD, 30.0, sec(90)); + } + + public void testDurationSubNumber() { + evaluate(sec(60), SUB, 30, sec(30)); + evaluate(sec(60), SUB, 30.0, sec(30)); + } + + public void testDurationMulNumber() { + evaluate(sec(60), MUL, 2, sec(120)); + evaluate(sec(60), MUL, 2.5, sec(150)); + } + + public void testDurationDivNumber() { + evaluate(sec(60), DIV, 2, sec(30)); + evaluate(sec(60), DIV, 2.0, sec(30)); + } + + public void testDurationModNumber() { + evaluate(sec(65), MOD, 60, sec(5)); + } + + public void testDurationPowNumber() { + evaluate(sec(2), POW, 3, sec(8)); + } + + public void testDurationDivByZero() { + error(sec(60), DIV, 0, "Cannot divide duration by zero"); + } + + public void testDurationModByZero() { + error(sec(60), MOD, 0, "Cannot compute modulo with zero"); + } + + public void testNumberMulDuration() { + evaluate(2, MUL, sec(60), sec(120)); + evaluate(2.5, MUL, sec(60), sec(150)); + evaluate(2, ADD, sec(60), sec(62)); + evaluate(60, SUB, sec(2), sec(58)); + } + + public void testNumberInvalidDurationOperations() { + error(2, DIV, sec(60), "not supported with scalar on left"); + } + + // Validation tests + public void testNegativeDuration() { + evaluate(sec(30), SUB, sec(60), sec(-30)); + evaluate(sec(60), SUB, 90, sec(-30)); + } + + // Comparison tests + public void testComparisonEqual() { + assertTrue(evaluate(5, EQ, 5)); + assertTrue(evaluate(2.5, EQ, 2.5)); + assertFalse(evaluate(5, EQ, 3)); + } + + public void testComparisonNotEqual() { + assertTrue(evaluate(5, NEQ, 3)); + assertFalse(evaluate(5, NEQ, 5)); + } + + public void testComparisonGreaterThan() { + assertTrue(evaluate(5, GT, 3)); + assertFalse(evaluate(3, GT, 5)); + assertFalse(evaluate(5, GT, 5)); + } + + public void testComparisonGreaterThanOrEqual() { + assertTrue(evaluate(5, GTE, 3)); + assertTrue(evaluate(5, GTE, 5)); + assertFalse(evaluate(3, GTE, 5)); + } + + public void testComparisonLessThan() { + assertTrue(evaluate(3, LT, 5)); + assertFalse(evaluate(5, LT, 3)); + assertFalse(evaluate(5, LT, 5)); + } + + public void testComparisonLessThanOrEqual() { + assertTrue(evaluate(3, LTE, 5)); + assertTrue(evaluate(5, LTE, 5)); + assertFalse(evaluate(5, LTE, 3)); + } +} diff --git a/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/parser/promql/PromqlParamsTests.java b/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/parser/promql/PromqlParamsTests.java new file mode 100644 index 0000000000000..9cc8c20c73059 --- /dev/null +++ b/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/parser/promql/PromqlParamsTests.java @@ -0,0 +1,199 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +package org.elasticsearch.xpack.esql.parser.promql; + +import org.elasticsearch.test.ESTestCase; +import org.elasticsearch.xpack.esql.EsqlTestUtils; +import org.elasticsearch.xpack.esql.action.PromqlFeatures; +import org.elasticsearch.xpack.esql.parser.EsqlParser; +import org.elasticsearch.xpack.esql.parser.ParsingException; +import org.elasticsearch.xpack.esql.parser.QueryParams; +import org.elasticsearch.xpack.esql.plan.logical.promql.PromqlCommand; +import org.junit.BeforeClass; + +import java.time.Duration; +import java.time.Instant; +import java.util.List; + +import static org.elasticsearch.xpack.esql.EsqlTestUtils.as; +import static org.elasticsearch.xpack.esql.EsqlTestUtils.paramAsConstant; +import static org.elasticsearch.xpack.esql.EsqlTestUtils.withDefaultLimitWarning; +import static org.hamcrest.Matchers.containsString; +import static org.hamcrest.Matchers.equalTo; +import static org.hamcrest.Matchers.nullValue; +import static org.junit.Assume.assumeTrue; + +public class PromqlParamsTests extends ESTestCase { + + private static final EsqlParser parser = new EsqlParser(); + + @BeforeClass + public static void checkPromqlEnabled() { + assumeTrue("requires snapshot build with promql feature enabled", PromqlFeatures.isEnabled()); + } + + public void testValidRangeQuery() { + PromqlCommand promql = parse("TS test | PROMQL start \"2025-10-31T00:00:00Z\" end \"2025-10-31T01:00:00Z\" step 1m (avg(foo))"); + assertThat(promql.start().value(), equalTo(Instant.parse("2025-10-31T00:00:00Z"))); + assertThat(promql.end().value(), equalTo(Instant.parse("2025-10-31T01:00:00Z"))); + assertThat(promql.step().value(), equalTo(Duration.ofMinutes(1))); + assertThat(promql.isRangeQuery(), equalTo(true)); + assertThat(promql.isInstantQuery(), equalTo(false)); + } + + public void testValidRangeQueryParams() { + PromqlCommand promql = EsqlTestUtils.as( + parser.createStatement( + "TS test | PROMQL start ?_tstart end ?_tend step ?_step (avg(foo))", + new QueryParams( + List.of( + paramAsConstant("_tstart", "2025-10-31T00:00:00Z"), + paramAsConstant("_tend", "2025-10-31T01:00:00Z"), + paramAsConstant("_step", "1m") + ) + ) + ), + PromqlCommand.class + ); + assertThat(promql.start().value(), equalTo(Instant.parse("2025-10-31T00:00:00Z"))); + assertThat(promql.end().value(), equalTo(Instant.parse("2025-10-31T01:00:00Z"))); + assertThat(promql.step().value(), equalTo(Duration.ofMinutes(1))); + assertThat(promql.isRangeQuery(), equalTo(true)); + assertThat(promql.isInstantQuery(), equalTo(false)); + } + + public void testValidRangeQueryOnlyStep() { + PromqlCommand promql = parse("TS test | PROMQL `step` \"1\" (avg(foo))"); + assertThat(promql.start().value(), nullValue()); + assertThat(promql.end().value(), nullValue()); + assertThat(promql.step().value(), equalTo(Duration.ofSeconds(1))); + assertThat(promql.isRangeQuery(), equalTo(true)); + assertThat(promql.isInstantQuery(), equalTo(false)); + } + + public void testValidInstantQuery() { + PromqlCommand promql = parse("TS test | PROMQL time \"2025-10-31T00:00:00Z\" (avg(foo))"); + assertThat(promql.start().value(), equalTo(Instant.parse("2025-10-31T00:00:00Z"))); + assertThat(promql.end().value(), equalTo(Instant.parse("2025-10-31T00:00:00Z"))); + assertThat(promql.step().value(), nullValue()); + assertThat(promql.isInstantQuery(), equalTo(true)); + assertThat(promql.isRangeQuery(), equalTo(false)); + } + + public void testValidRangeQueryInvalidQuotedIdentifierValue() { + ParsingException e = assertThrows(ParsingException.class, () -> parse("TS test | PROMQL step `1m` (avg(foo))")); + assertThat(e.getMessage(), containsString("1:23: Parameter value [`1m`] must not be a quoted identifier")); + } + + // TODO nicer error messages for missing params + public void testMissingParams() { + assertThrows(ParsingException.class, () -> parse("TS test | PROMQL (avg(foo))")); + } + + public void testZeroStep() { + ParsingException e = assertThrows(ParsingException.class, () -> parse("TS test | PROMQL step 0 (avg(foo))")); + assertThat( + e.getMessage(), + containsString( + "1:11: invalid parameter \"step\": zero or negative query resolution step widths are not accepted. " + + "Try a positive integer" + ) + ); + } + + public void testNegativeStep() { + ParsingException e = assertThrows(ParsingException.class, () -> parse("TS test | PROMQL step \"-1\" (avg(foo))")); + assertThat( + e.getMessage(), + containsString("invalid parameter \"step\": zero or negative query resolution step widths are not accepted") + ); + } + + public void testEndBeforeStart() { + ParsingException e = assertThrows( + ParsingException.class, + () -> parse("TS test | PROMQL start \"2025-10-31T01:00:00Z\" end \"2025-10-31T00:00:00Z\" step 1m (avg(foo))") + ); + assertThat(e.getMessage(), containsString("1:11: invalid parameter \"end\": end timestamp must not be before start time")); + } + + public void testInstantAndRangeParams() { + ParsingException e = assertThrows(ParsingException.class, () -> parse(""" + TS test + | PROMQL start "2025-10-31T00:00:00Z" end "2025-10-31T01:00:00Z" step 1m time "2025-10-31T00:00:00Z" ( + avg(foo) + )""")); + assertThat( + e.getMessage(), + containsString("2:4: Specify either [time] for instant query or [step], [start] or [end] for a range query") + ); + } + + public void testDuplicateParameter() { + ParsingException e = assertThrows(ParsingException.class, () -> parse("TS test | PROMQL step 1 step 2 (avg(foo))")); + assertThat(e.getMessage(), containsString("[step] already specified")); + } + + public void testUnknownParameter() { + ParsingException e = assertThrows(ParsingException.class, () -> parse("TS test | PROMQL stp 1 (avg(foo))")); + assertThat(e.getMessage(), containsString("Unknown parameter [stp], did you mean [step]?")); + } + + public void testUnknownParameterNoSuggestion() { + ParsingException e = assertThrows(ParsingException.class, () -> parse("TS test | PROMQL foo 1 (avg(foo))")); + assertThat(e.getMessage(), containsString("Unknown parameter [foo]")); + } + + public void testInvalidDateFormat() { + ParsingException e = assertThrows( + ParsingException.class, + () -> parse("TS test | PROMQL start \"not-a-date\" end \"2025-10-31T01:00:00Z\" step 1m (avg(foo))") + ); + assertThat(e.getMessage(), containsString("1:24: Invalid date format [not-a-date]")); + } + + public void testOnlyStartSpecified() { + ParsingException e = assertThrows( + ParsingException.class, + () -> parse("TS test | PROMQL start \"2025-10-31T00:00:00Z\" step 1m (avg(foo))") + ); + assertThat( + e.getMessage(), + containsString("Parameters [start] and [end] must either both be specified or both be omitted for a range query") + ); + } + + public void testOnlyEndSpecified() { + ParsingException e = assertThrows( + ParsingException.class, + () -> parse("TS test | PROMQL end \"2025-10-31T01:00:00Z\" step 1m (avg(foo))") + ); + assertThat( + e.getMessage(), + containsString("Parameters [start] and [end] must either both be specified or both be omitted for a range query") + ); + } + + public void testRangeQueryMissingStep() { + ParsingException e = assertThrows( + ParsingException.class, + () -> parse("TS test | PROMQL start \"2025-10-31T00:00:00Z\" end \"2025-10-31T01:00:00Z\" (avg(foo))") + ); + assertThat(e.getMessage(), containsString("Parameter [step] or [time] is required")); + } + + private static PromqlCommand parse(String query) { + return as(parser.createStatement(query), PromqlCommand.class); + } + + @Override + protected List filteredWarnings() { + return withDefaultLimitWarning(super.filteredWarnings()); + } + +} diff --git a/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/parser/promql/PromqlParserUtilsTests.java b/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/parser/promql/PromqlParserUtilsTests.java new file mode 100644 index 0000000000000..a52ac5663e878 --- /dev/null +++ b/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/parser/promql/PromqlParserUtilsTests.java @@ -0,0 +1,196 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +package org.elasticsearch.xpack.esql.parser.promql; + +import org.elasticsearch.core.Tuple; +import org.elasticsearch.test.ESTestCase; +import org.elasticsearch.xpack.esql.action.PromqlFeatures; +import org.elasticsearch.xpack.esql.core.tree.Source; +import org.elasticsearch.xpack.esql.parser.ParsingException; +import org.junit.BeforeClass; + +import java.time.Duration; +import java.util.List; +import java.util.function.Function; + +import static java.time.Duration.ofDays; +import static java.time.Duration.ofHours; +import static java.time.Duration.ofMillis; +import static java.time.Duration.ofMinutes; +import static java.time.Duration.ofSeconds; +import static java.util.Arrays.asList; +import static org.hamcrest.Matchers.containsString; +import static org.junit.Assume.assumeTrue; + +public class PromqlParserUtilsTests extends ESTestCase { + + @BeforeClass + public static void checkPromqlEnabled() { + assumeTrue("requires snapshot build with promql feature enabled", PromqlFeatures.isEnabled()); + } + + private Duration parseTimeValue(String value) { + return PromqlParserUtils.parseDuration(new Source(0, 0, value), value); + } + + private void invalidTimeValue(String value, String errorMessage) { + ParsingException exception = expectThrows(ParsingException.class, () -> parseTimeValue(value)); + assertThat(exception.getErrorMessage(), containsString(errorMessage)); + } + + public void testTimeValuePerUnit() throws Exception { + assertEquals(ofDays(365), parseTimeValue("1y")); + assertEquals(ofDays(7), parseTimeValue("1w")); + assertEquals(ofDays(1), parseTimeValue("1d")); + assertEquals(ofHours(1), parseTimeValue("1h")); + assertEquals(ofMinutes(1), parseTimeValue("1m")); + assertEquals(ofSeconds(1), parseTimeValue("1s")); + assertEquals(ofMillis(1), parseTimeValue("1ms")); + } + + public void testTimeValueCombined() throws Exception { + assertEquals(ofDays(365).plus(ofDays(14)), parseTimeValue("1y2w")); + assertEquals(ofDays(365).plus(ofDays(3)), parseTimeValue("1y3d")); + assertEquals(ofDays(365).plus(ofHours(4)), parseTimeValue("1y4h")); + assertEquals(ofDays(365).plus(ofMinutes(5)), parseTimeValue("1y5m")); + assertEquals(ofDays(365).plus(ofSeconds(6)), parseTimeValue("1y6s")); + assertEquals(ofDays(365).plus(ofMillis(7)), parseTimeValue("1y7ms")); + + assertEquals(ofDays(365).plus(ofDays(14)).plus(ofDays(3)), parseTimeValue("1y2w3d")); + + assertEquals(ofDays(365).plus(ofDays(3)).plus(ofHours(4)), parseTimeValue("1y3d4h")); + + assertEquals(ofDays(365).plus(ofMinutes(5)).plus(ofSeconds(6)), parseTimeValue("1y5m6s")); + + assertEquals( + ofDays(365).plus(ofDays(7)).plus(ofDays(1)).plus(ofHours(1)).plus(ofMinutes(1)).plus(ofSeconds(1)).plus(ofMillis(1)), + parseTimeValue("1y1w1d1h1m1s1ms") + ); + + } + + public void testTimeValueRandomCombination() throws Exception { + // lambdas generating duration for each time unit (identified by its list index) + List>> generators = asList( + new Tuple<>("y", n -> ofDays(365 * n)), + new Tuple<>("w", n -> ofDays(7 * n)), + new Tuple<>("d", Duration::ofDays), + new Tuple<>("h", Duration::ofHours), + new Tuple<>("m", Duration::ofMinutes), + new Tuple<>("s", Duration::ofSeconds), + new Tuple<>("ms", Duration::ofMillis) + ); + // iterate using a random step through list pick a random number of units from the list by iterating with a random step + int maximum = generators.size() - 1; + StringBuilder timeString = new StringBuilder(); + long millis = 0; + + for (int position = -1; position < maximum;) { + int step = randomIntBetween(1, maximum - position); + position += step; + Tuple> tuple = generators.get(position); + int number = randomInt(128); + timeString.append(number); + timeString.append(tuple.v1()); + millis += tuple.v2().apply(number).toMillis(); + } + + assertEquals(ofMillis(millis), parseTimeValue(timeString.toString())); + } + + public void testTimeValueErrorNoNumber() throws Exception { + String error = "no number specified at"; + List values = asList("d", " y"); + for (String value : values) { + invalidTimeValue(value, error); + } + } + + public void testTimeValueErrorNoUnit() throws Exception { + String error = "no unit specified at"; + List values = asList("234/", "12-", "1y1"); + for (String value : values) { + invalidTimeValue(value, error); + } + } + + public void testTimeValueErrorInvalidUnit() throws Exception { + String error = "unrecognized time unit"; + List values = asList("1o", "234sd", "1dd"); + for (String value : values) { + invalidTimeValue(value, error); + } + } + + public void testTimeValueErrorUnitOrder() throws Exception { + String error = "units must be ordered from the longest to the shortest"; + List values = asList("1w1y", "1y1w1h1m1h", "1y1w1y"); + for (String value : values) { + invalidTimeValue(value, error); + } + } + + public void testTimeValueErrorUnitDuplicated() throws Exception { + String error = "a given unit must only appear once"; + List values = asList("1w1w", "1y1w1d1d"); + for (String value : values) { + invalidTimeValue(value, error); + } + } + + // + // Go escaping rules + // + private String unquote(String value) { + return PromqlParserUtils.unquote(new Source(0, 0, value)); + } + + private void invalidString(String value, String errorMessage) { + ParsingException exception = expectThrows(ParsingException.class, () -> unquote(value)); + assertThat(exception.getErrorMessage(), containsString(errorMessage)); + } + + private String quote(String unquote) { + char c = randomBoolean() ? '"' : '\''; + return c + unquote + c; + } + + public void testGoRuneLiteralsHex() throws Exception { + assertEquals("#", unquote(quote("\\x23"))); + assertEquals("#4", unquote(quote("\\x234"))); + assertEquals("a#4", unquote(quote("a\\x234"))); + + assertEquals("#", unquote(quote("\\u0023"))); + assertEquals("#4", unquote(quote("\\u00234"))); + + assertEquals("#", unquote(quote("\\U00000023"))); + assertEquals("#4", unquote(quote("\\U000000234"))); + } + + public void testGoRuneLiteralsErrorHex() throws Exception { + String error = "Invalid unicode character code"; + List values = asList("\\xAG", "a\\xXA", "\\u123G", "u\\uX23G", "\\U1234567X", "AB\\U1234567X", "\\xff"); + for (String value : values) { + invalidString(quote(value), error); + } + } + + public void testGoRuneLiteralsOct() throws Exception { + assertEquals("#", unquote(quote("\\043"))); + assertEquals("#4", unquote(quote("\\0434"))); + assertEquals("a#4", unquote(quote("a\\0434"))); + } + + public void testGoRuneLiteralsErrorOct() throws Exception { + String error = "Invalid unicode character code"; + List values = asList("901", "0909"); + for (String value : values) { + invalidString(quote("\\" + value), error); + } + } +} diff --git a/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/telemetry/VerifierMetricsTests.java b/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/telemetry/VerifierMetricsTests.java index 258349e8d2e7a..c3f679da49bf5 100644 --- a/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/telemetry/VerifierMetricsTests.java +++ b/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/telemetry/VerifierMetricsTests.java @@ -39,6 +39,7 @@ import static org.elasticsearch.xpack.esql.telemetry.FeatureMetric.LOOKUP_JOIN; import static org.elasticsearch.xpack.esql.telemetry.FeatureMetric.LOOKUP_JOIN_ON_EXPRESSION; import static org.elasticsearch.xpack.esql.telemetry.FeatureMetric.MV_EXPAND; +import static org.elasticsearch.xpack.esql.telemetry.FeatureMetric.PROMQL; import static org.elasticsearch.xpack.esql.telemetry.FeatureMetric.RENAME; import static org.elasticsearch.xpack.esql.telemetry.FeatureMetric.ROW; import static org.elasticsearch.xpack.esql.telemetry.FeatureMetric.SHOW; @@ -61,6 +62,7 @@ public void testDissectQuery() { assertEquals(0, limit(c)); assertEquals(0, sort(c)); assertEquals(0, stats(c)); + assertEquals(0, promql(c)); assertEquals(0, where(c)); assertEquals(0, enrich(c)); assertEquals(0, mvExpand(c)); @@ -86,6 +88,7 @@ public void testEvalQuery() { assertEquals(0, limit(c)); assertEquals(0, sort(c)); assertEquals(0, stats(c)); + assertEquals(0, promql(c)); assertEquals(0, where(c)); assertEquals(0, enrich(c)); assertEquals(0, mvExpand(c)); @@ -111,6 +114,7 @@ public void testGrokQuery() { assertEquals(0, limit(c)); assertEquals(0, sort(c)); assertEquals(0, stats(c)); + assertEquals(0, promql(c)); assertEquals(0, where(c)); assertEquals(0, enrich(c)); assertEquals(0, mvExpand(c)); @@ -136,6 +140,7 @@ public void testLimitQuery() { assertEquals(1L, limit(c)); assertEquals(0, sort(c)); assertEquals(0, stats(c)); + assertEquals(0, promql(c)); assertEquals(0, where(c)); assertEquals(0, enrich(c)); assertEquals(0, mvExpand(c)); @@ -160,6 +165,7 @@ public void testSortQuery() { assertEquals(0, limit(c)); assertEquals(1L, sort(c)); assertEquals(0, stats(c)); + assertEquals(0, promql(c)); assertEquals(0, where(c)); assertEquals(0, enrich(c)); assertEquals(0, mvExpand(c)); @@ -184,6 +190,7 @@ public void testStatsQuery() { assertEquals(0, limit(c)); assertEquals(0, sort(c)); assertEquals(1L, stats(c)); + assertEquals(0, promql(c)); assertEquals(0, where(c)); assertEquals(0, enrich(c)); assertEquals(0, mvExpand(c)); @@ -209,6 +216,7 @@ public void testWhereQuery() { assertEquals(0, limit(c)); assertEquals(0, sort(c)); assertEquals(0, stats(c)); + assertEquals(0, promql(c)); assertEquals(1L, where(c)); assertEquals(0, enrich(c)); assertEquals(0, mvExpand(c)); @@ -233,6 +241,7 @@ public void testTwoWhereQuery() { assertEquals(1L, limit(c)); assertEquals(1L, sort(c)); assertEquals(0, stats(c)); + assertEquals(0, promql(c)); assertEquals(1L, where(c)); assertEquals(0, enrich(c)); assertEquals(0, mvExpand(c)); @@ -277,6 +286,7 @@ public void testTwoQueriesExecuted() { assertEquals(1L, limit(c)); assertEquals(2L, sort(c)); assertEquals(1L, stats(c)); + assertEquals(0, promql(c)); assertEquals(2L, where(c)); assertEquals(0, enrich(c)); assertEquals(0, mvExpand(c)); @@ -365,6 +375,7 @@ public void testEnrich() { assertEquals(1L, limit(c)); assertEquals(1L, sort(c)); assertEquals(0, stats(c)); + assertEquals(0, promql(c)); assertEquals(0, where(c)); assertEquals(1L, enrich(c)); assertEquals(0, mvExpand(c)); @@ -399,6 +410,7 @@ public void testMvExpand() { assertEquals(1L, limit(c)); assertEquals(0, sort(c)); assertEquals(0, stats(c)); + assertEquals(0, promql(c)); assertEquals(1L, where(c)); assertEquals(0, enrich(c)); assertEquals(1L, mvExpand(c)); @@ -423,6 +435,7 @@ public void testShowInfo() { assertEquals(0, limit(c)); assertEquals(0, sort(c)); assertEquals(1L, stats(c)); + assertEquals(0, promql(c)); assertEquals(0, where(c)); assertEquals(0, enrich(c)); assertEquals(1L, mvExpand(c)); @@ -448,6 +461,7 @@ public void testRow() { assertEquals(0, limit(c)); assertEquals(0, sort(c)); assertEquals(0, stats(c)); + assertEquals(0, promql(c)); assertEquals(0, where(c)); assertEquals(1L, enrich(c)); assertEquals(0, mvExpand(c)); @@ -472,6 +486,7 @@ public void testDropAndRename() { assertEquals(0, limit(c)); assertEquals(1L, sort(c)); assertEquals(1L, stats(c)); + assertEquals(0, promql(c)); assertEquals(0, where(c)); assertEquals(0, enrich(c)); assertEquals(0, mvExpand(c)); @@ -502,6 +517,7 @@ public void testKeep() { assertEquals(0, limit(c)); assertEquals(0, sort(c)); assertEquals(0, stats(c)); + assertEquals(0, promql(c)); assertEquals(1L, where(c)); assertEquals(0, enrich(c)); assertEquals(0, mvExpand(c)); @@ -530,6 +546,7 @@ public void testCategorize() { assertEquals(0, limit(c)); assertEquals(0, sort(c)); assertEquals(1L, stats(c)); + assertEquals(0, promql(c)); assertEquals(1L, where(c)); assertEquals(0, enrich(c)); assertEquals(0, mvExpand(c)); @@ -560,6 +577,7 @@ public void testInlineStatsStandalone() { assertEquals(0, limit(c)); assertEquals(0, sort(c)); assertEquals(0, stats(c)); + assertEquals(0, promql(c)); assertEquals(1L, where(c)); assertEquals(0, enrich(c)); assertEquals(0, mvExpand(c)); @@ -590,6 +608,7 @@ public void testInlineStatsWithOtherStats() { assertEquals(0, limit(c)); assertEquals(0, sort(c)); assertEquals(1L, stats(c)); + assertEquals(0, promql(c)); assertEquals(1L, where(c)); assertEquals(0, enrich(c)); assertEquals(0, mvExpand(c)); @@ -619,6 +638,7 @@ public void testBinaryPlanAfterStats() { assertEquals(0, limit(c)); assertEquals(0, sort(c)); assertEquals(1L, stats(c)); + assertEquals(0, promql(c)); assertEquals(0, where(c)); assertEquals(0, enrich(c)); assertEquals(0, mvExpand(c)); @@ -653,6 +673,7 @@ public void testBinaryPlanAfterStatsExpressionJoin() { assertEquals(0, limit(c)); assertEquals(0, sort(c)); assertEquals(1L, stats(c)); + assertEquals(0, promql(c)); assertEquals(0, where(c)); assertEquals(0, enrich(c)); assertEquals(0, mvExpand(c)); @@ -683,6 +704,7 @@ public void testBinaryPlanAfterInlineStats() { assertEquals(0, limit(c)); assertEquals(0, sort(c)); assertEquals(0, stats(c)); + assertEquals(0, promql(c)); assertEquals(0, where(c)); assertEquals(0, enrich(c)); assertEquals(0, mvExpand(c)); @@ -711,6 +733,7 @@ public void testTimeSeriesAggregate() { assertEquals(0, limit(c)); assertEquals(0, sort(c)); assertEquals(1L, stats(c)); + assertEquals(0, promql(c)); assertEquals(0, where(c)); assertEquals(0, enrich(c)); assertEquals(0, mvExpand(c)); @@ -740,6 +763,7 @@ public void testTimeSeriesNoAggregate() { assertEquals(0, limit(c)); assertEquals(0, sort(c)); assertEquals(0, stats(c)); + assertEquals(0, promql(c)); assertEquals(0, where(c)); assertEquals(0, enrich(c)); assertEquals(0, mvExpand(c)); @@ -771,6 +795,7 @@ public void testBinaryPlanAfterSubqueryInFromCommand() { assertEquals(0, limit(c)); assertEquals(0, sort(c)); assertEquals(1L, stats(c)); + assertEquals(0, promql(c)); assertEquals(1L, where(c)); assertEquals(0, enrich(c)); assertEquals(0, mvExpand(c)); @@ -789,6 +814,35 @@ public void testBinaryPlanAfterSubqueryInFromCommand() { assertEquals(1L, function("min", c)); } + @AwaitsFix(bugUrl = "unresolved @timestamp field") + public void testPromql() { + assumeTrue("PromQL required", EsqlCapabilities.Cap.PROMQL_V0.isEnabled()); + Counters c = esql(""" + TS metrics + | PROMQL step 5m (sum(salary))"""); + assertEquals(0, dissect(c)); + assertEquals(0, eval(c)); + assertEquals(0, grok(c)); + assertEquals(0, limit(c)); + assertEquals(0, sort(c)); + assertEquals(0, stats(c)); + assertEquals(1, promql(c)); + assertEquals(0, where(c)); + assertEquals(0, enrich(c)); + assertEquals(0, mvExpand(c)); + assertEquals(0, show(c)); + assertEquals(0, row(c)); + assertEquals(0, from(c)); + assertEquals(1L, ts(c)); + assertEquals(0, drop(c)); + assertEquals(0, keep(c)); + assertEquals(0, rename(c)); + assertEquals(0, inlineStats(c)); + assertEquals(0, lookupJoinOnFields(c)); + assertEquals(0, lookupJoinOnExpression(c)); + assertEquals(0, subqueryInFromCommand(c)); + } + private long dissect(Counters c) { return c.get(FEATURES_PREFIX + DISSECT); } @@ -841,6 +895,10 @@ private long ts(Counters c) { return c.get(FEATURES_PREFIX + TS); } + private long promql(Counters c) { + return c.get(FEATURES_PREFIX + PROMQL); + } + private long drop(Counters c) { return c.get(FEATURES_PREFIX + DROP); } diff --git a/x-pack/plugin/src/yamlRestTest/resources/rest-api-spec/test/esql/60_usage.yml b/x-pack/plugin/src/yamlRestTest/resources/rest-api-spec/test/esql/60_usage.yml index cfc20aa43f8ba..b2d9f6611449d 100644 --- a/x-pack/plugin/src/yamlRestTest/resources/rest-api-spec/test/esql/60_usage.yml +++ b/x-pack/plugin/src/yamlRestTest/resources/rest-api-spec/test/esql/60_usage.yml @@ -58,12 +58,13 @@ setup: - ts_command_v0 - cosine_vector_similarity_function - inline_stats + - promql_v0 reason: "Test that should only be executed on snapshot versions" - do: { xpack.usage: { } } - match: { esql.available: true } - match: { esql.enabled: true } - - length: { esql.features: 29 } + - length: { esql.features: 30 } - set: { esql.features.dissect: dissect_counter } - set: { esql.features.drop: drop_counter } - set: { esql.features.eval: eval_counter } @@ -79,6 +80,7 @@ setup: - set: { esql.features.show: show_counter } - set: { esql.features.sort: sort_counter } - set: { esql.features.stats: stats_counter } + - set: { esql.features.promql: promql_counter } - set: { esql.features.where: where_counter } - set: { esql.features.lookup_join: lookup_join_counter } - set: { esql.features.lookup_join_on_expression: lookup_join_on_expression_counter }