ソースを参照

ESQL: Add OPTIONS clause to FROM command (#106636)

This adds an OPTIONS clause to FROM, allowing to specify search or index
resolution options, such as: preference, allow_no_indices or
ignore_unavailable.
Bogdan Pintea 1 年間 前
コミット
aeeb5979ed
32 ファイル変更1930 行追加1101 行削除
  1. 5 0
      docs/changelog/106636.yaml
  2. 1 0
      server/src/main/java/org/elasticsearch/TransportVersions.java
  3. 1 1
      x-pack/plugin/esql/qa/server/multi-clusters/src/javaRestTest/java/org/elasticsearch/xpack/esql/ccq/MultiClusterSpecIT.java
  4. 49 0
      x-pack/plugin/esql/qa/server/multi-clusters/src/javaRestTest/java/org/elasticsearch/xpack/esql/ccq/MultiClustersIT.java
  5. 80 0
      x-pack/plugin/esql/qa/server/src/main/java/org/elasticsearch/xpack/esql/qa/rest/RestEsqlTestCase.java
  6. 15 0
      x-pack/plugin/esql/qa/testFixtures/src/main/resources/from.csv-spec
  7. 4 2
      x-pack/plugin/esql/src/main/antlr/EsqlBaseLexer.g4
  8. 48 46
      x-pack/plugin/esql/src/main/antlr/EsqlBaseLexer.tokens
  9. 15 6
      x-pack/plugin/esql/src/main/antlr/EsqlBaseParser.g4
  10. 48 46
      x-pack/plugin/esql/src/main/antlr/EsqlBaseParser.tokens
  11. 2 1
      x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/analysis/Analyzer.java
  12. 11 4
      x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/analysis/PreAnalyzer.java
  13. 12 1
      x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/io/stream/PlanNamedTypes.java
  14. 6 2
      x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/parser/EsqlBaseLexer.interp
  15. 738 727
      x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/parser/EsqlBaseLexer.java
  16. 6 2
      x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/parser/EsqlBaseParser.interp
  17. 371 173
      x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/parser/EsqlBaseParser.java
  18. 36 12
      x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/parser/EsqlBaseParserBaseListener.java
  19. 21 7
      x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/parser/EsqlBaseParserBaseVisitor.java
  20. 30 10
      x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/parser/EsqlBaseParserListener.java
  21. 18 6
      x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/parser/EsqlBaseParserVisitor.java
  22. 16 1
      x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/parser/LogicalPlanBuilder.java
  23. 27 4
      x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/plan/logical/EsqlUnresolvedRelation.java
  24. 7 0
      x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/planner/PlannerUtils.java
  25. 49 31
      x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/plugin/ComputeService.java
  26. 6 1
      x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/plugin/EsqlFeatures.java
  27. 10 5
      x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/session/EsqlIndexResolver.java
  28. 7 3
      x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/session/EsqlSession.java
  29. 35 3
      x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/io/stream/PlanNamedTypesTests.java
  30. 103 1
      x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/parser/StatementParserTests.java
  31. 135 0
      x-pack/plugin/ql/src/main/java/org/elasticsearch/xpack/ql/options/EsSourceOptions.java
  32. 18 6
      x-pack/plugin/ql/src/main/java/org/elasticsearch/xpack/ql/plan/logical/EsRelation.java

+ 5 - 0
docs/changelog/106636.yaml

@@ -0,0 +1,5 @@
+pr: 106636
+summary: "ESQL: Add OPTIONS clause to FROM command"
+area: ES|QL
+type: enhancement
+issues: []

+ 1 - 0
server/src/main/java/org/elasticsearch/TransportVersions.java

@@ -155,6 +155,7 @@ public class TransportVersions {
     public static final TransportVersion ML_INFERENCE_EMBEDDING_BYTE_ADDED = def(8_615_00_0);
     public static final TransportVersion ML_INFERENCE_L2_NORM_SIMILARITY_ADDED = def(8_616_00_0);
     public static final TransportVersion SEARCH_NODE_LOAD_AUTOSCALING = def(8_617_00_0);
+    public static final TransportVersion ESQL_ES_SOURCE_OPTIONS = def(8_618_00_0);
 
     /*
      * STOP! READ THIS FIRST! No, really,

+ 1 - 1
x-pack/plugin/esql/qa/server/multi-clusters/src/javaRestTest/java/org/elasticsearch/xpack/esql/ccq/MultiClusterSpecIT.java

@@ -192,7 +192,7 @@ public class MultiClusterSpecIT extends EsqlSpecTestCase {
         String first = commands[0].trim();
 
         if (commands[0].toLowerCase(Locale.ROOT).startsWith("from")) {
-            String[] parts = commands[0].split("(?i)metadata");
+            String[] parts = commands[0].split("(?i)(metadata|options)");
             assert parts.length >= 1 : parts;
             String fromStatement = parts[0];
 

+ 49 - 0
x-pack/plugin/esql/qa/server/multi-clusters/src/javaRestTest/java/org/elasticsearch/xpack/esql/ccq/MultiClustersIT.java

@@ -17,6 +17,7 @@ import org.elasticsearch.common.settings.Settings;
 import org.elasticsearch.test.TestClustersThreadFilter;
 import org.elasticsearch.test.cluster.ElasticsearchCluster;
 import org.elasticsearch.test.rest.ESRestTestCase;
+import org.elasticsearch.test.rest.TestFeatureService;
 import org.elasticsearch.xpack.esql.qa.rest.RestEsqlTestCase;
 import org.junit.After;
 import org.junit.Before;
@@ -27,6 +28,7 @@ import org.junit.rules.TestRule;
 import java.io.IOException;
 import java.util.List;
 import java.util.Map;
+import java.util.Optional;
 import java.util.stream.Collectors;
 import java.util.stream.IntStream;
 import java.util.stream.Stream;
@@ -42,6 +44,8 @@ public class MultiClustersIT extends ESRestTestCase {
     @ClassRule
     public static TestRule clusterRule = RuleChain.outerRule(remoteCluster).around(localCluster);
 
+    private static TestFeatureService remoteFeaturesService;
+
     @Override
     protected String getTestRestCluster() {
         return localCluster.getHttpAddresses();
@@ -152,6 +156,34 @@ public class MultiClustersIT extends ESRestTestCase {
         }
     }
 
+    public void testCountWithOptions() throws Exception {
+        assumeTrue("remote cluster requires FROM OPTIONS support", remoteFeaturesService().clusterHasFeature("esql.from_options"));
+        {
+            Map<String, Object> result = run(
+                "FROM test-local-index,*:test-remote-index,doesnotexist "
+                    + "OPTIONS \"ignore_unavailable\"=\"true\",\"preference\"=\"_local\" | STATS c = COUNT(*)"
+            );
+            var columns = List.of(Map.of("name", "c", "type", "long"));
+            var values = List.of(List.of(localDocs.size() + remoteDocs.size()));
+            assertMap(result, matchesMap().entry("columns", columns).entry("values", values));
+        }
+        {
+            Map<String, Object> result = run(
+                "FROM *:test-remote-index,doesnotexit OPTIONS \"ignore_unavailable\"=\"true\",\"preference\"=\"_local\" "
+                    + "| STATS c = COUNT(*)"
+            );
+            var columns = List.of(Map.of("name", "c", "type", "long"));
+            var values = List.of(List.of(remoteDocs.size()));
+            assertMap(result, matchesMap().entry("columns", columns).entry("values", values));
+        }
+        {
+            Map<String, Object> result = run("FROM *:test-remote-index OPTIONS \"preference\"=\"_shards:999\" | STATS c = COUNT(*)");
+            var columns = List.of(Map.of("name", "c", "type", "long"));
+            var values = List.of(List.of(0)); // shard with id 999 above (non-existent) yields count 0
+            assertMap(result, matchesMap().entry("columns", columns).entry("values", values));
+        }
+    }
+
     public void testUngroupedAggs() throws Exception {
         {
             Map<String, Object> result = run("FROM test-local-index,*:test-remote-index | STATS total = SUM(data)");
@@ -200,4 +232,21 @@ public class MultiClustersIT extends ESRestTestCase {
         var clusterHosts = parseClusterHosts(remoteCluster.getHttpAddresses());
         return buildClient(restClientSettings(), clusterHosts.toArray(new HttpHost[0]));
     }
+
+    private TestFeatureService remoteFeaturesService() throws IOException {
+        if (remoteFeaturesService == null) {
+            try (var remoteFeaturesServiceClient = remoteClusterClient()) {
+                var remoteNodeVersions = readVersionsFromNodesInfo(remoteFeaturesServiceClient);
+                var semanticNodeVersions = remoteNodeVersions.stream()
+                    .map(ESRestTestCase::parseLegacyVersion)
+                    .flatMap(Optional::stream)
+                    .collect(Collectors.toSet());
+                remoteFeaturesService = createTestFeatureService(
+                    getClusterStateFeatures(remoteFeaturesServiceClient),
+                    semanticNodeVersions
+                );
+            }
+        }
+        return remoteFeaturesService;
+    }
 }

+ 80 - 0
x-pack/plugin/esql/qa/server/src/main/java/org/elasticsearch/xpack/esql/qa/rest/RestEsqlTestCase.java

@@ -16,10 +16,12 @@ import org.elasticsearch.client.RequestOptions;
 import org.elasticsearch.client.Response;
 import org.elasticsearch.client.ResponseException;
 import org.elasticsearch.client.WarningsHandler;
+import org.elasticsearch.common.Strings;
 import org.elasticsearch.common.bytes.BytesArray;
 import org.elasticsearch.common.io.Streams;
 import org.elasticsearch.common.settings.Settings;
 import org.elasticsearch.common.xcontent.XContentHelper;
+import org.elasticsearch.core.CheckedFunction;
 import org.elasticsearch.core.Nullable;
 import org.elasticsearch.core.TimeValue;
 import org.elasticsearch.logging.LogManager;
@@ -215,6 +217,84 @@ public abstract class RestEsqlTestCase extends ESRestTestCase {
         assertThat(e.getMessage(), containsString("Unknown index [doesNotExist]"));
     }
 
+    public void testUseKnownIndexWithUnknownIndex() throws IOException {
+        // to ignore a concrete non-existent index, we need to opt in (which is not the default)
+        useKnownIndexWithOther("noSuchIndex", "ignore_unavailable");
+    }
+
+    public void testUseKnownIndexWithUnknownPattern() throws IOException {
+        // to not ignore a non-existing index, we need to opt in (which is the default)
+        useKnownIndexWithOther("noSuchPattern*", "allow_no_indices");
+    }
+
+    private void useKnownIndexWithOther(String other, String option) throws IOException {
+        final int count = randomIntBetween(1, 10);
+        bulkLoadTestData(count);
+
+        CheckedFunction<Boolean, RequestObjectBuilder, IOException> builder = o -> {
+            String q = fromIndex() + ',' + other;
+            q += " OPTIONS \"" + option + "\"=\"" + o + "\"";
+            q += " | KEEP keyword, integer | SORT integer asc | LIMIT 10";
+            return builder().query(q);
+        };
+
+        // test failure
+        ResponseException e = expectThrows(ResponseException.class, () -> runEsql(builder.apply(false)));
+        assertEquals(404, e.getResponse().getStatusLine().getStatusCode());
+        assertThat(e.getMessage(), containsString("no such index [" + other + "]"));
+
+        // test success
+        assertEquals(expectedTextBody("txt", count, null), runEsqlAsTextWithFormat(builder.apply(true), "txt", null));
+    }
+
+    // https://github.com/elastic/elasticsearch/issues/106805
+    public void testUseUnknownIndexOnly() {
+        useUnknownIndex("ignore_unavailable");
+        useUnknownIndex("allow_no_indices");
+    }
+
+    private void useUnknownIndex(String option) {
+        CheckedFunction<Boolean, RequestObjectBuilder, IOException> builder = o -> {
+            String q = "FROM doesnotexist OPTIONS \"" + option + "\"=\"" + o + "\"";
+            q += " | KEEP keyword, integer | SORT integer asc | LIMIT 10";
+            return builder().query(q);
+        };
+
+        // test failure 404 from resolver
+        ResponseException e = expectThrows(ResponseException.class, () -> runEsql(builder.apply(false)));
+        assertEquals(404, e.getResponse().getStatusLine().getStatusCode());
+        assertThat(e.getMessage(), containsString("index_not_found_exception"));
+        assertThat(e.getMessage(), containsString("no such index [doesnotexist]"));
+
+        // test failure 400 from verifier
+        e = expectThrows(ResponseException.class, () -> runEsql(builder.apply(true)));
+        assertEquals(400, e.getResponse().getStatusLine().getStatusCode());
+        assertThat(e.getMessage(), containsString("verification_exception"));
+        assertThat(e.getMessage(), containsString("Unknown index [doesnotexist]"));
+
+    }
+
+    public void testSearchPreference() throws IOException {
+        final int count = randomIntBetween(1, 10);
+        bulkLoadTestData(count);
+
+        CheckedFunction<String, RequestObjectBuilder, IOException> builder = o -> {
+            String q = fromIndex();
+            if (Strings.hasText(o)) {
+                q += " OPTIONS " + o;
+            }
+            q += " | KEEP keyword, integer | SORT integer asc | LIMIT 10";
+            return builder().query(q);
+        };
+
+        // verify that it returns as expected
+        assertEquals(expectedTextBody("txt", count, null), runEsqlAsTextWithFormat(builder.apply(null), "txt", null));
+
+        // returns nothing (0 for count), given the non-existing shard as preference
+        String option = "\"preference\"=\"_shards:666\"";
+        assertEquals(expectedTextBody("txt", 0, null), runEsqlAsTextWithFormat(builder.apply(option), "txt", null));
+    }
+
     public void testNullInAggs() throws IOException {
         StringBuilder b = new StringBuilder();
         for (int i = 0; i < 1000; i++) {

+ 15 - 0
x-pack/plugin/esql/qa/testFixtures/src/main/resources/id.csv-spec → x-pack/plugin/esql/qa/testFixtures/src/main/resources/from.csv-spec

@@ -128,3 +128,18 @@ c:l | name:k
 1   | ddddd
 1   | eeeee
 ;
+
+convertFromDatetimeWithOptions
+required_feature: esql.from_options
+
+  FROM employees OPTIONS "allow_no_indices"="false","preference"="_shards:0"
+| SORT emp_no
+| EVAL hire_double = to_double(hire_date)
+| KEEP emp_no, hire_date, hire_double
+| LIMIT 3;
+
+emp_no:integer |hire_date:date          |hire_double:double
+10001          |1986-06-26T00:00:00.000Z|5.20128E11
+10002          |1985-11-21T00:00:00.000Z|5.013792E11
+10003          |1986-08-28T00:00:00.000Z|5.255712E11
+;

+ 4 - 2
x-pack/plugin/esql/src/main/antlr/EsqlBaseLexer.g4

@@ -89,7 +89,7 @@ fragment UNQUOTED_ID_BODY
     : (LETTER | DIGIT | UNDERSCORE)
     ;
 
-STRING
+QUOTED_STRING
     : '"' (ESCAPE_SEQUENCE | UNESCAPED_CHARS)* '"'
     | '"""' (~[\r\n])*? '"""' '"'? '"'?
     ;
@@ -186,8 +186,10 @@ FROM_OPENING_BRACKET : OPENING_BRACKET -> type(OPENING_BRACKET);
 FROM_CLOSING_BRACKET : CLOSING_BRACKET -> type(CLOSING_BRACKET);
 FROM_COMMA : COMMA -> type(COMMA);
 FROM_ASSIGN : ASSIGN -> type(ASSIGN);
+FROM_QUOTED_STRING : QUOTED_STRING -> type(QUOTED_STRING);
 
-METADATA: 'metadata';
+OPTIONS : 'options';
+METADATA : 'metadata';
 
 fragment FROM_UNQUOTED_IDENTIFIER_PART
     : ~[=`|,[\]/ \t\r\n]

+ 48 - 46
x-pack/plugin/esql/src/main/antlr/EsqlBaseLexer.tokens

@@ -24,7 +24,7 @@ EXPLAIN_WS=23
 EXPLAIN_LINE_COMMENT=24
 EXPLAIN_MULTILINE_COMMENT=25
 PIPE=26
-STRING=27
+QUOTED_STRING=27
 INTEGER_LITERAL=28
 DECIMAL_LITERAL=29
 BY=30
@@ -68,44 +68,45 @@ QUOTED_IDENTIFIER=67
 EXPR_LINE_COMMENT=68
 EXPR_MULTILINE_COMMENT=69
 EXPR_WS=70
-METADATA=71
-FROM_UNQUOTED_IDENTIFIER=72
-FROM_LINE_COMMENT=73
-FROM_MULTILINE_COMMENT=74
-FROM_WS=75
-ID_PATTERN=76
-PROJECT_LINE_COMMENT=77
-PROJECT_MULTILINE_COMMENT=78
-PROJECT_WS=79
-AS=80
-RENAME_LINE_COMMENT=81
-RENAME_MULTILINE_COMMENT=82
-RENAME_WS=83
-ON=84
-WITH=85
-ENRICH_POLICY_NAME=86
-ENRICH_LINE_COMMENT=87
-ENRICH_MULTILINE_COMMENT=88
-ENRICH_WS=89
-ENRICH_FIELD_LINE_COMMENT=90
-ENRICH_FIELD_MULTILINE_COMMENT=91
-ENRICH_FIELD_WS=92
-MVEXPAND_LINE_COMMENT=93
-MVEXPAND_MULTILINE_COMMENT=94
-MVEXPAND_WS=95
-INFO=96
-SHOW_LINE_COMMENT=97
-SHOW_MULTILINE_COMMENT=98
-SHOW_WS=99
-FUNCTIONS=100
-META_LINE_COMMENT=101
-META_MULTILINE_COMMENT=102
-META_WS=103
-COLON=104
-SETTING=105
-SETTING_LINE_COMMENT=106
-SETTTING_MULTILINE_COMMENT=107
-SETTING_WS=108
+OPTIONS=71
+METADATA=72
+FROM_UNQUOTED_IDENTIFIER=73
+FROM_LINE_COMMENT=74
+FROM_MULTILINE_COMMENT=75
+FROM_WS=76
+ID_PATTERN=77
+PROJECT_LINE_COMMENT=78
+PROJECT_MULTILINE_COMMENT=79
+PROJECT_WS=80
+AS=81
+RENAME_LINE_COMMENT=82
+RENAME_MULTILINE_COMMENT=83
+RENAME_WS=84
+ON=85
+WITH=86
+ENRICH_POLICY_NAME=87
+ENRICH_LINE_COMMENT=88
+ENRICH_MULTILINE_COMMENT=89
+ENRICH_WS=90
+ENRICH_FIELD_LINE_COMMENT=91
+ENRICH_FIELD_MULTILINE_COMMENT=92
+ENRICH_FIELD_WS=93
+MVEXPAND_LINE_COMMENT=94
+MVEXPAND_MULTILINE_COMMENT=95
+MVEXPAND_WS=96
+INFO=97
+SHOW_LINE_COMMENT=98
+SHOW_MULTILINE_COMMENT=99
+SHOW_WS=100
+FUNCTIONS=101
+META_LINE_COMMENT=102
+META_MULTILINE_COMMENT=103
+META_WS=104
+COLON=105
+SETTING=106
+SETTING_LINE_COMMENT=107
+SETTTING_MULTILINE_COMMENT=108
+SETTING_WS=109
 'dissect'=1
 'drop'=2
 'enrich'=3
@@ -160,10 +161,11 @@ SETTING_WS=108
 '/'=62
 '%'=63
 ']'=65
-'metadata'=71
-'as'=80
-'on'=84
-'with'=85
-'info'=96
-'functions'=100
-':'=104
+'options'=71
+'metadata'=72
+'as'=81
+'on'=85
+'with'=86
+'info'=97
+'functions'=101
+':'=105

+ 15 - 6
x-pack/plugin/esql/src/main/antlr/EsqlBaseParser.g4

@@ -99,7 +99,20 @@ field
     ;
 
 fromCommand
-    : FROM fromIdentifier (COMMA fromIdentifier)* metadata?
+    : FROM fromIdentifier (COMMA fromIdentifier)* fromOptions? metadata?
+    ;
+
+fromIdentifier
+    : FROM_UNQUOTED_IDENTIFIER
+    | QUOTED_IDENTIFIER
+    ;
+
+fromOptions
+    : OPTIONS configOption (COMMA configOption)*
+    ;
+
+configOption
+    : string ASSIGN string
     ;
 
 metadata
@@ -127,10 +140,6 @@ inlinestatsCommand
     : INLINESTATS stats=fields (BY grouping=fields)?
     ;
 
-fromIdentifier
-    : FROM_UNQUOTED_IDENTIFIER
-    | QUOTED_IDENTIFIER
-    ;
 
 qualifiedName
     : identifier (DOT identifier)*
@@ -228,7 +237,7 @@ integerValue
     ;
 
 string
-    : STRING
+    : QUOTED_STRING
     ;
 
 comparisonOperator

+ 48 - 46
x-pack/plugin/esql/src/main/antlr/EsqlBaseParser.tokens

@@ -24,7 +24,7 @@ EXPLAIN_WS=23
 EXPLAIN_LINE_COMMENT=24
 EXPLAIN_MULTILINE_COMMENT=25
 PIPE=26
-STRING=27
+QUOTED_STRING=27
 INTEGER_LITERAL=28
 DECIMAL_LITERAL=29
 BY=30
@@ -68,44 +68,45 @@ QUOTED_IDENTIFIER=67
 EXPR_LINE_COMMENT=68
 EXPR_MULTILINE_COMMENT=69
 EXPR_WS=70
-METADATA=71
-FROM_UNQUOTED_IDENTIFIER=72
-FROM_LINE_COMMENT=73
-FROM_MULTILINE_COMMENT=74
-FROM_WS=75
-ID_PATTERN=76
-PROJECT_LINE_COMMENT=77
-PROJECT_MULTILINE_COMMENT=78
-PROJECT_WS=79
-AS=80
-RENAME_LINE_COMMENT=81
-RENAME_MULTILINE_COMMENT=82
-RENAME_WS=83
-ON=84
-WITH=85
-ENRICH_POLICY_NAME=86
-ENRICH_LINE_COMMENT=87
-ENRICH_MULTILINE_COMMENT=88
-ENRICH_WS=89
-ENRICH_FIELD_LINE_COMMENT=90
-ENRICH_FIELD_MULTILINE_COMMENT=91
-ENRICH_FIELD_WS=92
-MVEXPAND_LINE_COMMENT=93
-MVEXPAND_MULTILINE_COMMENT=94
-MVEXPAND_WS=95
-INFO=96
-SHOW_LINE_COMMENT=97
-SHOW_MULTILINE_COMMENT=98
-SHOW_WS=99
-FUNCTIONS=100
-META_LINE_COMMENT=101
-META_MULTILINE_COMMENT=102
-META_WS=103
-COLON=104
-SETTING=105
-SETTING_LINE_COMMENT=106
-SETTTING_MULTILINE_COMMENT=107
-SETTING_WS=108
+OPTIONS=71
+METADATA=72
+FROM_UNQUOTED_IDENTIFIER=73
+FROM_LINE_COMMENT=74
+FROM_MULTILINE_COMMENT=75
+FROM_WS=76
+ID_PATTERN=77
+PROJECT_LINE_COMMENT=78
+PROJECT_MULTILINE_COMMENT=79
+PROJECT_WS=80
+AS=81
+RENAME_LINE_COMMENT=82
+RENAME_MULTILINE_COMMENT=83
+RENAME_WS=84
+ON=85
+WITH=86
+ENRICH_POLICY_NAME=87
+ENRICH_LINE_COMMENT=88
+ENRICH_MULTILINE_COMMENT=89
+ENRICH_WS=90
+ENRICH_FIELD_LINE_COMMENT=91
+ENRICH_FIELD_MULTILINE_COMMENT=92
+ENRICH_FIELD_WS=93
+MVEXPAND_LINE_COMMENT=94
+MVEXPAND_MULTILINE_COMMENT=95
+MVEXPAND_WS=96
+INFO=97
+SHOW_LINE_COMMENT=98
+SHOW_MULTILINE_COMMENT=99
+SHOW_WS=100
+FUNCTIONS=101
+META_LINE_COMMENT=102
+META_MULTILINE_COMMENT=103
+META_WS=104
+COLON=105
+SETTING=106
+SETTING_LINE_COMMENT=107
+SETTTING_MULTILINE_COMMENT=108
+SETTING_WS=109
 'dissect'=1
 'drop'=2
 'enrich'=3
@@ -160,10 +161,11 @@ SETTING_WS=108
 '/'=62
 '%'=63
 ']'=65
-'metadata'=71
-'as'=80
-'on'=84
-'with'=85
-'info'=96
-'functions'=100
-':'=104
+'options'=71
+'metadata'=72
+'as'=81
+'on'=85
+'with'=86
+'info'=97
+'functions'=101
+':'=105

+ 2 - 1
x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/analysis/Analyzer.java

@@ -153,6 +153,7 @@ public class Analyzer extends ParameterizedRuleExecutor<LogicalPlan, AnalyzerCon
             }
             TableIdentifier table = plan.table();
             if (context.indexResolution().matches(table.index()) == false) {
+                // TODO: fix this (and tests), or drop check (seems SQL-inherited, where's also defective)
                 new EsqlUnresolvedRelation(
                     plan.source(),
                     plan.table(),
@@ -164,7 +165,7 @@ public class Analyzer extends ParameterizedRuleExecutor<LogicalPlan, AnalyzerCon
             EsIndex esIndex = context.indexResolution().get();
             var attributes = mappingAsAttributes(plan.source(), esIndex.mapping());
             attributes.addAll(plan.metadataFields());
-            return new EsRelation(plan.source(), esIndex, attributes.isEmpty() ? NO_FIELDS : attributes);
+            return new EsRelation(plan.source(), esIndex, attributes.isEmpty() ? NO_FIELDS : attributes, plan.esSourceOptions());
         }
 
     }

+ 11 - 4
x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/analysis/PreAnalyzer.java

@@ -10,6 +10,7 @@ package org.elasticsearch.xpack.esql.analysis;
 import org.elasticsearch.xpack.esql.plan.logical.Enrich;
 import org.elasticsearch.xpack.esql.plan.logical.EsqlUnresolvedRelation;
 import org.elasticsearch.xpack.ql.analyzer.TableInfo;
+import org.elasticsearch.xpack.ql.options.EsSourceOptions;
 import org.elasticsearch.xpack.ql.plan.logical.LogicalPlan;
 
 import java.util.ArrayList;
@@ -20,13 +21,15 @@ import static java.util.Collections.emptyList;
 public class PreAnalyzer {
 
     public static class PreAnalysis {
-        public static final PreAnalysis EMPTY = new PreAnalysis(emptyList(), emptyList());
+        public static final PreAnalysis EMPTY = new PreAnalysis(emptyList(), emptyList(), emptyList());
 
         public final List<TableInfo> indices;
+        public final List<EsSourceOptions> esSourceOptions;
         public final List<Enrich> enriches;
 
-        public PreAnalysis(List<TableInfo> indices, List<Enrich> enriches) {
+        public PreAnalysis(List<TableInfo> indices, List<EsSourceOptions> esSourceOptions, List<Enrich> enriches) {
             this.indices = indices;
+            this.esSourceOptions = esSourceOptions;
             this.enriches = enriches;
         }
     }
@@ -41,14 +44,18 @@ public class PreAnalyzer {
 
     protected PreAnalysis doPreAnalyze(LogicalPlan plan) {
         List<TableInfo> indices = new ArrayList<>();
+        List<EsSourceOptions> esSourceOptions = new ArrayList<>();
         List<Enrich> unresolvedEnriches = new ArrayList<>();
 
-        plan.forEachUp(EsqlUnresolvedRelation.class, p -> indices.add(new TableInfo(p.table(), p.frozen())));
+        plan.forEachUp(EsqlUnresolvedRelation.class, p -> {
+            indices.add(new TableInfo(p.table(), p.frozen()));
+            esSourceOptions.add(p.esSourceOptions());
+        });
         plan.forEachUp(Enrich.class, unresolvedEnriches::add);
 
         // mark plan as preAnalyzed (if it were marked, there would be no analysis)
         plan.forEachUp(LogicalPlan::setPreAnalyzed);
 
-        return new PreAnalysis(indices, unresolvedEnriches);
+        return new PreAnalysis(indices, esSourceOptions, unresolvedEnriches);
     }
 }

+ 12 - 1
x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/io/stream/PlanNamedTypes.java

@@ -182,6 +182,7 @@ import org.elasticsearch.xpack.ql.expression.predicate.regex.RLikePattern;
 import org.elasticsearch.xpack.ql.expression.predicate.regex.RegexMatch;
 import org.elasticsearch.xpack.ql.expression.predicate.regex.WildcardPattern;
 import org.elasticsearch.xpack.ql.index.EsIndex;
+import org.elasticsearch.xpack.ql.options.EsSourceOptions;
 import org.elasticsearch.xpack.ql.plan.logical.Aggregate;
 import org.elasticsearch.xpack.ql.plan.logical.EsRelation;
 import org.elasticsearch.xpack.ql.plan.logical.Filter;
@@ -772,7 +773,14 @@ public final class PlanNamedTypes {
     }
 
     static EsRelation readEsRelation(PlanStreamInput in) throws IOException {
-        return new EsRelation(in.readSource(), readEsIndex(in), readAttributes(in), in.readBoolean());
+        Source source = in.readSource();
+        EsIndex esIndex = readEsIndex(in);
+        List<Attribute> attributes = readAttributes(in);
+        EsSourceOptions esSourceOptions = in.getTransportVersion().onOrAfter(TransportVersions.ESQL_ES_SOURCE_OPTIONS)
+            ? new EsSourceOptions(in)
+            : EsSourceOptions.NO_OPTIONS;
+        boolean frozen = in.readBoolean();
+        return new EsRelation(source, esIndex, attributes, esSourceOptions, frozen);
     }
 
     static void writeEsRelation(PlanStreamOutput out, EsRelation relation) throws IOException {
@@ -780,6 +788,9 @@ public final class PlanNamedTypes {
         out.writeNoSource();
         writeEsIndex(out, relation.index());
         writeAttributes(out, relation.output());
+        if (out.getTransportVersion().onOrAfter(TransportVersions.ESQL_ES_SOURCE_OPTIONS)) {
+            relation.esSourceOptions().writeEsSourceOptions(out);
+        }
         out.writeBoolean(relation.frozen());
     }
 

ファイルの差分が大きいため隠しています
+ 6 - 2
x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/parser/EsqlBaseLexer.interp


+ 738 - 727
x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/parser/EsqlBaseLexer.java

@@ -21,23 +21,23 @@ public class EsqlBaseLexer extends Lexer {
     KEEP=9, LIMIT=10, META=11, MV_EXPAND=12, RENAME=13, ROW=14, SHOW=15, SORT=16, 
     STATS=17, WHERE=18, UNKNOWN_CMD=19, LINE_COMMENT=20, MULTILINE_COMMENT=21, 
     WS=22, EXPLAIN_WS=23, EXPLAIN_LINE_COMMENT=24, EXPLAIN_MULTILINE_COMMENT=25, 
-    PIPE=26, STRING=27, INTEGER_LITERAL=28, DECIMAL_LITERAL=29, BY=30, AND=31, 
-    ASC=32, ASSIGN=33, COMMA=34, DESC=35, DOT=36, FALSE=37, FIRST=38, LAST=39, 
-    LP=40, IN=41, IS=42, LIKE=43, NOT=44, NULL=45, NULLS=46, OR=47, PARAM=48, 
-    RLIKE=49, RP=50, TRUE=51, EQ=52, CIEQ=53, NEQ=54, LT=55, LTE=56, GT=57, 
-    GTE=58, PLUS=59, MINUS=60, ASTERISK=61, SLASH=62, PERCENT=63, OPENING_BRACKET=64, 
+    PIPE=26, QUOTED_STRING=27, INTEGER_LITERAL=28, DECIMAL_LITERAL=29, BY=30, 
+    AND=31, ASC=32, ASSIGN=33, COMMA=34, DESC=35, DOT=36, FALSE=37, FIRST=38, 
+    LAST=39, LP=40, IN=41, IS=42, LIKE=43, NOT=44, NULL=45, NULLS=46, OR=47, 
+    PARAM=48, RLIKE=49, RP=50, TRUE=51, EQ=52, CIEQ=53, NEQ=54, LT=55, LTE=56, 
+    GT=57, GTE=58, PLUS=59, MINUS=60, ASTERISK=61, SLASH=62, PERCENT=63, OPENING_BRACKET=64, 
     CLOSING_BRACKET=65, UNQUOTED_IDENTIFIER=66, QUOTED_IDENTIFIER=67, EXPR_LINE_COMMENT=68, 
-    EXPR_MULTILINE_COMMENT=69, EXPR_WS=70, METADATA=71, FROM_UNQUOTED_IDENTIFIER=72, 
-    FROM_LINE_COMMENT=73, FROM_MULTILINE_COMMENT=74, FROM_WS=75, ID_PATTERN=76, 
-    PROJECT_LINE_COMMENT=77, PROJECT_MULTILINE_COMMENT=78, PROJECT_WS=79, 
-    AS=80, RENAME_LINE_COMMENT=81, RENAME_MULTILINE_COMMENT=82, RENAME_WS=83, 
-    ON=84, WITH=85, ENRICH_POLICY_NAME=86, ENRICH_LINE_COMMENT=87, ENRICH_MULTILINE_COMMENT=88, 
-    ENRICH_WS=89, ENRICH_FIELD_LINE_COMMENT=90, ENRICH_FIELD_MULTILINE_COMMENT=91, 
-    ENRICH_FIELD_WS=92, MVEXPAND_LINE_COMMENT=93, MVEXPAND_MULTILINE_COMMENT=94, 
-    MVEXPAND_WS=95, INFO=96, SHOW_LINE_COMMENT=97, SHOW_MULTILINE_COMMENT=98, 
-    SHOW_WS=99, FUNCTIONS=100, META_LINE_COMMENT=101, META_MULTILINE_COMMENT=102, 
-    META_WS=103, COLON=104, SETTING=105, SETTING_LINE_COMMENT=106, SETTTING_MULTILINE_COMMENT=107, 
-    SETTING_WS=108;
+    EXPR_MULTILINE_COMMENT=69, EXPR_WS=70, OPTIONS=71, METADATA=72, FROM_UNQUOTED_IDENTIFIER=73, 
+    FROM_LINE_COMMENT=74, FROM_MULTILINE_COMMENT=75, FROM_WS=76, ID_PATTERN=77, 
+    PROJECT_LINE_COMMENT=78, PROJECT_MULTILINE_COMMENT=79, PROJECT_WS=80, 
+    AS=81, RENAME_LINE_COMMENT=82, RENAME_MULTILINE_COMMENT=83, RENAME_WS=84, 
+    ON=85, WITH=86, ENRICH_POLICY_NAME=87, ENRICH_LINE_COMMENT=88, ENRICH_MULTILINE_COMMENT=89, 
+    ENRICH_WS=90, ENRICH_FIELD_LINE_COMMENT=91, ENRICH_FIELD_MULTILINE_COMMENT=92, 
+    ENRICH_FIELD_WS=93, MVEXPAND_LINE_COMMENT=94, MVEXPAND_MULTILINE_COMMENT=95, 
+    MVEXPAND_WS=96, INFO=97, SHOW_LINE_COMMENT=98, SHOW_MULTILINE_COMMENT=99, 
+    SHOW_WS=100, FUNCTIONS=101, META_LINE_COMMENT=102, META_MULTILINE_COMMENT=103, 
+    META_WS=104, COLON=105, SETTING=106, SETTING_LINE_COMMENT=107, SETTTING_MULTILINE_COMMENT=108, 
+    SETTING_WS=109;
   public static final int
     EXPLAIN_MODE=1, EXPRESSION_MODE=2, FROM_MODE=3, PROJECT_MODE=4, RENAME_MODE=5, 
     ENRICH_MODE=6, ENRICH_FIELD_MODE=7, MVEXPAND_MODE=8, SHOW_MODE=9, META_MODE=10, 
@@ -60,14 +60,15 @@ public class EsqlBaseLexer extends Lexer {
       "WS", "EXPLAIN_OPENING_BRACKET", "EXPLAIN_PIPE", "EXPLAIN_WS", "EXPLAIN_LINE_COMMENT", 
       "EXPLAIN_MULTILINE_COMMENT", "PIPE", "DIGIT", "LETTER", "ESCAPE_SEQUENCE", 
       "UNESCAPED_CHARS", "EXPONENT", "ASPERAND", "BACKQUOTE", "BACKQUOTE_BLOCK", 
-      "UNDERSCORE", "UNQUOTED_ID_BODY", "STRING", "INTEGER_LITERAL", "DECIMAL_LITERAL", 
-      "BY", "AND", "ASC", "ASSIGN", "COMMA", "DESC", "DOT", "FALSE", "FIRST", 
-      "LAST", "LP", "IN", "IS", "LIKE", "NOT", "NULL", "NULLS", "OR", "PARAM", 
-      "RLIKE", "RP", "TRUE", "EQ", "CIEQ", "NEQ", "LT", "LTE", "GT", "GTE", 
-      "PLUS", "MINUS", "ASTERISK", "SLASH", "PERCENT", "OPENING_BRACKET", "CLOSING_BRACKET", 
-      "UNQUOTED_IDENTIFIER", "QUOTED_ID", "QUOTED_IDENTIFIER", "EXPR_LINE_COMMENT", 
-      "EXPR_MULTILINE_COMMENT", "EXPR_WS", "FROM_PIPE", "FROM_OPENING_BRACKET", 
-      "FROM_CLOSING_BRACKET", "FROM_COMMA", "FROM_ASSIGN", "METADATA", "FROM_UNQUOTED_IDENTIFIER_PART", 
+      "UNDERSCORE", "UNQUOTED_ID_BODY", "QUOTED_STRING", "INTEGER_LITERAL", 
+      "DECIMAL_LITERAL", "BY", "AND", "ASC", "ASSIGN", "COMMA", "DESC", "DOT", 
+      "FALSE", "FIRST", "LAST", "LP", "IN", "IS", "LIKE", "NOT", "NULL", "NULLS", 
+      "OR", "PARAM", "RLIKE", "RP", "TRUE", "EQ", "CIEQ", "NEQ", "LT", "LTE", 
+      "GT", "GTE", "PLUS", "MINUS", "ASTERISK", "SLASH", "PERCENT", "OPENING_BRACKET", 
+      "CLOSING_BRACKET", "UNQUOTED_IDENTIFIER", "QUOTED_ID", "QUOTED_IDENTIFIER", 
+      "EXPR_LINE_COMMENT", "EXPR_MULTILINE_COMMENT", "EXPR_WS", "FROM_PIPE", 
+      "FROM_OPENING_BRACKET", "FROM_CLOSING_BRACKET", "FROM_COMMA", "FROM_ASSIGN", 
+      "FROM_QUTED_STRING", "OPTIONS", "METADATA", "FROM_UNQUOTED_IDENTIFIER_PART", 
       "FROM_UNQUOTED_IDENTIFIER", "FROM_QUOTED_IDENTIFIER", "FROM_LINE_COMMENT", 
       "FROM_MULTILINE_COMMENT", "FROM_WS", "PROJECT_PIPE", "PROJECT_DOT", "PROJECT_COMMA", 
       "UNQUOTED_ID_BODY_WITH_PATTERN", "UNQUOTED_ID_PATTERN", "ID_PATTERN", 
@@ -99,10 +100,10 @@ public class EsqlBaseLexer extends Lexer {
       "'last'", "'('", "'in'", "'is'", "'like'", "'not'", "'null'", "'nulls'", 
       "'or'", "'?'", "'rlike'", "')'", "'true'", "'=='", "'=~'", "'!='", "'<'", 
       "'<='", "'>'", "'>='", "'+'", "'-'", "'*'", "'/'", "'%'", null, "']'", 
-      null, null, null, null, null, "'metadata'", null, null, null, null, null, 
-      null, null, null, "'as'", null, null, null, "'on'", "'with'", null, null, 
-      null, null, null, null, null, null, null, null, "'info'", null, null, 
-      null, "'functions'", null, null, null, "':'"
+      null, null, null, null, null, "'options'", "'metadata'", null, null, 
+      null, null, null, null, null, null, "'as'", null, null, null, "'on'", 
+      "'with'", null, null, null, null, null, null, null, null, null, null, 
+      "'info'", null, null, null, "'functions'", null, null, null, "':'"
     };
   }
   private static final String[] _LITERAL_NAMES = makeLiteralNames();
@@ -112,13 +113,13 @@ public class EsqlBaseLexer extends Lexer {
       "INLINESTATS", "KEEP", "LIMIT", "META", "MV_EXPAND", "RENAME", "ROW", 
       "SHOW", "SORT", "STATS", "WHERE", "UNKNOWN_CMD", "LINE_COMMENT", "MULTILINE_COMMENT", 
       "WS", "EXPLAIN_WS", "EXPLAIN_LINE_COMMENT", "EXPLAIN_MULTILINE_COMMENT", 
-      "PIPE", "STRING", "INTEGER_LITERAL", "DECIMAL_LITERAL", "BY", "AND", 
-      "ASC", "ASSIGN", "COMMA", "DESC", "DOT", "FALSE", "FIRST", "LAST", "LP", 
-      "IN", "IS", "LIKE", "NOT", "NULL", "NULLS", "OR", "PARAM", "RLIKE", "RP", 
-      "TRUE", "EQ", "CIEQ", "NEQ", "LT", "LTE", "GT", "GTE", "PLUS", "MINUS", 
-      "ASTERISK", "SLASH", "PERCENT", "OPENING_BRACKET", "CLOSING_BRACKET", 
+      "PIPE", "QUOTED_STRING", "INTEGER_LITERAL", "DECIMAL_LITERAL", "BY", 
+      "AND", "ASC", "ASSIGN", "COMMA", "DESC", "DOT", "FALSE", "FIRST", "LAST", 
+      "LP", "IN", "IS", "LIKE", "NOT", "NULL", "NULLS", "OR", "PARAM", "RLIKE", 
+      "RP", "TRUE", "EQ", "CIEQ", "NEQ", "LT", "LTE", "GT", "GTE", "PLUS", 
+      "MINUS", "ASTERISK", "SLASH", "PERCENT", "OPENING_BRACKET", "CLOSING_BRACKET", 
       "UNQUOTED_IDENTIFIER", "QUOTED_IDENTIFIER", "EXPR_LINE_COMMENT", "EXPR_MULTILINE_COMMENT", 
-      "EXPR_WS", "METADATA", "FROM_UNQUOTED_IDENTIFIER", "FROM_LINE_COMMENT", 
+      "EXPR_WS", "OPTIONS", "METADATA", "FROM_UNQUOTED_IDENTIFIER", "FROM_LINE_COMMENT", 
       "FROM_MULTILINE_COMMENT", "FROM_WS", "ID_PATTERN", "PROJECT_LINE_COMMENT", 
       "PROJECT_MULTILINE_COMMENT", "PROJECT_WS", "AS", "RENAME_LINE_COMMENT", 
       "RENAME_MULTILINE_COMMENT", "RENAME_WS", "ON", "WITH", "ENRICH_POLICY_NAME", 
@@ -190,7 +191,7 @@ public class EsqlBaseLexer extends Lexer {
   public ATN getATN() { return _ATN; }
 
   public static final String _serializedATN =
-    "\u0004\u0000l\u049e\u0006\uffff\uffff\u0006\uffff\uffff\u0006\uffff\uffff"+
+    "\u0004\u0000m\u04ae\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"+
@@ -232,707 +233,717 @@ public class EsqlBaseLexer extends Lexer {
     "\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\u0001\u0000\u0001\u0000\u0001\u0000\u0001\u0000"+
+    "\u0002\u009c\u0007\u009c\u0002\u009d\u0007\u009d\u0002\u009e\u0007\u009e"+
     "\u0001\u0000\u0001\u0000\u0001\u0000\u0001\u0000\u0001\u0000\u0001\u0000"+
-    "\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001"+
-    "\u0001\u0001\u0001\u0002\u0001\u0002\u0001\u0002\u0001\u0002\u0001\u0002"+
-    "\u0001\u0002\u0001\u0002\u0001\u0002\u0001\u0002\u0001\u0003\u0001\u0003"+
-    "\u0001\u0003\u0001\u0003\u0001\u0003\u0001\u0003\u0001\u0003\u0001\u0004"+
+    "\u0001\u0000\u0001\u0000\u0001\u0000\u0001\u0000\u0001\u0001\u0001\u0001"+
+    "\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0002"+
+    "\u0001\u0002\u0001\u0002\u0001\u0002\u0001\u0002\u0001\u0002\u0001\u0002"+
+    "\u0001\u0002\u0001\u0002\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\u0001\u0004\u0001\u0004\u0001\u0004"+
-    "\u0001\u0004\u0001\u0004\u0001\u0004\u0001\u0005\u0001\u0005\u0001\u0005"+
-    "\u0001\u0005\u0001\u0005\u0001\u0005\u0001\u0005\u0001\u0006\u0001\u0006"+
-    "\u0001\u0006\u0001\u0006\u0001\u0006\u0001\u0006\u0001\u0006\u0001\u0007"+
+    "\u0001\u0004\u0001\u0005\u0001\u0005\u0001\u0005\u0001\u0005\u0001\u0005"+
+    "\u0001\u0005\u0001\u0005\u0001\u0006\u0001\u0006\u0001\u0006\u0001\u0006"+
+    "\u0001\u0006\u0001\u0006\u0001\u0006\u0001\u0007\u0001\u0007\u0001\u0007"+
     "\u0001\u0007\u0001\u0007\u0001\u0007\u0001\u0007\u0001\u0007\u0001\u0007"+
-    "\u0001\u0007\u0001\u0007\u0001\u0007\u0001\u0007\u0001\u0007\u0001\u0007"+
-    "\u0001\u0007\u0001\b\u0001\b\u0001\b\u0001\b\u0001\b\u0001\b\u0001\b\u0001"+
-    "\t\u0001\t\u0001\t\u0001\t\u0001\t\u0001\t\u0001\t\u0001\t\u0001\n\u0001"+
-    "\n\u0001\n\u0001\n\u0001\n\u0001\n\u0001\n\u0001\u000b\u0001\u000b\u0001"+
+    "\u0001\u0007\u0001\u0007\u0001\u0007\u0001\u0007\u0001\u0007\u0001\b\u0001"+
+    "\b\u0001\b\u0001\b\u0001\b\u0001\b\u0001\b\u0001\t\u0001\t\u0001\t\u0001"+
+    "\t\u0001\t\u0001\t\u0001\t\u0001\t\u0001\n\u0001\n\u0001\n\u0001\n\u0001"+
+    "\n\u0001\n\u0001\n\u0001\u000b\u0001\u000b\u0001\u000b\u0001\u000b\u0001"+
     "\u000b\u0001\u000b\u0001\u000b\u0001\u000b\u0001\u000b\u0001\u000b\u0001"+
-    "\u000b\u0001\u000b\u0001\u000b\u0001\u000b\u0001\f\u0001\f\u0001\f\u0001"+
-    "\f\u0001\f\u0001\f\u0001\f\u0001\f\u0001\f\u0001\r\u0001\r\u0001\r\u0001"+
-    "\r\u0001\r\u0001\r\u0001\u000e\u0001\u000e\u0001\u000e\u0001\u000e\u0001"+
-    "\u000e\u0001\u000e\u0001\u000e\u0001\u000f\u0001\u000f\u0001\u000f\u0001"+
-    "\u000f\u0001\u000f\u0001\u000f\u0001\u000f\u0001\u0010\u0001\u0010\u0001"+
-    "\u0010\u0001\u0010\u0001\u0010\u0001\u0010\u0001\u0010\u0001\u0010\u0001"+
+    "\u000b\u0001\u000b\u0001\f\u0001\f\u0001\f\u0001\f\u0001\f\u0001\f\u0001"+
+    "\f\u0001\f\u0001\f\u0001\r\u0001\r\u0001\r\u0001\r\u0001\r\u0001\r\u0001"+
+    "\u000e\u0001\u000e\u0001\u000e\u0001\u000e\u0001\u000e\u0001\u000e\u0001"+
+    "\u000e\u0001\u000f\u0001\u000f\u0001\u000f\u0001\u000f\u0001\u000f\u0001"+
+    "\u000f\u0001\u000f\u0001\u0010\u0001\u0010\u0001\u0010\u0001\u0010\u0001"+
+    "\u0010\u0001\u0010\u0001\u0010\u0001\u0010\u0001\u0011\u0001\u0011\u0001"+
     "\u0011\u0001\u0011\u0001\u0011\u0001\u0011\u0001\u0011\u0001\u0011\u0001"+
-    "\u0011\u0001\u0011\u0001\u0012\u0004\u0012\u01de\b\u0012\u000b\u0012\f"+
-    "\u0012\u01df\u0001\u0012\u0001\u0012\u0001\u0013\u0001\u0013\u0001\u0013"+
-    "\u0001\u0013\u0005\u0013\u01e8\b\u0013\n\u0013\f\u0013\u01eb\t\u0013\u0001"+
-    "\u0013\u0003\u0013\u01ee\b\u0013\u0001\u0013\u0003\u0013\u01f1\b\u0013"+
-    "\u0001\u0013\u0001\u0013\u0001\u0014\u0001\u0014\u0001\u0014\u0001\u0014"+
-    "\u0001\u0014\u0005\u0014\u01fa\b\u0014\n\u0014\f\u0014\u01fd\t\u0014\u0001"+
-    "\u0014\u0001\u0014\u0001\u0014\u0001\u0014\u0001\u0014\u0001\u0015\u0004"+
-    "\u0015\u0205\b\u0015\u000b\u0015\f\u0015\u0206\u0001\u0015\u0001\u0015"+
-    "\u0001\u0016\u0001\u0016\u0001\u0016\u0001\u0016\u0001\u0016\u0001\u0017"+
-    "\u0001\u0017\u0001\u0017\u0001\u0017\u0001\u0017\u0001\u0018\u0001\u0018"+
-    "\u0001\u0018\u0001\u0018\u0001\u0019\u0001\u0019\u0001\u0019\u0001\u0019"+
-    "\u0001\u001a\u0001\u001a\u0001\u001a\u0001\u001a\u0001\u001b\u0001\u001b"+
-    "\u0001\u001b\u0001\u001b\u0001\u001c\u0001\u001c\u0001\u001d\u0001\u001d"+
-    "\u0001\u001e\u0001\u001e\u0001\u001e\u0001\u001f\u0001\u001f\u0001 \u0001"+
-    " \u0003 \u0230\b \u0001 \u0004 \u0233\b \u000b \f \u0234\u0001!\u0001"+
-    "!\u0001\"\u0001\"\u0001#\u0001#\u0001#\u0003#\u023e\b#\u0001$\u0001$\u0001"+
-    "%\u0001%\u0001%\u0003%\u0245\b%\u0001&\u0001&\u0001&\u0005&\u024a\b&\n"+
-    "&\f&\u024d\t&\u0001&\u0001&\u0001&\u0001&\u0001&\u0001&\u0005&\u0255\b"+
-    "&\n&\f&\u0258\t&\u0001&\u0001&\u0001&\u0001&\u0001&\u0003&\u025f\b&\u0001"+
-    "&\u0003&\u0262\b&\u0003&\u0264\b&\u0001\'\u0004\'\u0267\b\'\u000b\'\f"+
-    "\'\u0268\u0001(\u0004(\u026c\b(\u000b(\f(\u026d\u0001(\u0001(\u0005(\u0272"+
-    "\b(\n(\f(\u0275\t(\u0001(\u0001(\u0004(\u0279\b(\u000b(\f(\u027a\u0001"+
-    "(\u0004(\u027e\b(\u000b(\f(\u027f\u0001(\u0001(\u0005(\u0284\b(\n(\f("+
-    "\u0287\t(\u0003(\u0289\b(\u0001(\u0001(\u0001(\u0001(\u0004(\u028f\b("+
-    "\u000b(\f(\u0290\u0001(\u0001(\u0003(\u0295\b(\u0001)\u0001)\u0001)\u0001"+
-    "*\u0001*\u0001*\u0001*\u0001+\u0001+\u0001+\u0001+\u0001,\u0001,\u0001"+
-    "-\u0001-\u0001.\u0001.\u0001.\u0001.\u0001.\u0001/\u0001/\u00010\u0001"+
-    "0\u00010\u00010\u00010\u00010\u00011\u00011\u00011\u00011\u00011\u0001"+
-    "1\u00012\u00012\u00012\u00012\u00012\u00013\u00013\u00014\u00014\u0001"+
-    "4\u00015\u00015\u00015\u00016\u00016\u00016\u00016\u00016\u00017\u0001"+
-    "7\u00017\u00017\u00018\u00018\u00018\u00018\u00018\u00019\u00019\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@\u0001A\u0001A\u0001"+
-    "A\u0001B\u0001B\u0001C\u0001C\u0001C\u0001D\u0001D\u0001E\u0001E\u0001"+
-    "E\u0001F\u0001F\u0001G\u0001G\u0001H\u0001H\u0001I\u0001I\u0001J\u0001"+
-    "J\u0001K\u0001K\u0001K\u0001K\u0001K\u0001L\u0001L\u0001L\u0001L\u0001"+
-    "L\u0001M\u0001M\u0005M\u0315\bM\nM\fM\u0318\tM\u0001M\u0001M\u0003M\u031c"+
-    "\bM\u0001M\u0004M\u031f\bM\u000bM\fM\u0320\u0003M\u0323\bM\u0001N\u0001"+
-    "N\u0004N\u0327\bN\u000bN\fN\u0328\u0001N\u0001N\u0001O\u0001O\u0001P\u0001"+
-    "P\u0001P\u0001P\u0001Q\u0001Q\u0001Q\u0001Q\u0001R\u0001R\u0001R\u0001"+
-    "R\u0001S\u0001S\u0001S\u0001S\u0001S\u0001T\u0001T\u0001T\u0001T\u0001"+
-    "U\u0001U\u0001U\u0001U\u0001V\u0001V\u0001V\u0001V\u0001W\u0001W\u0001"+
-    "W\u0001W\u0001X\u0001X\u0001X\u0001X\u0001X\u0001X\u0001X\u0001X\u0001"+
-    "X\u0001Y\u0001Y\u0001Y\u0003Y\u035c\bY\u0001Z\u0004Z\u035f\bZ\u000bZ\f"+
-    "Z\u0360\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\u0003b\u0384\bb\u0001c\u0001c\u0003c\u0388"+
-    "\bc\u0001c\u0005c\u038b\bc\nc\fc\u038e\tc\u0001c\u0001c\u0003c\u0392\b"+
-    "c\u0001c\u0004c\u0395\bc\u000bc\fc\u0396\u0003c\u0399\bc\u0001d\u0001"+
-    "d\u0004d\u039d\bd\u000bd\fd\u039e\u0001e\u0001e\u0001e\u0001e\u0001f\u0001"+
-    "f\u0001f\u0001f\u0001g\u0001g\u0001g\u0001g\u0001h\u0001h\u0001h\u0001"+
-    "h\u0001h\u0001i\u0001i\u0001i\u0001i\u0001j\u0001j\u0001j\u0001j\u0001"+
-    "k\u0001k\u0001k\u0001k\u0001l\u0001l\u0001l\u0001m\u0001m\u0001m\u0001"+
-    "m\u0001n\u0001n\u0001n\u0001n\u0001o\u0001o\u0001o\u0001o\u0001p\u0001"+
-    "p\u0001p\u0001p\u0001q\u0001q\u0001q\u0001q\u0001q\u0001r\u0001r\u0001"+
+    "\u0012\u0004\u0012\u01e2\b\u0012\u000b\u0012\f\u0012\u01e3\u0001\u0012"+
+    "\u0001\u0012\u0001\u0013\u0001\u0013\u0001\u0013\u0001\u0013\u0005\u0013"+
+    "\u01ec\b\u0013\n\u0013\f\u0013\u01ef\t\u0013\u0001\u0013\u0003\u0013\u01f2"+
+    "\b\u0013\u0001\u0013\u0003\u0013\u01f5\b\u0013\u0001\u0013\u0001\u0013"+
+    "\u0001\u0014\u0001\u0014\u0001\u0014\u0001\u0014\u0001\u0014\u0005\u0014"+
+    "\u01fe\b\u0014\n\u0014\f\u0014\u0201\t\u0014\u0001\u0014\u0001\u0014\u0001"+
+    "\u0014\u0001\u0014\u0001\u0014\u0001\u0015\u0004\u0015\u0209\b\u0015\u000b"+
+    "\u0015\f\u0015\u020a\u0001\u0015\u0001\u0015\u0001\u0016\u0001\u0016\u0001"+
+    "\u0016\u0001\u0016\u0001\u0016\u0001\u0017\u0001\u0017\u0001\u0017\u0001"+
+    "\u0017\u0001\u0017\u0001\u0018\u0001\u0018\u0001\u0018\u0001\u0018\u0001"+
+    "\u0019\u0001\u0019\u0001\u0019\u0001\u0019\u0001\u001a\u0001\u001a\u0001"+
+    "\u001a\u0001\u001a\u0001\u001b\u0001\u001b\u0001\u001b\u0001\u001b\u0001"+
+    "\u001c\u0001\u001c\u0001\u001d\u0001\u001d\u0001\u001e\u0001\u001e\u0001"+
+    "\u001e\u0001\u001f\u0001\u001f\u0001 \u0001 \u0003 \u0234\b \u0001 \u0004"+
+    " \u0237\b \u000b \f \u0238\u0001!\u0001!\u0001\"\u0001\"\u0001#\u0001"+
+    "#\u0001#\u0003#\u0242\b#\u0001$\u0001$\u0001%\u0001%\u0001%\u0003%\u0249"+
+    "\b%\u0001&\u0001&\u0001&\u0005&\u024e\b&\n&\f&\u0251\t&\u0001&\u0001&"+
+    "\u0001&\u0001&\u0001&\u0001&\u0005&\u0259\b&\n&\f&\u025c\t&\u0001&\u0001"+
+    "&\u0001&\u0001&\u0001&\u0003&\u0263\b&\u0001&\u0003&\u0266\b&\u0003&\u0268"+
+    "\b&\u0001\'\u0004\'\u026b\b\'\u000b\'\f\'\u026c\u0001(\u0004(\u0270\b"+
+    "(\u000b(\f(\u0271\u0001(\u0001(\u0005(\u0276\b(\n(\f(\u0279\t(\u0001("+
+    "\u0001(\u0004(\u027d\b(\u000b(\f(\u027e\u0001(\u0004(\u0282\b(\u000b("+
+    "\f(\u0283\u0001(\u0001(\u0005(\u0288\b(\n(\f(\u028b\t(\u0003(\u028d\b"+
+    "(\u0001(\u0001(\u0001(\u0001(\u0004(\u0293\b(\u000b(\f(\u0294\u0001(\u0001"+
+    "(\u0003(\u0299\b(\u0001)\u0001)\u0001)\u0001*\u0001*\u0001*\u0001*\u0001"+
+    "+\u0001+\u0001+\u0001+\u0001,\u0001,\u0001-\u0001-\u0001.\u0001.\u0001"+
+    ".\u0001.\u0001.\u0001/\u0001/\u00010\u00010\u00010\u00010\u00010\u0001"+
+    "0\u00011\u00011\u00011\u00011\u00011\u00011\u00012\u00012\u00012\u0001"+
+    "2\u00012\u00013\u00013\u00014\u00014\u00014\u00015\u00015\u00015\u0001"+
+    "6\u00016\u00016\u00016\u00016\u00017\u00017\u00017\u00017\u00018\u0001"+
+    "8\u00018\u00018\u00018\u00019\u00019\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@\u0001A\u0001A\u0001A\u0001B\u0001B\u0001C\u0001"+
+    "C\u0001C\u0001D\u0001D\u0001E\u0001E\u0001E\u0001F\u0001F\u0001G\u0001"+
+    "G\u0001H\u0001H\u0001I\u0001I\u0001J\u0001J\u0001K\u0001K\u0001K\u0001"+
+    "K\u0001K\u0001L\u0001L\u0001L\u0001L\u0001L\u0001M\u0001M\u0005M\u0319"+
+    "\bM\nM\fM\u031c\tM\u0001M\u0001M\u0003M\u0320\bM\u0001M\u0004M\u0323\b"+
+    "M\u000bM\fM\u0324\u0003M\u0327\bM\u0001N\u0001N\u0004N\u032b\bN\u000b"+
+    "N\fN\u032c\u0001N\u0001N\u0001O\u0001O\u0001P\u0001P\u0001P\u0001P\u0001"+
+    "Q\u0001Q\u0001Q\u0001Q\u0001R\u0001R\u0001R\u0001R\u0001S\u0001S\u0001"+
+    "S\u0001S\u0001S\u0001T\u0001T\u0001T\u0001T\u0001U\u0001U\u0001U\u0001"+
+    "U\u0001V\u0001V\u0001V\u0001V\u0001W\u0001W\u0001W\u0001W\u0001X\u0001"+
+    "X\u0001X\u0001X\u0001Y\u0001Y\u0001Y\u0001Y\u0001Y\u0001Y\u0001Y\u0001"+
+    "Y\u0001Z\u0001Z\u0001Z\u0001Z\u0001Z\u0001Z\u0001Z\u0001Z\u0001Z\u0001"+
+    "[\u0001[\u0001[\u0003[\u036c\b[\u0001\\\u0004\\\u036f\b\\\u000b\\\f\\"+
+    "\u0370\u0001]\u0001]\u0001]\u0001]\u0001^\u0001^\u0001^\u0001^\u0001_"+
+    "\u0001_\u0001_\u0001_\u0001`\u0001`\u0001`\u0001`\u0001a\u0001a\u0001"+
+    "a\u0001a\u0001a\u0001b\u0001b\u0001b\u0001b\u0001c\u0001c\u0001c\u0001"+
+    "c\u0001d\u0001d\u0001d\u0001d\u0003d\u0394\bd\u0001e\u0001e\u0003e\u0398"+
+    "\be\u0001e\u0005e\u039b\be\ne\fe\u039e\te\u0001e\u0001e\u0003e\u03a2\b"+
+    "e\u0001e\u0004e\u03a5\be\u000be\fe\u03a6\u0003e\u03a9\be\u0001f\u0001"+
+    "f\u0004f\u03ad\bf\u000bf\ff\u03ae\u0001g\u0001g\u0001g\u0001g\u0001h\u0001"+
+    "h\u0001h\u0001h\u0001i\u0001i\u0001i\u0001i\u0001j\u0001j\u0001j\u0001"+
+    "j\u0001j\u0001k\u0001k\u0001k\u0001k\u0001l\u0001l\u0001l\u0001l\u0001"+
+    "m\u0001m\u0001m\u0001m\u0001n\u0001n\u0001n\u0001o\u0001o\u0001o\u0001"+
+    "o\u0001p\u0001p\u0001p\u0001p\u0001q\u0001q\u0001q\u0001q\u0001r\u0001"+
     "r\u0001r\u0001r\u0001s\u0001s\u0001s\u0001s\u0001s\u0001t\u0001t\u0001"+
-    "t\u0001t\u0001t\u0001t\u0001t\u0001u\u0001u\u0001v\u0004v\u03ea\bv\u000b"+
-    "v\fv\u03eb\u0001v\u0001v\u0003v\u03f0\bv\u0001v\u0004v\u03f3\bv\u000b"+
-    "v\fv\u03f4\u0001w\u0001w\u0001w\u0001w\u0001x\u0001x\u0001x\u0001x\u0001"+
-    "y\u0001y\u0001y\u0001y\u0001z\u0001z\u0001z\u0001z\u0001{\u0001{\u0001"+
-    "{\u0001{\u0001|\u0001|\u0001|\u0001|\u0001|\u0001|\u0001}\u0001}\u0001"+
-    "}\u0001}\u0001~\u0001~\u0001~\u0001~\u0001\u007f\u0001\u007f\u0001\u007f"+
-    "\u0001\u007f\u0001\u0080\u0001\u0080\u0001\u0080\u0001\u0080\u0001\u0081"+
-    "\u0001\u0081\u0001\u0081\u0001\u0081\u0001\u0082\u0001\u0082\u0001\u0082"+
-    "\u0001\u0082\u0001\u0083\u0001\u0083\u0001\u0083\u0001\u0083\u0001\u0084"+
-    "\u0001\u0084\u0001\u0084\u0001\u0084\u0001\u0085\u0001\u0085\u0001\u0085"+
-    "\u0001\u0085\u0001\u0086\u0001\u0086\u0001\u0086\u0001\u0086\u0001\u0086"+
+    "t\u0001t\u0001t\u0001u\u0001u\u0001u\u0001u\u0001u\u0001v\u0001v\u0001"+
+    "v\u0001v\u0001v\u0001v\u0001v\u0001w\u0001w\u0001x\u0004x\u03fa\bx\u000b"+
+    "x\fx\u03fb\u0001x\u0001x\u0003x\u0400\bx\u0001x\u0004x\u0403\bx\u000b"+
+    "x\fx\u0404\u0001y\u0001y\u0001y\u0001y\u0001z\u0001z\u0001z\u0001z\u0001"+
+    "{\u0001{\u0001{\u0001{\u0001|\u0001|\u0001|\u0001|\u0001}\u0001}\u0001"+
+    "}\u0001}\u0001~\u0001~\u0001~\u0001~\u0001~\u0001~\u0001\u007f\u0001\u007f"+
+    "\u0001\u007f\u0001\u007f\u0001\u0080\u0001\u0080\u0001\u0080\u0001\u0080"+
+    "\u0001\u0081\u0001\u0081\u0001\u0081\u0001\u0081\u0001\u0082\u0001\u0082"+
+    "\u0001\u0082\u0001\u0082\u0001\u0083\u0001\u0083\u0001\u0083\u0001\u0083"+
+    "\u0001\u0084\u0001\u0084\u0001\u0084\u0001\u0084\u0001\u0085\u0001\u0085"+
+    "\u0001\u0085\u0001\u0085\u0001\u0086\u0001\u0086\u0001\u0086\u0001\u0086"+
     "\u0001\u0087\u0001\u0087\u0001\u0087\u0001\u0087\u0001\u0088\u0001\u0088"+
-    "\u0001\u0088\u0001\u0088\u0001\u0089\u0001\u0089\u0001\u0089\u0001\u0089"+
-    "\u0001\u008a\u0001\u008a\u0001\u008a\u0001\u008a\u0001\u008b\u0001\u008b"+
-    "\u0001\u008b\u0001\u008b\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\u0088\u0001\u0088\u0001\u0088\u0001\u0089\u0001\u0089\u0001\u0089"+
+    "\u0001\u0089\u0001\u008a\u0001\u008a\u0001\u008a\u0001\u008a\u0001\u008b"+
+    "\u0001\u008b\u0001\u008b\u0001\u008b\u0001\u008c\u0001\u008c\u0001\u008c"+
+    "\u0001\u008c\u0001\u008d\u0001\u008d\u0001\u008d\u0001\u008d\u0001\u008e"+
+    "\u0001\u008e\u0001\u008e\u0001\u008e\u0001\u008f\u0001\u008f\u0001\u008f"+
     "\u0001\u008f\u0001\u008f\u0001\u0090\u0001\u0090\u0001\u0090\u0001\u0090"+
-    "\u0001\u0091\u0001\u0091\u0001\u0091\u0001\u0091\u0001\u0092\u0001\u0092"+
+    "\u0001\u0090\u0001\u0091\u0001\u0091\u0001\u0091\u0001\u0091\u0001\u0092"+
     "\u0001\u0092\u0001\u0092\u0001\u0092\u0001\u0093\u0001\u0093\u0001\u0093"+
-    "\u0001\u0093\u0001\u0093\u0001\u0093\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\u0096\u0001\u0096\u0001\u0096"+
-    "\u0001\u0096\u0001\u0097\u0001\u0097\u0001\u0097\u0001\u0097\u0001\u0097"+
-    "\u0001\u0098\u0001\u0098\u0001\u0099\u0001\u0099\u0001\u0099\u0001\u0099"+
-    "\u0001\u0099\u0004\u0099\u048f\b\u0099\u000b\u0099\f\u0099\u0490\u0001"+
-    "\u009a\u0001\u009a\u0001\u009a\u0001\u009a\u0001\u009b\u0001\u009b\u0001"+
-    "\u009b\u0001\u009b\u0001\u009c\u0001\u009c\u0001\u009c\u0001\u009c\u0002"+
-    "\u01fb\u0256\u0000\u009d\f\u0001\u000e\u0002\u0010\u0003\u0012\u0004\u0014"+
-    "\u0005\u0016\u0006\u0018\u0007\u001a\b\u001c\t\u001e\n \u000b\"\f$\r&"+
-    "\u000e(\u000f*\u0010,\u0011.\u00120\u00132\u00144\u00156\u00168\u0000"+
-    ":\u0000<\u0017>\u0018@\u0019B\u001aD\u0000F\u0000H\u0000J\u0000L\u0000"+
-    "N\u0000P\u0000R\u0000T\u0000V\u0000X\u001bZ\u001c\\\u001d^\u001e`\u001f"+
-    "b d!f\"h#j$l%n&p\'r(t)v*x+z,|-~.\u0080/\u00820\u00841\u00862\u00883\u008a"+
-    "4\u008c5\u008e6\u00907\u00928\u00949\u0096:\u0098;\u009a<\u009c=\u009e"+
-    ">\u00a0?\u00a2@\u00a4A\u00a6B\u00a8\u0000\u00aaC\u00acD\u00aeE\u00b0F"+
-    "\u00b2\u0000\u00b4\u0000\u00b6\u0000\u00b8\u0000\u00ba\u0000\u00bcG\u00be"+
-    "\u0000\u00c0H\u00c2\u0000\u00c4I\u00c6J\u00c8K\u00ca\u0000\u00cc\u0000"+
-    "\u00ce\u0000\u00d0\u0000\u00d2\u0000\u00d4L\u00d6M\u00d8N\u00daO\u00dc"+
-    "\u0000\u00de\u0000\u00e0\u0000\u00e2\u0000\u00e4P\u00e6\u0000\u00e8Q\u00ea"+
-    "R\u00ecS\u00ee\u0000\u00f0\u0000\u00f2T\u00f4U\u00f6\u0000\u00f8V\u00fa"+
-    "\u0000\u00fc\u0000\u00feW\u0100X\u0102Y\u0104\u0000\u0106\u0000\u0108"+
-    "\u0000\u010a\u0000\u010c\u0000\u010e\u0000\u0110\u0000\u0112Z\u0114[\u0116"+
-    "\\\u0118\u0000\u011a\u0000\u011c\u0000\u011e\u0000\u0120]\u0122^\u0124"+
-    "_\u0126\u0000\u0128`\u012aa\u012cb\u012ec\u0130\u0000\u0132d\u0134e\u0136"+
-    "f\u0138g\u013a\u0000\u013ch\u013ei\u0140j\u0142k\u0144l\f\u0000\u0001"+
-    "\u0002\u0003\u0004\u0005\u0006\u0007\b\t\n\u000b\r\u0006\u0000\t\n\r\r"+
-    "  //[[]]\u0002\u0000\n\n\r\r\u0003\u0000\t\n\r\r  \u0001\u000009\u0002"+
-    "\u0000AZaz\u0005\u0000\"\"\\\\nnrrtt\u0004\u0000\n\n\r\r\"\"\\\\\u0002"+
-    "\u0000EEee\u0002\u0000++--\u0001\u0000``\n\u0000\t\n\r\r  ,,//==[[]]`"+
-    "`||\u0002\u0000**//\u000b\u0000\t\n\r\r  \"#,,//::<<>?\\\\||\u04b9\u0000"+
-    "\f\u0001\u0000\u0000\u0000\u0000\u000e\u0001\u0000\u0000\u0000\u0000\u0010"+
-    "\u0001\u0000\u0000\u0000\u0000\u0012\u0001\u0000\u0000\u0000\u0000\u0014"+
-    "\u0001\u0000\u0000\u0000\u0000\u0016\u0001\u0000\u0000\u0000\u0000\u0018"+
-    "\u0001\u0000\u0000\u0000\u0000\u001a\u0001\u0000\u0000\u0000\u0000\u001c"+
-    "\u0001\u0000\u0000\u0000\u0000\u001e\u0001\u0000\u0000\u0000\u0000 \u0001"+
-    "\u0000\u0000\u0000\u0000\"\u0001\u0000\u0000\u0000\u0000$\u0001\u0000"+
-    "\u0000\u0000\u0000&\u0001\u0000\u0000\u0000\u0000(\u0001\u0000\u0000\u0000"+
-    "\u0000*\u0001\u0000\u0000\u0000\u0000,\u0001\u0000\u0000\u0000\u0000."+
-    "\u0001\u0000\u0000\u0000\u00000\u0001\u0000\u0000\u0000\u00002\u0001\u0000"+
-    "\u0000\u0000\u00004\u0001\u0000\u0000\u0000\u00006\u0001\u0000\u0000\u0000"+
-    "\u00018\u0001\u0000\u0000\u0000\u0001:\u0001\u0000\u0000\u0000\u0001<"+
-    "\u0001\u0000\u0000\u0000\u0001>\u0001\u0000\u0000\u0000\u0001@\u0001\u0000"+
-    "\u0000\u0000\u0002B\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`\u0001\u0000\u0000\u0000\u0002b\u0001"+
-    "\u0000\u0000\u0000\u0002d\u0001\u0000\u0000\u0000\u0002f\u0001\u0000\u0000"+
-    "\u0000\u0002h\u0001\u0000\u0000\u0000\u0002j\u0001\u0000\u0000\u0000\u0002"+
-    "l\u0001\u0000\u0000\u0000\u0002n\u0001\u0000\u0000\u0000\u0002p\u0001"+
-    "\u0000\u0000\u0000\u0002r\u0001\u0000\u0000\u0000\u0002t\u0001\u0000\u0000"+
-    "\u0000\u0002v\u0001\u0000\u0000\u0000\u0002x\u0001\u0000\u0000\u0000\u0002"+
-    "z\u0001\u0000\u0000\u0000\u0002|\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\u0002\u008a\u0001"+
-    "\u0000\u0000\u0000\u0002\u008c\u0001\u0000\u0000\u0000\u0002\u008e\u0001"+
-    "\u0000\u0000\u0000\u0002\u0090\u0001\u0000\u0000\u0000\u0002\u0092\u0001"+
-    "\u0000\u0000\u0000\u0002\u0094\u0001\u0000\u0000\u0000\u0002\u0096\u0001"+
-    "\u0000\u0000\u0000\u0002\u0098\u0001\u0000\u0000\u0000\u0002\u009a\u0001"+
-    "\u0000\u0000\u0000\u0002\u009c\u0001\u0000\u0000\u0000\u0002\u009e\u0001"+
-    "\u0000\u0000\u0000\u0002\u00a0\u0001\u0000\u0000\u0000\u0002\u00a2\u0001"+
-    "\u0000\u0000\u0000\u0002\u00a4\u0001\u0000\u0000\u0000\u0002\u00a6\u0001"+
-    "\u0000\u0000\u0000\u0002\u00aa\u0001\u0000\u0000\u0000\u0002\u00ac\u0001"+
-    "\u0000\u0000\u0000\u0002\u00ae\u0001\u0000\u0000\u0000\u0002\u00b0\u0001"+
-    "\u0000\u0000\u0000\u0003\u00b2\u0001\u0000\u0000\u0000\u0003\u00b4\u0001"+
-    "\u0000\u0000\u0000\u0003\u00b6\u0001\u0000\u0000\u0000\u0003\u00b8\u0001"+
-    "\u0000\u0000\u0000\u0003\u00ba\u0001\u0000\u0000\u0000\u0003\u00bc\u0001"+
-    "\u0000\u0000\u0000\u0003\u00c0\u0001\u0000\u0000\u0000\u0003\u00c2\u0001"+
-    "\u0000\u0000\u0000\u0003\u00c4\u0001\u0000\u0000\u0000\u0003\u00c6\u0001"+
-    "\u0000\u0000\u0000\u0003\u00c8\u0001\u0000\u0000\u0000\u0004\u00ca\u0001"+
-    "\u0000\u0000\u0000\u0004\u00cc\u0001\u0000\u0000\u0000\u0004\u00ce\u0001"+
-    "\u0000\u0000\u0000\u0004\u00d4\u0001\u0000\u0000\u0000\u0004\u00d6\u0001"+
-    "\u0000\u0000\u0000\u0004\u00d8\u0001\u0000\u0000\u0000\u0004\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\u0006\u00ee\u0001"+
-    "\u0000\u0000\u0000\u0006\u00f0\u0001\u0000\u0000\u0000\u0006\u00f2\u0001"+
-    "\u0000\u0000\u0000\u0006\u00f4\u0001\u0000\u0000\u0000\u0006\u00f8\u0001"+
-    "\u0000\u0000\u0000\u0006\u00fa\u0001\u0000\u0000\u0000\u0006\u00fc\u0001"+
-    "\u0000\u0000\u0000\u0006\u00fe\u0001\u0000\u0000\u0000\u0006\u0100\u0001"+
-    "\u0000\u0000\u0000\u0006\u0102\u0001\u0000\u0000\u0000\u0007\u0104\u0001"+
-    "\u0000\u0000\u0000\u0007\u0106\u0001\u0000\u0000\u0000\u0007\u0108\u0001"+
-    "\u0000\u0000\u0000\u0007\u010a\u0001\u0000\u0000\u0000\u0007\u010c\u0001"+
-    "\u0000\u0000\u0000\u0007\u010e\u0001\u0000\u0000\u0000\u0007\u0110\u0001"+
-    "\u0000\u0000\u0000\u0007\u0112\u0001\u0000\u0000\u0000\u0007\u0114\u0001"+
-    "\u0000\u0000\u0000\u0007\u0116\u0001\u0000\u0000\u0000\b\u0118\u0001\u0000"+
-    "\u0000\u0000\b\u011a\u0001\u0000\u0000\u0000\b\u011c\u0001\u0000\u0000"+
-    "\u0000\b\u011e\u0001\u0000\u0000\u0000\b\u0120\u0001\u0000\u0000\u0000"+
-    "\b\u0122\u0001\u0000\u0000\u0000\b\u0124\u0001\u0000\u0000\u0000\t\u0126"+
-    "\u0001\u0000\u0000\u0000\t\u0128\u0001\u0000\u0000\u0000\t\u012a\u0001"+
-    "\u0000\u0000\u0000\t\u012c\u0001\u0000\u0000\u0000\t\u012e\u0001\u0000"+
-    "\u0000\u0000\n\u0130\u0001\u0000\u0000\u0000\n\u0132\u0001\u0000\u0000"+
-    "\u0000\n\u0134\u0001\u0000\u0000\u0000\n\u0136\u0001\u0000\u0000\u0000"+
-    "\n\u0138\u0001\u0000\u0000\u0000\u000b\u013a\u0001\u0000\u0000\u0000\u000b"+
-    "\u013c\u0001\u0000\u0000\u0000\u000b\u013e\u0001\u0000\u0000\u0000\u000b"+
-    "\u0140\u0001\u0000\u0000\u0000\u000b\u0142\u0001\u0000\u0000\u0000\u000b"+
-    "\u0144\u0001\u0000\u0000\u0000\f\u0146\u0001\u0000\u0000\u0000\u000e\u0150"+
-    "\u0001\u0000\u0000\u0000\u0010\u0157\u0001\u0000\u0000\u0000\u0012\u0160"+
-    "\u0001\u0000\u0000\u0000\u0014\u0167\u0001\u0000\u0000\u0000\u0016\u0171"+
-    "\u0001\u0000\u0000\u0000\u0018\u0178\u0001\u0000\u0000\u0000\u001a\u017f"+
-    "\u0001\u0000\u0000\u0000\u001c\u018d\u0001\u0000\u0000\u0000\u001e\u0194"+
-    "\u0001\u0000\u0000\u0000 \u019c\u0001\u0000\u0000\u0000\"\u01a3\u0001"+
-    "\u0000\u0000\u0000$\u01af\u0001\u0000\u0000\u0000&\u01b8\u0001\u0000\u0000"+
-    "\u0000(\u01be\u0001\u0000\u0000\u0000*\u01c5\u0001\u0000\u0000\u0000,"+
-    "\u01cc\u0001\u0000\u0000\u0000.\u01d4\u0001\u0000\u0000\u00000\u01dd\u0001"+
-    "\u0000\u0000\u00002\u01e3\u0001\u0000\u0000\u00004\u01f4\u0001\u0000\u0000"+
-    "\u00006\u0204\u0001\u0000\u0000\u00008\u020a\u0001\u0000\u0000\u0000:"+
-    "\u020f\u0001\u0000\u0000\u0000<\u0214\u0001\u0000\u0000\u0000>\u0218\u0001"+
-    "\u0000\u0000\u0000@\u021c\u0001\u0000\u0000\u0000B\u0220\u0001\u0000\u0000"+
-    "\u0000D\u0224\u0001\u0000\u0000\u0000F\u0226\u0001\u0000\u0000\u0000H"+
-    "\u0228\u0001\u0000\u0000\u0000J\u022b\u0001\u0000\u0000\u0000L\u022d\u0001"+
-    "\u0000\u0000\u0000N\u0236\u0001\u0000\u0000\u0000P\u0238\u0001\u0000\u0000"+
-    "\u0000R\u023d\u0001\u0000\u0000\u0000T\u023f\u0001\u0000\u0000\u0000V"+
-    "\u0244\u0001\u0000\u0000\u0000X\u0263\u0001\u0000\u0000\u0000Z\u0266\u0001"+
-    "\u0000\u0000\u0000\\\u0294\u0001\u0000\u0000\u0000^\u0296\u0001\u0000"+
-    "\u0000\u0000`\u0299\u0001\u0000\u0000\u0000b\u029d\u0001\u0000\u0000\u0000"+
-    "d\u02a1\u0001\u0000\u0000\u0000f\u02a3\u0001\u0000\u0000\u0000h\u02a5"+
-    "\u0001\u0000\u0000\u0000j\u02aa\u0001\u0000\u0000\u0000l\u02ac\u0001\u0000"+
-    "\u0000\u0000n\u02b2\u0001\u0000\u0000\u0000p\u02b8\u0001\u0000\u0000\u0000"+
-    "r\u02bd\u0001\u0000\u0000\u0000t\u02bf\u0001\u0000\u0000\u0000v\u02c2"+
-    "\u0001\u0000\u0000\u0000x\u02c5\u0001\u0000\u0000\u0000z\u02ca\u0001\u0000"+
-    "\u0000\u0000|\u02ce\u0001\u0000\u0000\u0000~\u02d3\u0001\u0000\u0000\u0000"+
-    "\u0080\u02d9\u0001\u0000\u0000\u0000\u0082\u02dc\u0001\u0000\u0000\u0000"+
-    "\u0084\u02de\u0001\u0000\u0000\u0000\u0086\u02e4\u0001\u0000\u0000\u0000"+
-    "\u0088\u02e6\u0001\u0000\u0000\u0000\u008a\u02eb\u0001\u0000\u0000\u0000"+
-    "\u008c\u02ee\u0001\u0000\u0000\u0000\u008e\u02f1\u0001\u0000\u0000\u0000"+
-    "\u0090\u02f4\u0001\u0000\u0000\u0000\u0092\u02f6\u0001\u0000\u0000\u0000"+
-    "\u0094\u02f9\u0001\u0000\u0000\u0000\u0096\u02fb\u0001\u0000\u0000\u0000"+
-    "\u0098\u02fe\u0001\u0000\u0000\u0000\u009a\u0300\u0001\u0000\u0000\u0000"+
-    "\u009c\u0302\u0001\u0000\u0000\u0000\u009e\u0304\u0001\u0000\u0000\u0000"+
-    "\u00a0\u0306\u0001\u0000\u0000\u0000\u00a2\u0308\u0001\u0000\u0000\u0000"+
-    "\u00a4\u030d\u0001\u0000\u0000\u0000\u00a6\u0322\u0001\u0000\u0000\u0000"+
-    "\u00a8\u0324\u0001\u0000\u0000\u0000\u00aa\u032c\u0001\u0000\u0000\u0000"+
-    "\u00ac\u032e\u0001\u0000\u0000\u0000\u00ae\u0332\u0001\u0000\u0000\u0000"+
-    "\u00b0\u0336\u0001\u0000\u0000\u0000\u00b2\u033a\u0001\u0000\u0000\u0000"+
-    "\u00b4\u033f\u0001\u0000\u0000\u0000\u00b6\u0343\u0001\u0000\u0000\u0000"+
-    "\u00b8\u0347\u0001\u0000\u0000\u0000\u00ba\u034b\u0001\u0000\u0000\u0000"+
-    "\u00bc\u034f\u0001\u0000\u0000\u0000\u00be\u035b\u0001\u0000\u0000\u0000"+
-    "\u00c0\u035e\u0001\u0000\u0000\u0000\u00c2\u0362\u0001\u0000\u0000\u0000"+
-    "\u00c4\u0366\u0001\u0000\u0000\u0000\u00c6\u036a\u0001\u0000\u0000\u0000"+
-    "\u00c8\u036e\u0001\u0000\u0000\u0000\u00ca\u0372\u0001\u0000\u0000\u0000"+
-    "\u00cc\u0377\u0001\u0000\u0000\u0000\u00ce\u037b\u0001\u0000\u0000\u0000"+
-    "\u00d0\u0383\u0001\u0000\u0000\u0000\u00d2\u0398\u0001\u0000\u0000\u0000"+
-    "\u00d4\u039c\u0001\u0000\u0000\u0000\u00d6\u03a0\u0001\u0000\u0000\u0000"+
-    "\u00d8\u03a4\u0001\u0000\u0000\u0000\u00da\u03a8\u0001\u0000\u0000\u0000"+
-    "\u00dc\u03ac\u0001\u0000\u0000\u0000\u00de\u03b1\u0001\u0000\u0000\u0000"+
-    "\u00e0\u03b5\u0001\u0000\u0000\u0000\u00e2\u03b9\u0001\u0000\u0000\u0000"+
-    "\u00e4\u03bd\u0001\u0000\u0000\u0000\u00e6\u03c0\u0001\u0000\u0000\u0000"+
-    "\u00e8\u03c4\u0001\u0000\u0000\u0000\u00ea\u03c8\u0001\u0000\u0000\u0000"+
-    "\u00ec\u03cc\u0001\u0000\u0000\u0000\u00ee\u03d0\u0001\u0000\u0000\u0000"+
-    "\u00f0\u03d5\u0001\u0000\u0000\u0000\u00f2\u03da\u0001\u0000\u0000\u0000"+
-    "\u00f4\u03df\u0001\u0000\u0000\u0000\u00f6\u03e6\u0001\u0000\u0000\u0000"+
-    "\u00f8\u03ef\u0001\u0000\u0000\u0000\u00fa\u03f6\u0001\u0000\u0000\u0000"+
-    "\u00fc\u03fa\u0001\u0000\u0000\u0000\u00fe\u03fe\u0001\u0000\u0000\u0000"+
-    "\u0100\u0402\u0001\u0000\u0000\u0000\u0102\u0406\u0001\u0000\u0000\u0000"+
-    "\u0104\u040a\u0001\u0000\u0000\u0000\u0106\u0410\u0001\u0000\u0000\u0000"+
-    "\u0108\u0414\u0001\u0000\u0000\u0000\u010a\u0418\u0001\u0000\u0000\u0000"+
-    "\u010c\u041c\u0001\u0000\u0000\u0000\u010e\u0420\u0001\u0000\u0000\u0000"+
-    "\u0110\u0424\u0001\u0000\u0000\u0000\u0112\u0428\u0001\u0000\u0000\u0000"+
-    "\u0114\u042c\u0001\u0000\u0000\u0000\u0116\u0430\u0001\u0000\u0000\u0000"+
-    "\u0118\u0434\u0001\u0000\u0000\u0000\u011a\u0439\u0001\u0000\u0000\u0000"+
-    "\u011c\u043d\u0001\u0000\u0000\u0000\u011e\u0441\u0001\u0000\u0000\u0000"+
-    "\u0120\u0445\u0001\u0000\u0000\u0000\u0122\u0449\u0001\u0000\u0000\u0000"+
-    "\u0124\u044d\u0001\u0000\u0000\u0000\u0126\u0451\u0001\u0000\u0000\u0000"+
-    "\u0128\u0456\u0001\u0000\u0000\u0000\u012a\u045b\u0001\u0000\u0000\u0000"+
-    "\u012c\u045f\u0001\u0000\u0000\u0000\u012e\u0463\u0001\u0000\u0000\u0000"+
-    "\u0130\u0467\u0001\u0000\u0000\u0000\u0132\u046c\u0001\u0000\u0000\u0000"+
-    "\u0134\u0476\u0001\u0000\u0000\u0000\u0136\u047a\u0001\u0000\u0000\u0000"+
-    "\u0138\u047e\u0001\u0000\u0000\u0000\u013a\u0482\u0001\u0000\u0000\u0000"+
-    "\u013c\u0487\u0001\u0000\u0000\u0000\u013e\u048e\u0001\u0000\u0000\u0000"+
-    "\u0140\u0492\u0001\u0000\u0000\u0000\u0142\u0496\u0001\u0000\u0000\u0000"+
-    "\u0144\u049a\u0001\u0000\u0000\u0000\u0146\u0147\u0005d\u0000\u0000\u0147"+
-    "\u0148\u0005i\u0000\u0000\u0148\u0149\u0005s\u0000\u0000\u0149\u014a\u0005"+
-    "s\u0000\u0000\u014a\u014b\u0005e\u0000\u0000\u014b\u014c\u0005c\u0000"+
-    "\u0000\u014c\u014d\u0005t\u0000\u0000\u014d\u014e\u0001\u0000\u0000\u0000"+
-    "\u014e\u014f\u0006\u0000\u0000\u0000\u014f\r\u0001\u0000\u0000\u0000\u0150"+
-    "\u0151\u0005d\u0000\u0000\u0151\u0152\u0005r\u0000\u0000\u0152\u0153\u0005"+
-    "o\u0000\u0000\u0153\u0154\u0005p\u0000\u0000\u0154\u0155\u0001\u0000\u0000"+
-    "\u0000\u0155\u0156\u0006\u0001\u0001\u0000\u0156\u000f\u0001\u0000\u0000"+
-    "\u0000\u0157\u0158\u0005e\u0000\u0000\u0158\u0159\u0005n\u0000\u0000\u0159"+
-    "\u015a\u0005r\u0000\u0000\u015a\u015b\u0005i\u0000\u0000\u015b\u015c\u0005"+
-    "c\u0000\u0000\u015c\u015d\u0005h\u0000\u0000\u015d\u015e\u0001\u0000\u0000"+
-    "\u0000\u015e\u015f\u0006\u0002\u0002\u0000\u015f\u0011\u0001\u0000\u0000"+
-    "\u0000\u0160\u0161\u0005e\u0000\u0000\u0161\u0162\u0005v\u0000\u0000\u0162"+
-    "\u0163\u0005a\u0000\u0000\u0163\u0164\u0005l\u0000\u0000\u0164\u0165\u0001"+
-    "\u0000\u0000\u0000\u0165\u0166\u0006\u0003\u0000\u0000\u0166\u0013\u0001"+
-    "\u0000\u0000\u0000\u0167\u0168\u0005e\u0000\u0000\u0168\u0169\u0005x\u0000"+
-    "\u0000\u0169\u016a\u0005p\u0000\u0000\u016a\u016b\u0005l\u0000\u0000\u016b"+
-    "\u016c\u0005a\u0000\u0000\u016c\u016d\u0005i\u0000\u0000\u016d\u016e\u0005"+
-    "n\u0000\u0000\u016e\u016f\u0001\u0000\u0000\u0000\u016f\u0170\u0006\u0004"+
-    "\u0003\u0000\u0170\u0015\u0001\u0000\u0000\u0000\u0171\u0172\u0005f\u0000"+
-    "\u0000\u0172\u0173\u0005r\u0000\u0000\u0173\u0174\u0005o\u0000\u0000\u0174"+
-    "\u0175\u0005m\u0000\u0000\u0175\u0176\u0001\u0000\u0000\u0000\u0176\u0177"+
-    "\u0006\u0005\u0004\u0000\u0177\u0017\u0001\u0000\u0000\u0000\u0178\u0179"+
-    "\u0005g\u0000\u0000\u0179\u017a\u0005r\u0000\u0000\u017a\u017b\u0005o"+
-    "\u0000\u0000\u017b\u017c\u0005k\u0000\u0000\u017c\u017d\u0001\u0000\u0000"+
-    "\u0000\u017d\u017e\u0006\u0006\u0000\u0000\u017e\u0019\u0001\u0000\u0000"+
-    "\u0000\u017f\u0180\u0005i\u0000\u0000\u0180\u0181\u0005n\u0000\u0000\u0181"+
-    "\u0182\u0005l\u0000\u0000\u0182\u0183\u0005i\u0000\u0000\u0183\u0184\u0005"+
-    "n\u0000\u0000\u0184\u0185\u0005e\u0000\u0000\u0185\u0186\u0005s\u0000"+
-    "\u0000\u0186\u0187\u0005t\u0000\u0000\u0187\u0188\u0005a\u0000\u0000\u0188"+
-    "\u0189\u0005t\u0000\u0000\u0189\u018a\u0005s\u0000\u0000\u018a\u018b\u0001"+
-    "\u0000\u0000\u0000\u018b\u018c\u0006\u0007\u0000\u0000\u018c\u001b\u0001"+
-    "\u0000\u0000\u0000\u018d\u018e\u0005k\u0000\u0000\u018e\u018f\u0005e\u0000"+
-    "\u0000\u018f\u0190\u0005e\u0000\u0000\u0190\u0191\u0005p\u0000\u0000\u0191"+
-    "\u0192\u0001\u0000\u0000\u0000\u0192\u0193\u0006\b\u0001\u0000\u0193\u001d"+
-    "\u0001\u0000\u0000\u0000\u0194\u0195\u0005l\u0000\u0000\u0195\u0196\u0005"+
-    "i\u0000\u0000\u0196\u0197\u0005m\u0000\u0000\u0197\u0198\u0005i\u0000"+
-    "\u0000\u0198\u0199\u0005t\u0000\u0000\u0199\u019a\u0001\u0000\u0000\u0000"+
-    "\u019a\u019b\u0006\t\u0000\u0000\u019b\u001f\u0001\u0000\u0000\u0000\u019c"+
-    "\u019d\u0005m\u0000\u0000\u019d\u019e\u0005e\u0000\u0000\u019e\u019f\u0005"+
-    "t\u0000\u0000\u019f\u01a0\u0005a\u0000\u0000\u01a0\u01a1\u0001\u0000\u0000"+
-    "\u0000\u01a1\u01a2\u0006\n\u0005\u0000\u01a2!\u0001\u0000\u0000\u0000"+
-    "\u01a3\u01a4\u0005m\u0000\u0000\u01a4\u01a5\u0005v\u0000\u0000\u01a5\u01a6"+
-    "\u0005_\u0000\u0000\u01a6\u01a7\u0005e\u0000\u0000\u01a7\u01a8\u0005x"+
-    "\u0000\u0000\u01a8\u01a9\u0005p\u0000\u0000\u01a9\u01aa\u0005a\u0000\u0000"+
-    "\u01aa\u01ab\u0005n\u0000\u0000\u01ab\u01ac\u0005d\u0000\u0000\u01ac\u01ad"+
-    "\u0001\u0000\u0000\u0000\u01ad\u01ae\u0006\u000b\u0006\u0000\u01ae#\u0001"+
-    "\u0000\u0000\u0000\u01af\u01b0\u0005r\u0000\u0000\u01b0\u01b1\u0005e\u0000"+
-    "\u0000\u01b1\u01b2\u0005n\u0000\u0000\u01b2\u01b3\u0005a\u0000\u0000\u01b3"+
-    "\u01b4\u0005m\u0000\u0000\u01b4\u01b5\u0005e\u0000\u0000\u01b5\u01b6\u0001"+
-    "\u0000\u0000\u0000\u01b6\u01b7\u0006\f\u0007\u0000\u01b7%\u0001\u0000"+
-    "\u0000\u0000\u01b8\u01b9\u0005r\u0000\u0000\u01b9\u01ba\u0005o\u0000\u0000"+
-    "\u01ba\u01bb\u0005w\u0000\u0000\u01bb\u01bc\u0001\u0000\u0000\u0000\u01bc"+
-    "\u01bd\u0006\r\u0000\u0000\u01bd\'\u0001\u0000\u0000\u0000\u01be\u01bf"+
-    "\u0005s\u0000\u0000\u01bf\u01c0\u0005h\u0000\u0000\u01c0\u01c1\u0005o"+
-    "\u0000\u0000\u01c1\u01c2\u0005w\u0000\u0000\u01c2\u01c3\u0001\u0000\u0000"+
-    "\u0000\u01c3\u01c4\u0006\u000e\b\u0000\u01c4)\u0001\u0000\u0000\u0000"+
-    "\u01c5\u01c6\u0005s\u0000\u0000\u01c6\u01c7\u0005o\u0000\u0000\u01c7\u01c8"+
-    "\u0005r\u0000\u0000\u01c8\u01c9\u0005t\u0000\u0000\u01c9\u01ca\u0001\u0000"+
-    "\u0000\u0000\u01ca\u01cb\u0006\u000f\u0000\u0000\u01cb+\u0001\u0000\u0000"+
-    "\u0000\u01cc\u01cd\u0005s\u0000\u0000\u01cd\u01ce\u0005t\u0000\u0000\u01ce"+
-    "\u01cf\u0005a\u0000\u0000\u01cf\u01d0\u0005t\u0000\u0000\u01d0\u01d1\u0005"+
-    "s\u0000\u0000\u01d1\u01d2\u0001\u0000\u0000\u0000\u01d2\u01d3\u0006\u0010"+
-    "\u0000\u0000\u01d3-\u0001\u0000\u0000\u0000\u01d4\u01d5\u0005w\u0000\u0000"+
-    "\u01d5\u01d6\u0005h\u0000\u0000\u01d6\u01d7\u0005e\u0000\u0000\u01d7\u01d8"+
-    "\u0005r\u0000\u0000\u01d8\u01d9\u0005e\u0000\u0000\u01d9\u01da\u0001\u0000"+
-    "\u0000\u0000\u01da\u01db\u0006\u0011\u0000\u0000\u01db/\u0001\u0000\u0000"+
-    "\u0000\u01dc\u01de\b\u0000\u0000\u0000\u01dd\u01dc\u0001\u0000\u0000\u0000"+
-    "\u01de\u01df\u0001\u0000\u0000\u0000\u01df\u01dd\u0001\u0000\u0000\u0000"+
-    "\u01df\u01e0\u0001\u0000\u0000\u0000\u01e0\u01e1\u0001\u0000\u0000\u0000"+
-    "\u01e1\u01e2\u0006\u0012\u0000\u0000\u01e21\u0001\u0000\u0000\u0000\u01e3"+
-    "\u01e4\u0005/\u0000\u0000\u01e4\u01e5\u0005/\u0000\u0000\u01e5\u01e9\u0001"+
-    "\u0000\u0000\u0000\u01e6\u01e8\b\u0001\u0000\u0000\u01e7\u01e6\u0001\u0000"+
-    "\u0000\u0000\u01e8\u01eb\u0001\u0000\u0000\u0000\u01e9\u01e7\u0001\u0000"+
-    "\u0000\u0000\u01e9\u01ea\u0001\u0000\u0000\u0000\u01ea\u01ed\u0001\u0000"+
-    "\u0000\u0000\u01eb\u01e9\u0001\u0000\u0000\u0000\u01ec\u01ee\u0005\r\u0000"+
-    "\u0000\u01ed\u01ec\u0001\u0000\u0000\u0000\u01ed\u01ee\u0001\u0000\u0000"+
-    "\u0000\u01ee\u01f0\u0001\u0000\u0000\u0000\u01ef\u01f1\u0005\n\u0000\u0000"+
-    "\u01f0\u01ef\u0001\u0000\u0000\u0000\u01f0\u01f1\u0001\u0000\u0000\u0000"+
-    "\u01f1\u01f2\u0001\u0000\u0000\u0000\u01f2\u01f3\u0006\u0013\t\u0000\u01f3"+
-    "3\u0001\u0000\u0000\u0000\u01f4\u01f5\u0005/\u0000\u0000\u01f5\u01f6\u0005"+
-    "*\u0000\u0000\u01f6\u01fb\u0001\u0000\u0000\u0000\u01f7\u01fa\u00034\u0014"+
-    "\u0000\u01f8\u01fa\t\u0000\u0000\u0000\u01f9\u01f7\u0001\u0000\u0000\u0000"+
-    "\u01f9\u01f8\u0001\u0000\u0000\u0000\u01fa\u01fd\u0001\u0000\u0000\u0000"+
-    "\u01fb\u01fc\u0001\u0000\u0000\u0000\u01fb\u01f9\u0001\u0000\u0000\u0000"+
-    "\u01fc\u01fe\u0001\u0000\u0000\u0000\u01fd\u01fb\u0001\u0000\u0000\u0000"+
-    "\u01fe\u01ff\u0005*\u0000\u0000\u01ff\u0200\u0005/\u0000\u0000\u0200\u0201"+
-    "\u0001\u0000\u0000\u0000\u0201\u0202\u0006\u0014\t\u0000\u02025\u0001"+
-    "\u0000\u0000\u0000\u0203\u0205\u0007\u0002\u0000\u0000\u0204\u0203\u0001"+
-    "\u0000\u0000\u0000\u0205\u0206\u0001\u0000\u0000\u0000\u0206\u0204\u0001"+
-    "\u0000\u0000\u0000\u0206\u0207\u0001\u0000\u0000\u0000\u0207\u0208\u0001"+
-    "\u0000\u0000\u0000\u0208\u0209\u0006\u0015\t\u0000\u02097\u0001\u0000"+
-    "\u0000\u0000\u020a\u020b\u0003\u00a2K\u0000\u020b\u020c\u0001\u0000\u0000"+
-    "\u0000\u020c\u020d\u0006\u0016\n\u0000\u020d\u020e\u0006\u0016\u000b\u0000"+
-    "\u020e9\u0001\u0000\u0000\u0000\u020f\u0210\u0003B\u001b\u0000\u0210\u0211"+
-    "\u0001\u0000\u0000\u0000\u0211\u0212\u0006\u0017\f\u0000\u0212\u0213\u0006"+
-    "\u0017\r\u0000\u0213;\u0001\u0000\u0000\u0000\u0214\u0215\u00036\u0015"+
-    "\u0000\u0215\u0216\u0001\u0000\u0000\u0000\u0216\u0217\u0006\u0018\t\u0000"+
-    "\u0217=\u0001\u0000\u0000\u0000\u0218\u0219\u00032\u0013\u0000\u0219\u021a"+
-    "\u0001\u0000\u0000\u0000\u021a\u021b\u0006\u0019\t\u0000\u021b?\u0001"+
-    "\u0000\u0000\u0000\u021c\u021d\u00034\u0014\u0000\u021d\u021e\u0001\u0000"+
-    "\u0000\u0000\u021e\u021f\u0006\u001a\t\u0000\u021fA\u0001\u0000\u0000"+
-    "\u0000\u0220\u0221\u0005|\u0000\u0000\u0221\u0222\u0001\u0000\u0000\u0000"+
-    "\u0222\u0223\u0006\u001b\r\u0000\u0223C\u0001\u0000\u0000\u0000\u0224"+
-    "\u0225\u0007\u0003\u0000\u0000\u0225E\u0001\u0000\u0000\u0000\u0226\u0227"+
-    "\u0007\u0004\u0000\u0000\u0227G\u0001\u0000\u0000\u0000\u0228\u0229\u0005"+
-    "\\\u0000\u0000\u0229\u022a\u0007\u0005\u0000\u0000\u022aI\u0001\u0000"+
-    "\u0000\u0000\u022b\u022c\b\u0006\u0000\u0000\u022cK\u0001\u0000\u0000"+
-    "\u0000\u022d\u022f\u0007\u0007\u0000\u0000\u022e\u0230\u0007\b\u0000\u0000"+
-    "\u022f\u022e\u0001\u0000\u0000\u0000\u022f\u0230\u0001\u0000\u0000\u0000"+
-    "\u0230\u0232\u0001\u0000\u0000\u0000\u0231\u0233\u0003D\u001c\u0000\u0232"+
-    "\u0231\u0001\u0000\u0000\u0000\u0233\u0234\u0001\u0000\u0000\u0000\u0234"+
-    "\u0232\u0001\u0000\u0000\u0000\u0234\u0235\u0001\u0000\u0000\u0000\u0235"+
-    "M\u0001\u0000\u0000\u0000\u0236\u0237\u0005@\u0000\u0000\u0237O\u0001"+
-    "\u0000\u0000\u0000\u0238\u0239\u0005`\u0000\u0000\u0239Q\u0001\u0000\u0000"+
-    "\u0000\u023a\u023e\b\t\u0000\u0000\u023b\u023c\u0005`\u0000\u0000\u023c"+
-    "\u023e\u0005`\u0000\u0000\u023d\u023a\u0001\u0000\u0000\u0000\u023d\u023b"+
-    "\u0001\u0000\u0000\u0000\u023eS\u0001\u0000\u0000\u0000\u023f\u0240\u0005"+
-    "_\u0000\u0000\u0240U\u0001\u0000\u0000\u0000\u0241\u0245\u0003F\u001d"+
-    "\u0000\u0242\u0245\u0003D\u001c\u0000\u0243\u0245\u0003T$\u0000\u0244"+
-    "\u0241\u0001\u0000\u0000\u0000\u0244\u0242\u0001\u0000\u0000\u0000\u0244"+
-    "\u0243\u0001\u0000\u0000\u0000\u0245W\u0001\u0000\u0000\u0000\u0246\u024b"+
-    "\u0005\"\u0000\u0000\u0247\u024a\u0003H\u001e\u0000\u0248\u024a\u0003"+
-    "J\u001f\u0000\u0249\u0247\u0001\u0000\u0000\u0000\u0249\u0248\u0001\u0000"+
-    "\u0000\u0000\u024a\u024d\u0001\u0000\u0000\u0000\u024b\u0249\u0001\u0000"+
-    "\u0000\u0000\u024b\u024c\u0001\u0000\u0000\u0000\u024c\u024e\u0001\u0000"+
-    "\u0000\u0000\u024d\u024b\u0001\u0000\u0000\u0000\u024e\u0264\u0005\"\u0000"+
-    "\u0000\u024f\u0250\u0005\"\u0000\u0000\u0250\u0251\u0005\"\u0000\u0000"+
-    "\u0251\u0252\u0005\"\u0000\u0000\u0252\u0256\u0001\u0000\u0000\u0000\u0253"+
-    "\u0255\b\u0001\u0000\u0000\u0254\u0253\u0001\u0000\u0000\u0000\u0255\u0258"+
-    "\u0001\u0000\u0000\u0000\u0256\u0257\u0001\u0000\u0000\u0000\u0256\u0254"+
-    "\u0001\u0000\u0000\u0000\u0257\u0259\u0001\u0000\u0000\u0000\u0258\u0256"+
-    "\u0001\u0000\u0000\u0000\u0259\u025a\u0005\"\u0000\u0000\u025a\u025b\u0005"+
-    "\"\u0000\u0000\u025b\u025c\u0005\"\u0000\u0000\u025c\u025e\u0001\u0000"+
-    "\u0000\u0000\u025d\u025f\u0005\"\u0000\u0000\u025e\u025d\u0001\u0000\u0000"+
-    "\u0000\u025e\u025f\u0001\u0000\u0000\u0000\u025f\u0261\u0001\u0000\u0000"+
-    "\u0000\u0260\u0262\u0005\"\u0000\u0000\u0261\u0260\u0001\u0000\u0000\u0000"+
-    "\u0261\u0262\u0001\u0000\u0000\u0000\u0262\u0264\u0001\u0000\u0000\u0000"+
-    "\u0263\u0246\u0001\u0000\u0000\u0000\u0263\u024f\u0001\u0000\u0000\u0000"+
-    "\u0264Y\u0001\u0000\u0000\u0000\u0265\u0267\u0003D\u001c\u0000\u0266\u0265"+
-    "\u0001\u0000\u0000\u0000\u0267\u0268\u0001\u0000\u0000\u0000\u0268\u0266"+
-    "\u0001\u0000\u0000\u0000\u0268\u0269\u0001\u0000\u0000\u0000\u0269[\u0001"+
-    "\u0000\u0000\u0000\u026a\u026c\u0003D\u001c\u0000\u026b\u026a\u0001\u0000"+
-    "\u0000\u0000\u026c\u026d\u0001\u0000\u0000\u0000\u026d\u026b\u0001\u0000"+
-    "\u0000\u0000\u026d\u026e\u0001\u0000\u0000\u0000\u026e\u026f\u0001\u0000"+
-    "\u0000\u0000\u026f\u0273\u0003j/\u0000\u0270\u0272\u0003D\u001c\u0000"+
-    "\u0271\u0270\u0001\u0000\u0000\u0000\u0272\u0275\u0001\u0000\u0000\u0000"+
-    "\u0273\u0271\u0001\u0000\u0000\u0000\u0273\u0274\u0001\u0000\u0000\u0000"+
-    "\u0274\u0295\u0001\u0000\u0000\u0000\u0275\u0273\u0001\u0000\u0000\u0000"+
-    "\u0276\u0278\u0003j/\u0000\u0277\u0279\u0003D\u001c\u0000\u0278\u0277"+
-    "\u0001\u0000\u0000\u0000\u0279\u027a\u0001\u0000\u0000\u0000\u027a\u0278"+
-    "\u0001\u0000\u0000\u0000\u027a\u027b\u0001\u0000\u0000\u0000\u027b\u0295"+
-    "\u0001\u0000\u0000\u0000\u027c\u027e\u0003D\u001c\u0000\u027d\u027c\u0001"+
-    "\u0000\u0000\u0000\u027e\u027f\u0001\u0000\u0000\u0000\u027f\u027d\u0001"+
-    "\u0000\u0000\u0000\u027f\u0280\u0001\u0000\u0000\u0000\u0280\u0288\u0001"+
-    "\u0000\u0000\u0000\u0281\u0285\u0003j/\u0000\u0282\u0284\u0003D\u001c"+
-    "\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\u0289\u0001\u0000\u0000\u0000\u0287\u0285\u0001\u0000\u0000"+
-    "\u0000\u0288\u0281\u0001\u0000\u0000\u0000\u0288\u0289\u0001\u0000\u0000"+
-    "\u0000\u0289\u028a\u0001\u0000\u0000\u0000\u028a\u028b\u0003L \u0000\u028b"+
-    "\u0295\u0001\u0000\u0000\u0000\u028c\u028e\u0003j/\u0000\u028d\u028f\u0003"+
-    "D\u001c\u0000\u028e\u028d\u0001\u0000\u0000\u0000\u028f\u0290\u0001\u0000"+
-    "\u0000\u0000\u0290\u028e\u0001\u0000\u0000\u0000\u0290\u0291\u0001\u0000"+
-    "\u0000\u0000\u0291\u0292\u0001\u0000\u0000\u0000\u0292\u0293\u0003L \u0000"+
-    "\u0293\u0295\u0001\u0000\u0000\u0000\u0294\u026b\u0001\u0000\u0000\u0000"+
-    "\u0294\u0276\u0001\u0000\u0000\u0000\u0294\u027d\u0001\u0000\u0000\u0000"+
-    "\u0294\u028c\u0001\u0000\u0000\u0000\u0295]\u0001\u0000\u0000\u0000\u0296"+
-    "\u0297\u0005b\u0000\u0000\u0297\u0298\u0005y\u0000\u0000\u0298_\u0001"+
-    "\u0000\u0000\u0000\u0299\u029a\u0005a\u0000\u0000\u029a\u029b\u0005n\u0000"+
-    "\u0000\u029b\u029c\u0005d\u0000\u0000\u029ca\u0001\u0000\u0000\u0000\u029d"+
-    "\u029e\u0005a\u0000\u0000\u029e\u029f\u0005s\u0000\u0000\u029f\u02a0\u0005"+
-    "c\u0000\u0000\u02a0c\u0001\u0000\u0000\u0000\u02a1\u02a2\u0005=\u0000"+
-    "\u0000\u02a2e\u0001\u0000\u0000\u0000\u02a3\u02a4\u0005,\u0000\u0000\u02a4"+
-    "g\u0001\u0000\u0000\u0000\u02a5\u02a6\u0005d\u0000\u0000\u02a6\u02a7\u0005"+
-    "e\u0000\u0000\u02a7\u02a8\u0005s\u0000\u0000\u02a8\u02a9\u0005c\u0000"+
-    "\u0000\u02a9i\u0001\u0000\u0000\u0000\u02aa\u02ab\u0005.\u0000\u0000\u02ab"+
-    "k\u0001\u0000\u0000\u0000\u02ac\u02ad\u0005f\u0000\u0000\u02ad\u02ae\u0005"+
-    "a\u0000\u0000\u02ae\u02af\u0005l\u0000\u0000\u02af\u02b0\u0005s\u0000"+
-    "\u0000\u02b0\u02b1\u0005e\u0000\u0000\u02b1m\u0001\u0000\u0000\u0000\u02b2"+
-    "\u02b3\u0005f\u0000\u0000\u02b3\u02b4\u0005i\u0000\u0000\u02b4\u02b5\u0005"+
-    "r\u0000\u0000\u02b5\u02b6\u0005s\u0000\u0000\u02b6\u02b7\u0005t\u0000"+
-    "\u0000\u02b7o\u0001\u0000\u0000\u0000\u02b8\u02b9\u0005l\u0000\u0000\u02b9"+
-    "\u02ba\u0005a\u0000\u0000\u02ba\u02bb\u0005s\u0000\u0000\u02bb\u02bc\u0005"+
-    "t\u0000\u0000\u02bcq\u0001\u0000\u0000\u0000\u02bd\u02be\u0005(\u0000"+
-    "\u0000\u02bes\u0001\u0000\u0000\u0000\u02bf\u02c0\u0005i\u0000\u0000\u02c0"+
-    "\u02c1\u0005n\u0000\u0000\u02c1u\u0001\u0000\u0000\u0000\u02c2\u02c3\u0005"+
-    "i\u0000\u0000\u02c3\u02c4\u0005s\u0000\u0000\u02c4w\u0001\u0000\u0000"+
-    "\u0000\u02c5\u02c6\u0005l\u0000\u0000\u02c6\u02c7\u0005i\u0000\u0000\u02c7"+
-    "\u02c8\u0005k\u0000\u0000\u02c8\u02c9\u0005e\u0000\u0000\u02c9y\u0001"+
-    "\u0000\u0000\u0000\u02ca\u02cb\u0005n\u0000\u0000\u02cb\u02cc\u0005o\u0000"+
-    "\u0000\u02cc\u02cd\u0005t\u0000\u0000\u02cd{\u0001\u0000\u0000\u0000\u02ce"+
-    "\u02cf\u0005n\u0000\u0000\u02cf\u02d0\u0005u\u0000\u0000\u02d0\u02d1\u0005"+
-    "l\u0000\u0000\u02d1\u02d2\u0005l\u0000\u0000\u02d2}\u0001\u0000\u0000"+
-    "\u0000\u02d3\u02d4\u0005n\u0000\u0000\u02d4\u02d5\u0005u\u0000\u0000\u02d5"+
-    "\u02d6\u0005l\u0000\u0000\u02d6\u02d7\u0005l\u0000\u0000\u02d7\u02d8\u0005"+
-    "s\u0000\u0000\u02d8\u007f\u0001\u0000\u0000\u0000\u02d9\u02da\u0005o\u0000"+
-    "\u0000\u02da\u02db\u0005r\u0000\u0000\u02db\u0081\u0001\u0000\u0000\u0000"+
-    "\u02dc\u02dd\u0005?\u0000\u0000\u02dd\u0083\u0001\u0000\u0000\u0000\u02de"+
-    "\u02df\u0005r\u0000\u0000\u02df\u02e0\u0005l\u0000\u0000\u02e0\u02e1\u0005"+
-    "i\u0000\u0000\u02e1\u02e2\u0005k\u0000\u0000\u02e2\u02e3\u0005e\u0000"+
-    "\u0000\u02e3\u0085\u0001\u0000\u0000\u0000\u02e4\u02e5\u0005)\u0000\u0000"+
-    "\u02e5\u0087\u0001\u0000\u0000\u0000\u02e6\u02e7\u0005t\u0000\u0000\u02e7"+
-    "\u02e8\u0005r\u0000\u0000\u02e8\u02e9\u0005u\u0000\u0000\u02e9\u02ea\u0005"+
-    "e\u0000\u0000\u02ea\u0089\u0001\u0000\u0000\u0000\u02eb\u02ec\u0005=\u0000"+
-    "\u0000\u02ec\u02ed\u0005=\u0000\u0000\u02ed\u008b\u0001\u0000\u0000\u0000"+
-    "\u02ee\u02ef\u0005=\u0000\u0000\u02ef\u02f0\u0005~\u0000\u0000\u02f0\u008d"+
-    "\u0001\u0000\u0000\u0000\u02f1\u02f2\u0005!\u0000\u0000\u02f2\u02f3\u0005"+
-    "=\u0000\u0000\u02f3\u008f\u0001\u0000\u0000\u0000\u02f4\u02f5\u0005<\u0000"+
-    "\u0000\u02f5\u0091\u0001\u0000\u0000\u0000\u02f6\u02f7\u0005<\u0000\u0000"+
-    "\u02f7\u02f8\u0005=\u0000\u0000\u02f8\u0093\u0001\u0000\u0000\u0000\u02f9"+
-    "\u02fa\u0005>\u0000\u0000\u02fa\u0095\u0001\u0000\u0000\u0000\u02fb\u02fc"+
-    "\u0005>\u0000\u0000\u02fc\u02fd\u0005=\u0000\u0000\u02fd\u0097\u0001\u0000"+
-    "\u0000\u0000\u02fe\u02ff\u0005+\u0000\u0000\u02ff\u0099\u0001\u0000\u0000"+
-    "\u0000\u0300\u0301\u0005-\u0000\u0000\u0301\u009b\u0001\u0000\u0000\u0000"+
-    "\u0302\u0303\u0005*\u0000\u0000\u0303\u009d\u0001\u0000\u0000\u0000\u0304"+
-    "\u0305\u0005/\u0000\u0000\u0305\u009f\u0001\u0000\u0000\u0000\u0306\u0307"+
-    "\u0005%\u0000\u0000\u0307\u00a1\u0001\u0000\u0000\u0000\u0308\u0309\u0005"+
-    "[\u0000\u0000\u0309\u030a\u0001\u0000\u0000\u0000\u030a\u030b\u0006K\u0000"+
-    "\u0000\u030b\u030c\u0006K\u0000\u0000\u030c\u00a3\u0001\u0000\u0000\u0000"+
-    "\u030d\u030e\u0005]\u0000\u0000\u030e\u030f\u0001\u0000\u0000\u0000\u030f"+
-    "\u0310\u0006L\r\u0000\u0310\u0311\u0006L\r\u0000\u0311\u00a5\u0001\u0000"+
-    "\u0000\u0000\u0312\u0316\u0003F\u001d\u0000\u0313\u0315\u0003V%\u0000"+
-    "\u0314\u0313\u0001\u0000\u0000\u0000\u0315\u0318\u0001\u0000\u0000\u0000"+
-    "\u0316\u0314\u0001\u0000\u0000\u0000\u0316\u0317\u0001\u0000\u0000\u0000"+
-    "\u0317\u0323\u0001\u0000\u0000\u0000\u0318\u0316\u0001\u0000\u0000\u0000"+
-    "\u0319\u031c\u0003T$\u0000\u031a\u031c\u0003N!\u0000\u031b\u0319\u0001"+
-    "\u0000\u0000\u0000\u031b\u031a\u0001\u0000\u0000\u0000\u031c\u031e\u0001"+
-    "\u0000\u0000\u0000\u031d\u031f\u0003V%\u0000\u031e\u031d\u0001\u0000\u0000"+
-    "\u0000\u031f\u0320\u0001\u0000\u0000\u0000\u0320\u031e\u0001\u0000\u0000"+
-    "\u0000\u0320\u0321\u0001\u0000\u0000\u0000\u0321\u0323\u0001\u0000\u0000"+
-    "\u0000\u0322\u0312\u0001\u0000\u0000\u0000\u0322\u031b\u0001\u0000\u0000"+
-    "\u0000\u0323\u00a7\u0001\u0000\u0000\u0000\u0324\u0326\u0003P\"\u0000"+
-    "\u0325\u0327\u0003R#\u0000\u0326\u0325\u0001\u0000\u0000\u0000\u0327\u0328"+
-    "\u0001\u0000\u0000\u0000\u0328\u0326\u0001\u0000\u0000\u0000\u0328\u0329"+
-    "\u0001\u0000\u0000\u0000\u0329\u032a\u0001\u0000\u0000\u0000\u032a\u032b"+
-    "\u0003P\"\u0000\u032b\u00a9\u0001\u0000\u0000\u0000\u032c\u032d\u0003"+
-    "\u00a8N\u0000\u032d\u00ab\u0001\u0000\u0000\u0000\u032e\u032f\u00032\u0013"+
-    "\u0000\u032f\u0330\u0001\u0000\u0000\u0000\u0330\u0331\u0006P\t\u0000"+
-    "\u0331\u00ad\u0001\u0000\u0000\u0000\u0332\u0333\u00034\u0014\u0000\u0333"+
-    "\u0334\u0001\u0000\u0000\u0000\u0334\u0335\u0006Q\t\u0000\u0335\u00af"+
-    "\u0001\u0000\u0000\u0000\u0336\u0337\u00036\u0015\u0000\u0337\u0338\u0001"+
-    "\u0000\u0000\u0000\u0338\u0339\u0006R\t\u0000\u0339\u00b1\u0001\u0000"+
-    "\u0000\u0000\u033a\u033b\u0003B\u001b\u0000\u033b\u033c\u0001\u0000\u0000"+
-    "\u0000\u033c\u033d\u0006S\f\u0000\u033d\u033e\u0006S\r\u0000\u033e\u00b3"+
-    "\u0001\u0000\u0000\u0000\u033f\u0340\u0003\u00a2K\u0000\u0340\u0341\u0001"+
-    "\u0000\u0000\u0000\u0341\u0342\u0006T\n\u0000\u0342\u00b5\u0001\u0000"+
-    "\u0000\u0000\u0343\u0344\u0003\u00a4L\u0000\u0344\u0345\u0001\u0000\u0000"+
-    "\u0000\u0345\u0346\u0006U\u000e\u0000\u0346\u00b7\u0001\u0000\u0000\u0000"+
-    "\u0347\u0348\u0003f-\u0000\u0348\u0349\u0001\u0000\u0000\u0000\u0349\u034a"+
-    "\u0006V\u000f\u0000\u034a\u00b9\u0001\u0000\u0000\u0000\u034b\u034c\u0003"+
-    "d,\u0000\u034c\u034d\u0001\u0000\u0000\u0000\u034d\u034e\u0006W\u0010"+
-    "\u0000\u034e\u00bb\u0001\u0000\u0000\u0000\u034f\u0350\u0005m\u0000\u0000"+
-    "\u0350\u0351\u0005e\u0000\u0000\u0351\u0352\u0005t\u0000\u0000\u0352\u0353"+
-    "\u0005a\u0000\u0000\u0353\u0354\u0005d\u0000\u0000\u0354\u0355\u0005a"+
-    "\u0000\u0000\u0355\u0356\u0005t\u0000\u0000\u0356\u0357\u0005a\u0000\u0000"+
-    "\u0357\u00bd\u0001\u0000\u0000\u0000\u0358\u035c\b\n\u0000\u0000\u0359"+
-    "\u035a\u0005/\u0000\u0000\u035a\u035c\b\u000b\u0000\u0000\u035b\u0358"+
-    "\u0001\u0000\u0000\u0000\u035b\u0359\u0001\u0000\u0000\u0000\u035c\u00bf"+
-    "\u0001\u0000\u0000\u0000\u035d\u035f\u0003\u00beY\u0000\u035e\u035d\u0001"+
-    "\u0000\u0000\u0000\u035f\u0360\u0001\u0000\u0000\u0000\u0360\u035e\u0001"+
-    "\u0000\u0000\u0000\u0360\u0361\u0001\u0000\u0000\u0000\u0361\u00c1\u0001"+
-    "\u0000\u0000\u0000\u0362\u0363\u0003\u00aaO\u0000\u0363\u0364\u0001\u0000"+
-    "\u0000\u0000\u0364\u0365\u0006[\u0011\u0000\u0365\u00c3\u0001\u0000\u0000"+
-    "\u0000\u0366\u0367\u00032\u0013\u0000\u0367\u0368\u0001\u0000\u0000\u0000"+
-    "\u0368\u0369\u0006\\\t\u0000\u0369\u00c5\u0001\u0000\u0000\u0000\u036a"+
-    "\u036b\u00034\u0014\u0000\u036b\u036c\u0001\u0000\u0000\u0000\u036c\u036d"+
-    "\u0006]\t\u0000\u036d\u00c7\u0001\u0000\u0000\u0000\u036e\u036f\u0003"+
-    "6\u0015\u0000\u036f\u0370\u0001\u0000\u0000\u0000\u0370\u0371\u0006^\t"+
-    "\u0000\u0371\u00c9\u0001\u0000\u0000\u0000\u0372\u0373\u0003B\u001b\u0000"+
-    "\u0373\u0374\u0001\u0000\u0000\u0000\u0374\u0375\u0006_\f\u0000\u0375"+
-    "\u0376\u0006_\r\u0000\u0376\u00cb\u0001\u0000\u0000\u0000\u0377\u0378"+
-    "\u0003j/\u0000\u0378\u0379\u0001\u0000\u0000\u0000\u0379\u037a\u0006`"+
-    "\u0012\u0000\u037a\u00cd\u0001\u0000\u0000\u0000\u037b\u037c\u0003f-\u0000"+
-    "\u037c\u037d\u0001\u0000\u0000\u0000\u037d\u037e\u0006a\u000f\u0000\u037e"+
-    "\u00cf\u0001\u0000\u0000\u0000\u037f\u0384\u0003F\u001d\u0000\u0380\u0384"+
-    "\u0003D\u001c\u0000\u0381\u0384\u0003T$\u0000\u0382\u0384\u0003\u009c"+
-    "H\u0000\u0383\u037f\u0001\u0000\u0000\u0000\u0383\u0380\u0001\u0000\u0000"+
-    "\u0000\u0383\u0381\u0001\u0000\u0000\u0000\u0383\u0382\u0001\u0000\u0000"+
-    "\u0000\u0384\u00d1\u0001\u0000\u0000\u0000\u0385\u0388\u0003F\u001d\u0000"+
-    "\u0386\u0388\u0003\u009cH\u0000\u0387\u0385\u0001\u0000\u0000\u0000\u0387"+
-    "\u0386\u0001\u0000\u0000\u0000\u0388\u038c\u0001\u0000\u0000\u0000\u0389"+
-    "\u038b\u0003\u00d0b\u0000\u038a\u0389\u0001\u0000\u0000\u0000\u038b\u038e"+
-    "\u0001\u0000\u0000\u0000\u038c\u038a\u0001\u0000\u0000\u0000\u038c\u038d"+
-    "\u0001\u0000\u0000\u0000\u038d\u0399\u0001\u0000\u0000\u0000\u038e\u038c"+
-    "\u0001\u0000\u0000\u0000\u038f\u0392\u0003T$\u0000\u0390\u0392\u0003N"+
-    "!\u0000\u0391\u038f\u0001\u0000\u0000\u0000\u0391\u0390\u0001\u0000\u0000"+
-    "\u0000\u0392\u0394\u0001\u0000\u0000\u0000\u0393\u0395\u0003\u00d0b\u0000"+
-    "\u0394\u0393\u0001\u0000\u0000\u0000\u0395\u0396\u0001\u0000\u0000\u0000"+
-    "\u0396\u0394\u0001\u0000\u0000\u0000\u0396\u0397\u0001\u0000\u0000\u0000"+
-    "\u0397\u0399\u0001\u0000\u0000\u0000\u0398\u0387\u0001\u0000\u0000\u0000"+
-    "\u0398\u0391\u0001\u0000\u0000\u0000\u0399\u00d3\u0001\u0000\u0000\u0000"+
-    "\u039a\u039d\u0003\u00d2c\u0000\u039b\u039d\u0003\u00a8N\u0000\u039c\u039a"+
-    "\u0001\u0000\u0000\u0000\u039c\u039b\u0001\u0000\u0000\u0000\u039d\u039e"+
-    "\u0001\u0000\u0000\u0000\u039e\u039c\u0001\u0000\u0000\u0000\u039e\u039f"+
-    "\u0001\u0000\u0000\u0000\u039f\u00d5\u0001\u0000\u0000\u0000\u03a0\u03a1"+
-    "\u00032\u0013\u0000\u03a1\u03a2\u0001\u0000\u0000\u0000\u03a2\u03a3\u0006"+
-    "e\t\u0000\u03a3\u00d7\u0001\u0000\u0000\u0000\u03a4\u03a5\u00034\u0014"+
-    "\u0000\u03a5\u03a6\u0001\u0000\u0000\u0000\u03a6\u03a7\u0006f\t\u0000"+
-    "\u03a7\u00d9\u0001\u0000\u0000\u0000\u03a8\u03a9\u00036\u0015\u0000\u03a9"+
-    "\u03aa\u0001\u0000\u0000\u0000\u03aa\u03ab\u0006g\t\u0000\u03ab\u00db"+
-    "\u0001\u0000\u0000\u0000\u03ac\u03ad\u0003B\u001b\u0000\u03ad\u03ae\u0001"+
-    "\u0000\u0000\u0000\u03ae\u03af\u0006h\f\u0000\u03af\u03b0\u0006h\r\u0000"+
-    "\u03b0\u00dd\u0001\u0000\u0000\u0000\u03b1\u03b2\u0003d,\u0000\u03b2\u03b3"+
-    "\u0001\u0000\u0000\u0000\u03b3\u03b4\u0006i\u0010\u0000\u03b4\u00df\u0001"+
-    "\u0000\u0000\u0000\u03b5\u03b6\u0003f-\u0000\u03b6\u03b7\u0001\u0000\u0000"+
-    "\u0000\u03b7\u03b8\u0006j\u000f\u0000\u03b8\u00e1\u0001\u0000\u0000\u0000"+
-    "\u03b9\u03ba\u0003j/\u0000\u03ba\u03bb\u0001\u0000\u0000\u0000\u03bb\u03bc"+
-    "\u0006k\u0012\u0000\u03bc\u00e3\u0001\u0000\u0000\u0000\u03bd\u03be\u0005"+
-    "a\u0000\u0000\u03be\u03bf\u0005s\u0000\u0000\u03bf\u00e5\u0001\u0000\u0000"+
-    "\u0000\u03c0\u03c1\u0003\u00d4d\u0000\u03c1\u03c2\u0001\u0000\u0000\u0000"+
-    "\u03c2\u03c3\u0006m\u0013\u0000\u03c3\u00e7\u0001\u0000\u0000\u0000\u03c4"+
-    "\u03c5\u00032\u0013\u0000\u03c5\u03c6\u0001\u0000\u0000\u0000\u03c6\u03c7"+
-    "\u0006n\t\u0000\u03c7\u00e9\u0001\u0000\u0000\u0000\u03c8\u03c9\u0003"+
-    "4\u0014\u0000\u03c9\u03ca\u0001\u0000\u0000\u0000\u03ca\u03cb\u0006o\t"+
-    "\u0000\u03cb\u00eb\u0001\u0000\u0000\u0000\u03cc\u03cd\u00036\u0015\u0000"+
-    "\u03cd\u03ce\u0001\u0000\u0000\u0000\u03ce\u03cf\u0006p\t\u0000\u03cf"+
-    "\u00ed\u0001\u0000\u0000\u0000\u03d0\u03d1\u0003B\u001b\u0000\u03d1\u03d2"+
-    "\u0001\u0000\u0000\u0000\u03d2\u03d3\u0006q\f\u0000\u03d3\u03d4\u0006"+
-    "q\r\u0000\u03d4\u00ef\u0001\u0000\u0000\u0000\u03d5\u03d6\u0003\u00a2"+
-    "K\u0000\u03d6\u03d7\u0001\u0000\u0000\u0000\u03d7\u03d8\u0006r\n\u0000"+
-    "\u03d8\u03d9\u0006r\u0014\u0000\u03d9\u00f1\u0001\u0000\u0000\u0000\u03da"+
-    "\u03db\u0005o\u0000\u0000\u03db\u03dc\u0005n\u0000\u0000\u03dc\u03dd\u0001"+
-    "\u0000\u0000\u0000\u03dd\u03de\u0006s\u0015\u0000\u03de\u00f3\u0001\u0000"+
-    "\u0000\u0000\u03df\u03e0\u0005w\u0000\u0000\u03e0\u03e1\u0005i\u0000\u0000"+
-    "\u03e1\u03e2\u0005t\u0000\u0000\u03e2\u03e3\u0005h\u0000\u0000\u03e3\u03e4"+
-    "\u0001\u0000\u0000\u0000\u03e4\u03e5\u0006t\u0015\u0000\u03e5\u00f5\u0001"+
-    "\u0000\u0000\u0000\u03e6\u03e7\b\f\u0000\u0000\u03e7\u00f7\u0001\u0000"+
-    "\u0000\u0000\u03e8\u03ea\u0003\u00f6u\u0000\u03e9\u03e8\u0001\u0000\u0000"+
-    "\u0000\u03ea\u03eb\u0001\u0000\u0000\u0000\u03eb\u03e9\u0001\u0000\u0000"+
-    "\u0000\u03eb\u03ec\u0001\u0000\u0000\u0000\u03ec\u03ed\u0001\u0000\u0000"+
-    "\u0000\u03ed\u03ee\u0003\u013c\u0098\u0000\u03ee\u03f0\u0001\u0000\u0000"+
-    "\u0000\u03ef\u03e9\u0001\u0000\u0000\u0000\u03ef\u03f0\u0001\u0000\u0000"+
-    "\u0000\u03f0\u03f2\u0001\u0000\u0000\u0000\u03f1\u03f3\u0003\u00f6u\u0000"+
-    "\u03f2\u03f1\u0001\u0000\u0000\u0000\u03f3\u03f4\u0001\u0000\u0000\u0000"+
-    "\u03f4\u03f2\u0001\u0000\u0000\u0000\u03f4\u03f5\u0001\u0000\u0000\u0000"+
-    "\u03f5\u00f9\u0001\u0000\u0000\u0000\u03f6\u03f7\u0003\u00aaO\u0000\u03f7"+
-    "\u03f8\u0001\u0000\u0000\u0000\u03f8\u03f9\u0006w\u0011\u0000\u03f9\u00fb"+
-    "\u0001\u0000\u0000\u0000\u03fa\u03fb\u0003\u00f8v\u0000\u03fb\u03fc\u0001"+
-    "\u0000\u0000\u0000\u03fc\u03fd\u0006x\u0016\u0000\u03fd\u00fd\u0001\u0000"+
-    "\u0000\u0000\u03fe\u03ff\u00032\u0013\u0000\u03ff\u0400\u0001\u0000\u0000"+
-    "\u0000\u0400\u0401\u0006y\t\u0000\u0401\u00ff\u0001\u0000\u0000\u0000"+
-    "\u0402\u0403\u00034\u0014\u0000\u0403\u0404\u0001\u0000\u0000\u0000\u0404"+
-    "\u0405\u0006z\t\u0000\u0405\u0101\u0001\u0000\u0000\u0000\u0406\u0407"+
-    "\u00036\u0015\u0000\u0407\u0408\u0001\u0000\u0000\u0000\u0408\u0409\u0006"+
-    "{\t\u0000\u0409\u0103\u0001\u0000\u0000\u0000\u040a\u040b\u0003B\u001b"+
-    "\u0000\u040b\u040c\u0001\u0000\u0000\u0000\u040c\u040d\u0006|\f\u0000"+
-    "\u040d\u040e\u0006|\r\u0000\u040e\u040f\u0006|\r\u0000\u040f\u0105\u0001"+
-    "\u0000\u0000\u0000\u0410\u0411\u0003d,\u0000\u0411\u0412\u0001\u0000\u0000"+
-    "\u0000\u0412\u0413\u0006}\u0010\u0000\u0413\u0107\u0001\u0000\u0000\u0000"+
-    "\u0414\u0415\u0003f-\u0000\u0415\u0416\u0001\u0000\u0000\u0000\u0416\u0417"+
-    "\u0006~\u000f\u0000\u0417\u0109\u0001\u0000\u0000\u0000\u0418\u0419\u0003"+
-    "j/\u0000\u0419\u041a\u0001\u0000\u0000\u0000\u041a\u041b\u0006\u007f\u0012"+
-    "\u0000\u041b\u010b\u0001\u0000\u0000\u0000\u041c\u041d\u0003\u00f4t\u0000"+
-    "\u041d\u041e\u0001\u0000\u0000\u0000\u041e\u041f\u0006\u0080\u0017\u0000"+
-    "\u041f\u010d\u0001\u0000\u0000\u0000\u0420\u0421\u0003\u00d4d\u0000\u0421"+
-    "\u0422\u0001\u0000\u0000\u0000\u0422\u0423\u0006\u0081\u0013\u0000\u0423"+
-    "\u010f\u0001\u0000\u0000\u0000\u0424\u0425\u0003\u00aaO\u0000\u0425\u0426"+
-    "\u0001\u0000\u0000\u0000\u0426\u0427\u0006\u0082\u0011\u0000\u0427\u0111"+
-    "\u0001\u0000\u0000\u0000\u0428\u0429\u00032\u0013\u0000\u0429\u042a\u0001"+
-    "\u0000\u0000\u0000\u042a\u042b\u0006\u0083\t\u0000\u042b\u0113\u0001\u0000"+
-    "\u0000\u0000\u042c\u042d\u00034\u0014\u0000\u042d\u042e\u0001\u0000\u0000"+
-    "\u0000\u042e\u042f\u0006\u0084\t\u0000\u042f\u0115\u0001\u0000\u0000\u0000"+
-    "\u0430\u0431\u00036\u0015\u0000\u0431\u0432\u0001\u0000\u0000\u0000\u0432"+
-    "\u0433\u0006\u0085\t\u0000\u0433\u0117\u0001\u0000\u0000\u0000\u0434\u0435"+
-    "\u0003B\u001b\u0000\u0435\u0436\u0001\u0000\u0000\u0000\u0436\u0437\u0006"+
-    "\u0086\f\u0000\u0437\u0438\u0006\u0086\r\u0000\u0438\u0119\u0001\u0000"+
-    "\u0000\u0000\u0439\u043a\u0003j/\u0000\u043a\u043b\u0001\u0000\u0000\u0000"+
-    "\u043b\u043c\u0006\u0087\u0012\u0000\u043c\u011b\u0001\u0000\u0000\u0000"+
-    "\u043d\u043e\u0003\u00aaO\u0000\u043e\u043f\u0001\u0000\u0000\u0000\u043f"+
-    "\u0440\u0006\u0088\u0011\u0000\u0440\u011d\u0001\u0000\u0000\u0000\u0441"+
-    "\u0442\u0003\u00a6M\u0000\u0442\u0443\u0001\u0000\u0000\u0000\u0443\u0444"+
-    "\u0006\u0089\u0018\u0000\u0444\u011f\u0001\u0000\u0000\u0000\u0445\u0446"+
-    "\u00032\u0013\u0000\u0446\u0447\u0001\u0000\u0000\u0000\u0447\u0448\u0006"+
-    "\u008a\t\u0000\u0448\u0121\u0001\u0000\u0000\u0000\u0449\u044a\u00034"+
-    "\u0014\u0000\u044a\u044b\u0001\u0000\u0000\u0000\u044b\u044c\u0006\u008b"+
-    "\t\u0000\u044c\u0123\u0001\u0000\u0000\u0000\u044d\u044e\u00036\u0015"+
-    "\u0000\u044e\u044f\u0001\u0000\u0000\u0000\u044f\u0450\u0006\u008c\t\u0000"+
-    "\u0450\u0125\u0001\u0000\u0000\u0000\u0451\u0452\u0003B\u001b\u0000\u0452"+
-    "\u0453\u0001\u0000\u0000\u0000\u0453\u0454\u0006\u008d\f\u0000\u0454\u0455"+
-    "\u0006\u008d\r\u0000\u0455\u0127\u0001\u0000\u0000\u0000\u0456\u0457\u0005"+
-    "i\u0000\u0000\u0457\u0458\u0005n\u0000\u0000\u0458\u0459\u0005f\u0000"+
-    "\u0000\u0459\u045a\u0005o\u0000\u0000\u045a\u0129\u0001\u0000\u0000\u0000"+
-    "\u045b\u045c\u00032\u0013\u0000\u045c\u045d\u0001\u0000\u0000\u0000\u045d"+
-    "\u045e\u0006\u008f\t\u0000\u045e\u012b\u0001\u0000\u0000\u0000\u045f\u0460"+
-    "\u00034\u0014\u0000\u0460\u0461\u0001\u0000\u0000\u0000\u0461\u0462\u0006"+
-    "\u0090\t\u0000\u0462\u012d\u0001\u0000\u0000\u0000\u0463\u0464\u00036"+
-    "\u0015\u0000\u0464\u0465\u0001\u0000\u0000\u0000\u0465\u0466\u0006\u0091"+
-    "\t\u0000\u0466\u012f\u0001\u0000\u0000\u0000\u0467\u0468\u0003B\u001b"+
-    "\u0000\u0468\u0469\u0001\u0000\u0000\u0000\u0469\u046a\u0006\u0092\f\u0000"+
-    "\u046a\u046b\u0006\u0092\r\u0000\u046b\u0131\u0001\u0000\u0000\u0000\u046c"+
-    "\u046d\u0005f\u0000\u0000\u046d\u046e\u0005u\u0000\u0000\u046e\u046f\u0005"+
-    "n\u0000\u0000\u046f\u0470\u0005c\u0000\u0000\u0470\u0471\u0005t\u0000"+
-    "\u0000\u0471\u0472\u0005i\u0000\u0000\u0472\u0473\u0005o\u0000\u0000\u0473"+
-    "\u0474\u0005n\u0000\u0000\u0474\u0475\u0005s\u0000\u0000\u0475\u0133\u0001"+
-    "\u0000\u0000\u0000\u0476\u0477\u00032\u0013\u0000\u0477\u0478\u0001\u0000"+
-    "\u0000\u0000\u0478\u0479\u0006\u0094\t\u0000\u0479\u0135\u0001\u0000\u0000"+
-    "\u0000\u047a\u047b\u00034\u0014\u0000\u047b\u047c\u0001\u0000\u0000\u0000"+
-    "\u047c\u047d\u0006\u0095\t\u0000\u047d\u0137\u0001\u0000\u0000\u0000\u047e"+
-    "\u047f\u00036\u0015\u0000\u047f\u0480\u0001\u0000\u0000\u0000\u0480\u0481"+
-    "\u0006\u0096\t\u0000\u0481\u0139\u0001\u0000\u0000\u0000\u0482\u0483\u0003"+
-    "\u00a4L\u0000\u0483\u0484\u0001\u0000\u0000\u0000\u0484\u0485\u0006\u0097"+
-    "\u000e\u0000\u0485\u0486\u0006\u0097\r\u0000\u0486\u013b\u0001\u0000\u0000"+
-    "\u0000\u0487\u0488\u0005:\u0000\u0000\u0488\u013d\u0001\u0000\u0000\u0000"+
-    "\u0489\u048f\u0003N!\u0000\u048a\u048f\u0003D\u001c\u0000\u048b\u048f"+
-    "\u0003j/\u0000\u048c\u048f\u0003F\u001d\u0000\u048d\u048f\u0003T$\u0000"+
-    "\u048e\u0489\u0001\u0000\u0000\u0000\u048e\u048a\u0001\u0000\u0000\u0000"+
-    "\u048e\u048b\u0001\u0000\u0000\u0000\u048e\u048c\u0001\u0000\u0000\u0000"+
-    "\u048e\u048d\u0001\u0000\u0000\u0000\u048f\u0490\u0001\u0000\u0000\u0000"+
-    "\u0490\u048e\u0001\u0000\u0000\u0000\u0490\u0491\u0001\u0000\u0000\u0000"+
-    "\u0491\u013f\u0001\u0000\u0000\u0000\u0492\u0493\u00032\u0013\u0000\u0493"+
-    "\u0494\u0001\u0000\u0000\u0000\u0494\u0495\u0006\u009a\t\u0000\u0495\u0141"+
-    "\u0001\u0000\u0000\u0000\u0496\u0497\u00034\u0014\u0000\u0497\u0498\u0001"+
-    "\u0000\u0000\u0000\u0498\u0499\u0006\u009b\t\u0000\u0499\u0143\u0001\u0000"+
-    "\u0000\u0000\u049a\u049b\u00036\u0015\u0000\u049b\u049c\u0001\u0000\u0000"+
-    "\u0000\u049c\u049d\u0006\u009c\t\u0000\u049d\u0145\u0001\u0000\u0000\u0000"+
-    ":\u0000\u0001\u0002\u0003\u0004\u0005\u0006\u0007\b\t\n\u000b\u01df\u01e9"+
-    "\u01ed\u01f0\u01f9\u01fb\u0206\u022f\u0234\u023d\u0244\u0249\u024b\u0256"+
-    "\u025e\u0261\u0263\u0268\u026d\u0273\u027a\u027f\u0285\u0288\u0290\u0294"+
-    "\u0316\u031b\u0320\u0322\u0328\u035b\u0360\u0383\u0387\u038c\u0391\u0396"+
-    "\u0398\u039c\u039e\u03eb\u03ef\u03f4\u048e\u0490\u0019\u0005\u0002\u0000"+
-    "\u0005\u0004\u0000\u0005\u0006\u0000\u0005\u0001\u0000\u0005\u0003\u0000"+
-    "\u0005\n\u0000\u0005\b\u0000\u0005\u0005\u0000\u0005\t\u0000\u0000\u0001"+
-    "\u0000\u0007@\u0000\u0005\u0000\u0000\u0007\u001a\u0000\u0004\u0000\u0000"+
-    "\u0007A\u0000\u0007\"\u0000\u0007!\u0000\u0007C\u0000\u0007$\u0000\u0007"+
-    "L\u0000\u0005\u000b\u0000\u0005\u0007\u0000\u0007V\u0000\u0007U\u0000"+
-    "\u0007B\u0000";
+    "\u0001\u0093\u0001\u0094\u0001\u0094\u0001\u0094\u0001\u0094\u0001\u0094"+
+    "\u0001\u0095\u0001\u0095\u0001\u0095\u0001\u0095\u0001\u0095\u0001\u0095"+
+    "\u0001\u0095\u0001\u0095\u0001\u0095\u0001\u0095\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\u0099\u0001\u009a\u0001\u009a\u0001\u009b"+
+    "\u0001\u009b\u0001\u009b\u0001\u009b\u0001\u009b\u0004\u009b\u049f\b\u009b"+
+    "\u000b\u009b\f\u009b\u04a0\u0001\u009c\u0001\u009c\u0001\u009c\u0001\u009c"+
+    "\u0001\u009d\u0001\u009d\u0001\u009d\u0001\u009d\u0001\u009e\u0001\u009e"+
+    "\u0001\u009e\u0001\u009e\u0002\u01ff\u025a\u0000\u009f\f\u0001\u000e\u0002"+
+    "\u0010\u0003\u0012\u0004\u0014\u0005\u0016\u0006\u0018\u0007\u001a\b\u001c"+
+    "\t\u001e\n \u000b\"\f$\r&\u000e(\u000f*\u0010,\u0011.\u00120\u00132\u0014"+
+    "4\u00156\u00168\u0000:\u0000<\u0017>\u0018@\u0019B\u001aD\u0000F\u0000"+
+    "H\u0000J\u0000L\u0000N\u0000P\u0000R\u0000T\u0000V\u0000X\u001bZ\u001c"+
+    "\\\u001d^\u001e`\u001fb d!f\"h#j$l%n&p\'r(t)v*x+z,|-~.\u0080/\u00820\u0084"+
+    "1\u00862\u00883\u008a4\u008c5\u008e6\u00907\u00928\u00949\u0096:\u0098"+
+    ";\u009a<\u009c=\u009e>\u00a0?\u00a2@\u00a4A\u00a6B\u00a8\u0000\u00aaC"+
+    "\u00acD\u00aeE\u00b0F\u00b2\u0000\u00b4\u0000\u00b6\u0000\u00b8\u0000"+
+    "\u00ba\u0000\u00bc\u0000\u00beG\u00c0H\u00c2\u0000\u00c4I\u00c6\u0000"+
+    "\u00c8J\u00caK\u00ccL\u00ce\u0000\u00d0\u0000\u00d2\u0000\u00d4\u0000"+
+    "\u00d6\u0000\u00d8M\u00daN\u00dcO\u00deP\u00e0\u0000\u00e2\u0000\u00e4"+
+    "\u0000\u00e6\u0000\u00e8Q\u00ea\u0000\u00ecR\u00eeS\u00f0T\u00f2\u0000"+
+    "\u00f4\u0000\u00f6U\u00f8V\u00fa\u0000\u00fcW\u00fe\u0000\u0100\u0000"+
+    "\u0102X\u0104Y\u0106Z\u0108\u0000\u010a\u0000\u010c\u0000\u010e\u0000"+
+    "\u0110\u0000\u0112\u0000\u0114\u0000\u0116[\u0118\\\u011a]\u011c\u0000"+
+    "\u011e\u0000\u0120\u0000\u0122\u0000\u0124^\u0126_\u0128`\u012a\u0000"+
+    "\u012ca\u012eb\u0130c\u0132d\u0134\u0000\u0136e\u0138f\u013ag\u013ch\u013e"+
+    "\u0000\u0140i\u0142j\u0144k\u0146l\u0148m\f\u0000\u0001\u0002\u0003\u0004"+
+    "\u0005\u0006\u0007\b\t\n\u000b\r\u0006\u0000\t\n\r\r  //[[]]\u0002\u0000"+
+    "\n\n\r\r\u0003\u0000\t\n\r\r  \u0001\u000009\u0002\u0000AZaz\u0005\u0000"+
+    "\"\"\\\\nnrrtt\u0004\u0000\n\n\r\r\"\"\\\\\u0002\u0000EEee\u0002\u0000"+
+    "++--\u0001\u0000``\n\u0000\t\n\r\r  ,,//==[[]]``||\u0002\u0000**//\u000b"+
+    "\u0000\t\n\r\r  \"#,,//::<<>?\\\\||\u04c9\u0000\f\u0001\u0000\u0000\u0000"+
+    "\u0000\u000e\u0001\u0000\u0000\u0000\u0000\u0010\u0001\u0000\u0000\u0000"+
+    "\u0000\u0012\u0001\u0000\u0000\u0000\u0000\u0014\u0001\u0000\u0000\u0000"+
+    "\u0000\u0016\u0001\u0000\u0000\u0000\u0000\u0018\u0001\u0000\u0000\u0000"+
+    "\u0000\u001a\u0001\u0000\u0000\u0000\u0000\u001c\u0001\u0000\u0000\u0000"+
+    "\u0000\u001e\u0001\u0000\u0000\u0000\u0000 \u0001\u0000\u0000\u0000\u0000"+
+    "\"\u0001\u0000\u0000\u0000\u0000$\u0001\u0000\u0000\u0000\u0000&\u0001"+
+    "\u0000\u0000\u0000\u0000(\u0001\u0000\u0000\u0000\u0000*\u0001\u0000\u0000"+
+    "\u0000\u0000,\u0001\u0000\u0000\u0000\u0000.\u0001\u0000\u0000\u0000\u0000"+
+    "0\u0001\u0000\u0000\u0000\u00002\u0001\u0000\u0000\u0000\u00004\u0001"+
+    "\u0000\u0000\u0000\u00006\u0001\u0000\u0000\u0000\u00018\u0001\u0000\u0000"+
+    "\u0000\u0001:\u0001\u0000\u0000\u0000\u0001<\u0001\u0000\u0000\u0000\u0001"+
+    ">\u0001\u0000\u0000\u0000\u0001@\u0001\u0000\u0000\u0000\u0002B\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`\u0001\u0000\u0000\u0000\u0002b\u0001\u0000\u0000\u0000\u0002d"+
+    "\u0001\u0000\u0000\u0000\u0002f\u0001\u0000\u0000\u0000\u0002h\u0001\u0000"+
+    "\u0000\u0000\u0002j\u0001\u0000\u0000\u0000\u0002l\u0001\u0000\u0000\u0000"+
+    "\u0002n\u0001\u0000\u0000\u0000\u0002p\u0001\u0000\u0000\u0000\u0002r"+
+    "\u0001\u0000\u0000\u0000\u0002t\u0001\u0000\u0000\u0000\u0002v\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\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\u0002\u008a\u0001\u0000\u0000\u0000\u0002\u008c"+
+    "\u0001\u0000\u0000\u0000\u0002\u008e\u0001\u0000\u0000\u0000\u0002\u0090"+
+    "\u0001\u0000\u0000\u0000\u0002\u0092\u0001\u0000\u0000\u0000\u0002\u0094"+
+    "\u0001\u0000\u0000\u0000\u0002\u0096\u0001\u0000\u0000\u0000\u0002\u0098"+
+    "\u0001\u0000\u0000\u0000\u0002\u009a\u0001\u0000\u0000\u0000\u0002\u009c"+
+    "\u0001\u0000\u0000\u0000\u0002\u009e\u0001\u0000\u0000\u0000\u0002\u00a0"+
+    "\u0001\u0000\u0000\u0000\u0002\u00a2\u0001\u0000\u0000\u0000\u0002\u00a4"+
+    "\u0001\u0000\u0000\u0000\u0002\u00a6\u0001\u0000\u0000\u0000\u0002\u00aa"+
+    "\u0001\u0000\u0000\u0000\u0002\u00ac\u0001\u0000\u0000\u0000\u0002\u00ae"+
+    "\u0001\u0000\u0000\u0000\u0002\u00b0\u0001\u0000\u0000\u0000\u0003\u00b2"+
+    "\u0001\u0000\u0000\u0000\u0003\u00b4\u0001\u0000\u0000\u0000\u0003\u00b6"+
+    "\u0001\u0000\u0000\u0000\u0003\u00b8\u0001\u0000\u0000\u0000\u0003\u00ba"+
+    "\u0001\u0000\u0000\u0000\u0003\u00bc\u0001\u0000\u0000\u0000\u0003\u00be"+
+    "\u0001\u0000\u0000\u0000\u0003\u00c0\u0001\u0000\u0000\u0000\u0003\u00c4"+
+    "\u0001\u0000\u0000\u0000\u0003\u00c6\u0001\u0000\u0000\u0000\u0003\u00c8"+
+    "\u0001\u0000\u0000\u0000\u0003\u00ca\u0001\u0000\u0000\u0000\u0003\u00cc"+
+    "\u0001\u0000\u0000\u0000\u0004\u00ce\u0001\u0000\u0000\u0000\u0004\u00d0"+
+    "\u0001\u0000\u0000\u0000\u0004\u00d2\u0001\u0000\u0000\u0000\u0004\u00d8"+
+    "\u0001\u0000\u0000\u0000\u0004\u00da\u0001\u0000\u0000\u0000\u0004\u00dc"+
+    "\u0001\u0000\u0000\u0000\u0004\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\u0006\u00f2\u0001\u0000\u0000\u0000\u0006\u00f4"+
+    "\u0001\u0000\u0000\u0000\u0006\u00f6\u0001\u0000\u0000\u0000\u0006\u00f8"+
+    "\u0001\u0000\u0000\u0000\u0006\u00fc\u0001\u0000\u0000\u0000\u0006\u00fe"+
+    "\u0001\u0000\u0000\u0000\u0006\u0100\u0001\u0000\u0000\u0000\u0006\u0102"+
+    "\u0001\u0000\u0000\u0000\u0006\u0104\u0001\u0000\u0000\u0000\u0006\u0106"+
+    "\u0001\u0000\u0000\u0000\u0007\u0108\u0001\u0000\u0000\u0000\u0007\u010a"+
+    "\u0001\u0000\u0000\u0000\u0007\u010c\u0001\u0000\u0000\u0000\u0007\u010e"+
+    "\u0001\u0000\u0000\u0000\u0007\u0110\u0001\u0000\u0000\u0000\u0007\u0112"+
+    "\u0001\u0000\u0000\u0000\u0007\u0114\u0001\u0000\u0000\u0000\u0007\u0116"+
+    "\u0001\u0000\u0000\u0000\u0007\u0118\u0001\u0000\u0000\u0000\u0007\u011a"+
+    "\u0001\u0000\u0000\u0000\b\u011c\u0001\u0000\u0000\u0000\b\u011e\u0001"+
+    "\u0000\u0000\u0000\b\u0120\u0001\u0000\u0000\u0000\b\u0122\u0001\u0000"+
+    "\u0000\u0000\b\u0124\u0001\u0000\u0000\u0000\b\u0126\u0001\u0000\u0000"+
+    "\u0000\b\u0128\u0001\u0000\u0000\u0000\t\u012a\u0001\u0000\u0000\u0000"+
+    "\t\u012c\u0001\u0000\u0000\u0000\t\u012e\u0001\u0000\u0000\u0000\t\u0130"+
+    "\u0001\u0000\u0000\u0000\t\u0132\u0001\u0000\u0000\u0000\n\u0134\u0001"+
+    "\u0000\u0000\u0000\n\u0136\u0001\u0000\u0000\u0000\n\u0138\u0001\u0000"+
+    "\u0000\u0000\n\u013a\u0001\u0000\u0000\u0000\n\u013c\u0001\u0000\u0000"+
+    "\u0000\u000b\u013e\u0001\u0000\u0000\u0000\u000b\u0140\u0001\u0000\u0000"+
+    "\u0000\u000b\u0142\u0001\u0000\u0000\u0000\u000b\u0144\u0001\u0000\u0000"+
+    "\u0000\u000b\u0146\u0001\u0000\u0000\u0000\u000b\u0148\u0001\u0000\u0000"+
+    "\u0000\f\u014a\u0001\u0000\u0000\u0000\u000e\u0154\u0001\u0000\u0000\u0000"+
+    "\u0010\u015b\u0001\u0000\u0000\u0000\u0012\u0164\u0001\u0000\u0000\u0000"+
+    "\u0014\u016b\u0001\u0000\u0000\u0000\u0016\u0175\u0001\u0000\u0000\u0000"+
+    "\u0018\u017c\u0001\u0000\u0000\u0000\u001a\u0183\u0001\u0000\u0000\u0000"+
+    "\u001c\u0191\u0001\u0000\u0000\u0000\u001e\u0198\u0001\u0000\u0000\u0000"+
+    " \u01a0\u0001\u0000\u0000\u0000\"\u01a7\u0001\u0000\u0000\u0000$\u01b3"+
+    "\u0001\u0000\u0000\u0000&\u01bc\u0001\u0000\u0000\u0000(\u01c2\u0001\u0000"+
+    "\u0000\u0000*\u01c9\u0001\u0000\u0000\u0000,\u01d0\u0001\u0000\u0000\u0000"+
+    ".\u01d8\u0001\u0000\u0000\u00000\u01e1\u0001\u0000\u0000\u00002\u01e7"+
+    "\u0001\u0000\u0000\u00004\u01f8\u0001\u0000\u0000\u00006\u0208\u0001\u0000"+
+    "\u0000\u00008\u020e\u0001\u0000\u0000\u0000:\u0213\u0001\u0000\u0000\u0000"+
+    "<\u0218\u0001\u0000\u0000\u0000>\u021c\u0001\u0000\u0000\u0000@\u0220"+
+    "\u0001\u0000\u0000\u0000B\u0224\u0001\u0000\u0000\u0000D\u0228\u0001\u0000"+
+    "\u0000\u0000F\u022a\u0001\u0000\u0000\u0000H\u022c\u0001\u0000\u0000\u0000"+
+    "J\u022f\u0001\u0000\u0000\u0000L\u0231\u0001\u0000\u0000\u0000N\u023a"+
+    "\u0001\u0000\u0000\u0000P\u023c\u0001\u0000\u0000\u0000R\u0241\u0001\u0000"+
+    "\u0000\u0000T\u0243\u0001\u0000\u0000\u0000V\u0248\u0001\u0000\u0000\u0000"+
+    "X\u0267\u0001\u0000\u0000\u0000Z\u026a\u0001\u0000\u0000\u0000\\\u0298"+
+    "\u0001\u0000\u0000\u0000^\u029a\u0001\u0000\u0000\u0000`\u029d\u0001\u0000"+
+    "\u0000\u0000b\u02a1\u0001\u0000\u0000\u0000d\u02a5\u0001\u0000\u0000\u0000"+
+    "f\u02a7\u0001\u0000\u0000\u0000h\u02a9\u0001\u0000\u0000\u0000j\u02ae"+
+    "\u0001\u0000\u0000\u0000l\u02b0\u0001\u0000\u0000\u0000n\u02b6\u0001\u0000"+
+    "\u0000\u0000p\u02bc\u0001\u0000\u0000\u0000r\u02c1\u0001\u0000\u0000\u0000"+
+    "t\u02c3\u0001\u0000\u0000\u0000v\u02c6\u0001\u0000\u0000\u0000x\u02c9"+
+    "\u0001\u0000\u0000\u0000z\u02ce\u0001\u0000\u0000\u0000|\u02d2\u0001\u0000"+
+    "\u0000\u0000~\u02d7\u0001\u0000\u0000\u0000\u0080\u02dd\u0001\u0000\u0000"+
+    "\u0000\u0082\u02e0\u0001\u0000\u0000\u0000\u0084\u02e2\u0001\u0000\u0000"+
+    "\u0000\u0086\u02e8\u0001\u0000\u0000\u0000\u0088\u02ea\u0001\u0000\u0000"+
+    "\u0000\u008a\u02ef\u0001\u0000\u0000\u0000\u008c\u02f2\u0001\u0000\u0000"+
+    "\u0000\u008e\u02f5\u0001\u0000\u0000\u0000\u0090\u02f8\u0001\u0000\u0000"+
+    "\u0000\u0092\u02fa\u0001\u0000\u0000\u0000\u0094\u02fd\u0001\u0000\u0000"+
+    "\u0000\u0096\u02ff\u0001\u0000\u0000\u0000\u0098\u0302\u0001\u0000\u0000"+
+    "\u0000\u009a\u0304\u0001\u0000\u0000\u0000\u009c\u0306\u0001\u0000\u0000"+
+    "\u0000\u009e\u0308\u0001\u0000\u0000\u0000\u00a0\u030a\u0001\u0000\u0000"+
+    "\u0000\u00a2\u030c\u0001\u0000\u0000\u0000\u00a4\u0311\u0001\u0000\u0000"+
+    "\u0000\u00a6\u0326\u0001\u0000\u0000\u0000\u00a8\u0328\u0001\u0000\u0000"+
+    "\u0000\u00aa\u0330\u0001\u0000\u0000\u0000\u00ac\u0332\u0001\u0000\u0000"+
+    "\u0000\u00ae\u0336\u0001\u0000\u0000\u0000\u00b0\u033a\u0001\u0000\u0000"+
+    "\u0000\u00b2\u033e\u0001\u0000\u0000\u0000\u00b4\u0343\u0001\u0000\u0000"+
+    "\u0000\u00b6\u0347\u0001\u0000\u0000\u0000\u00b8\u034b\u0001\u0000\u0000"+
+    "\u0000\u00ba\u034f\u0001\u0000\u0000\u0000\u00bc\u0353\u0001\u0000\u0000"+
+    "\u0000\u00be\u0357\u0001\u0000\u0000\u0000\u00c0\u035f\u0001\u0000\u0000"+
+    "\u0000\u00c2\u036b\u0001\u0000\u0000\u0000\u00c4\u036e\u0001\u0000\u0000"+
+    "\u0000\u00c6\u0372\u0001\u0000\u0000\u0000\u00c8\u0376\u0001\u0000\u0000"+
+    "\u0000\u00ca\u037a\u0001\u0000\u0000\u0000\u00cc\u037e\u0001\u0000\u0000"+
+    "\u0000\u00ce\u0382\u0001\u0000\u0000\u0000\u00d0\u0387\u0001\u0000\u0000"+
+    "\u0000\u00d2\u038b\u0001\u0000\u0000\u0000\u00d4\u0393\u0001\u0000\u0000"+
+    "\u0000\u00d6\u03a8\u0001\u0000\u0000\u0000\u00d8\u03ac\u0001\u0000\u0000"+
+    "\u0000\u00da\u03b0\u0001\u0000\u0000\u0000\u00dc\u03b4\u0001\u0000\u0000"+
+    "\u0000\u00de\u03b8\u0001\u0000\u0000\u0000\u00e0\u03bc\u0001\u0000\u0000"+
+    "\u0000\u00e2\u03c1\u0001\u0000\u0000\u0000\u00e4\u03c5\u0001\u0000\u0000"+
+    "\u0000\u00e6\u03c9\u0001\u0000\u0000\u0000\u00e8\u03cd\u0001\u0000\u0000"+
+    "\u0000\u00ea\u03d0\u0001\u0000\u0000\u0000\u00ec\u03d4\u0001\u0000\u0000"+
+    "\u0000\u00ee\u03d8\u0001\u0000\u0000\u0000\u00f0\u03dc\u0001\u0000\u0000"+
+    "\u0000\u00f2\u03e0\u0001\u0000\u0000\u0000\u00f4\u03e5\u0001\u0000\u0000"+
+    "\u0000\u00f6\u03ea\u0001\u0000\u0000\u0000\u00f8\u03ef\u0001\u0000\u0000"+
+    "\u0000\u00fa\u03f6\u0001\u0000\u0000\u0000\u00fc\u03ff\u0001\u0000\u0000"+
+    "\u0000\u00fe\u0406\u0001\u0000\u0000\u0000\u0100\u040a\u0001\u0000\u0000"+
+    "\u0000\u0102\u040e\u0001\u0000\u0000\u0000\u0104\u0412\u0001\u0000\u0000"+
+    "\u0000\u0106\u0416\u0001\u0000\u0000\u0000\u0108\u041a\u0001\u0000\u0000"+
+    "\u0000\u010a\u0420\u0001\u0000\u0000\u0000\u010c\u0424\u0001\u0000\u0000"+
+    "\u0000\u010e\u0428\u0001\u0000\u0000\u0000\u0110\u042c\u0001\u0000\u0000"+
+    "\u0000\u0112\u0430\u0001\u0000\u0000\u0000\u0114\u0434\u0001\u0000\u0000"+
+    "\u0000\u0116\u0438\u0001\u0000\u0000\u0000\u0118\u043c\u0001\u0000\u0000"+
+    "\u0000\u011a\u0440\u0001\u0000\u0000\u0000\u011c\u0444\u0001\u0000\u0000"+
+    "\u0000\u011e\u0449\u0001\u0000\u0000\u0000\u0120\u044d\u0001\u0000\u0000"+
+    "\u0000\u0122\u0451\u0001\u0000\u0000\u0000\u0124\u0455\u0001\u0000\u0000"+
+    "\u0000\u0126\u0459\u0001\u0000\u0000\u0000\u0128\u045d\u0001\u0000\u0000"+
+    "\u0000\u012a\u0461\u0001\u0000\u0000\u0000\u012c\u0466\u0001\u0000\u0000"+
+    "\u0000\u012e\u046b\u0001\u0000\u0000\u0000\u0130\u046f\u0001\u0000\u0000"+
+    "\u0000\u0132\u0473\u0001\u0000\u0000\u0000\u0134\u0477\u0001\u0000\u0000"+
+    "\u0000\u0136\u047c\u0001\u0000\u0000\u0000\u0138\u0486\u0001\u0000\u0000"+
+    "\u0000\u013a\u048a\u0001\u0000\u0000\u0000\u013c\u048e\u0001\u0000\u0000"+
+    "\u0000\u013e\u0492\u0001\u0000\u0000\u0000\u0140\u0497\u0001\u0000\u0000"+
+    "\u0000\u0142\u049e\u0001\u0000\u0000\u0000\u0144\u04a2\u0001\u0000\u0000"+
+    "\u0000\u0146\u04a6\u0001\u0000\u0000\u0000\u0148\u04aa\u0001\u0000\u0000"+
+    "\u0000\u014a\u014b\u0005d\u0000\u0000\u014b\u014c\u0005i\u0000\u0000\u014c"+
+    "\u014d\u0005s\u0000\u0000\u014d\u014e\u0005s\u0000\u0000\u014e\u014f\u0005"+
+    "e\u0000\u0000\u014f\u0150\u0005c\u0000\u0000\u0150\u0151\u0005t\u0000"+
+    "\u0000\u0151\u0152\u0001\u0000\u0000\u0000\u0152\u0153\u0006\u0000\u0000"+
+    "\u0000\u0153\r\u0001\u0000\u0000\u0000\u0154\u0155\u0005d\u0000\u0000"+
+    "\u0155\u0156\u0005r\u0000\u0000\u0156\u0157\u0005o\u0000\u0000\u0157\u0158"+
+    "\u0005p\u0000\u0000\u0158\u0159\u0001\u0000\u0000\u0000\u0159\u015a\u0006"+
+    "\u0001\u0001\u0000\u015a\u000f\u0001\u0000\u0000\u0000\u015b\u015c\u0005"+
+    "e\u0000\u0000\u015c\u015d\u0005n\u0000\u0000\u015d\u015e\u0005r\u0000"+
+    "\u0000\u015e\u015f\u0005i\u0000\u0000\u015f\u0160\u0005c\u0000\u0000\u0160"+
+    "\u0161\u0005h\u0000\u0000\u0161\u0162\u0001\u0000\u0000\u0000\u0162\u0163"+
+    "\u0006\u0002\u0002\u0000\u0163\u0011\u0001\u0000\u0000\u0000\u0164\u0165"+
+    "\u0005e\u0000\u0000\u0165\u0166\u0005v\u0000\u0000\u0166\u0167\u0005a"+
+    "\u0000\u0000\u0167\u0168\u0005l\u0000\u0000\u0168\u0169\u0001\u0000\u0000"+
+    "\u0000\u0169\u016a\u0006\u0003\u0000\u0000\u016a\u0013\u0001\u0000\u0000"+
+    "\u0000\u016b\u016c\u0005e\u0000\u0000\u016c\u016d\u0005x\u0000\u0000\u016d"+
+    "\u016e\u0005p\u0000\u0000\u016e\u016f\u0005l\u0000\u0000\u016f\u0170\u0005"+
+    "a\u0000\u0000\u0170\u0171\u0005i\u0000\u0000\u0171\u0172\u0005n\u0000"+
+    "\u0000\u0172\u0173\u0001\u0000\u0000\u0000\u0173\u0174\u0006\u0004\u0003"+
+    "\u0000\u0174\u0015\u0001\u0000\u0000\u0000\u0175\u0176\u0005f\u0000\u0000"+
+    "\u0176\u0177\u0005r\u0000\u0000\u0177\u0178\u0005o\u0000\u0000\u0178\u0179"+
+    "\u0005m\u0000\u0000\u0179\u017a\u0001\u0000\u0000\u0000\u017a\u017b\u0006"+
+    "\u0005\u0004\u0000\u017b\u0017\u0001\u0000\u0000\u0000\u017c\u017d\u0005"+
+    "g\u0000\u0000\u017d\u017e\u0005r\u0000\u0000\u017e\u017f\u0005o\u0000"+
+    "\u0000\u017f\u0180\u0005k\u0000\u0000\u0180\u0181\u0001\u0000\u0000\u0000"+
+    "\u0181\u0182\u0006\u0006\u0000\u0000\u0182\u0019\u0001\u0000\u0000\u0000"+
+    "\u0183\u0184\u0005i\u0000\u0000\u0184\u0185\u0005n\u0000\u0000\u0185\u0186"+
+    "\u0005l\u0000\u0000\u0186\u0187\u0005i\u0000\u0000\u0187\u0188\u0005n"+
+    "\u0000\u0000\u0188\u0189\u0005e\u0000\u0000\u0189\u018a\u0005s\u0000\u0000"+
+    "\u018a\u018b\u0005t\u0000\u0000\u018b\u018c\u0005a\u0000\u0000\u018c\u018d"+
+    "\u0005t\u0000\u0000\u018d\u018e\u0005s\u0000\u0000\u018e\u018f\u0001\u0000"+
+    "\u0000\u0000\u018f\u0190\u0006\u0007\u0000\u0000\u0190\u001b\u0001\u0000"+
+    "\u0000\u0000\u0191\u0192\u0005k\u0000\u0000\u0192\u0193\u0005e\u0000\u0000"+
+    "\u0193\u0194\u0005e\u0000\u0000\u0194\u0195\u0005p\u0000\u0000\u0195\u0196"+
+    "\u0001\u0000\u0000\u0000\u0196\u0197\u0006\b\u0001\u0000\u0197\u001d\u0001"+
+    "\u0000\u0000\u0000\u0198\u0199\u0005l\u0000\u0000\u0199\u019a\u0005i\u0000"+
+    "\u0000\u019a\u019b\u0005m\u0000\u0000\u019b\u019c\u0005i\u0000\u0000\u019c"+
+    "\u019d\u0005t\u0000\u0000\u019d\u019e\u0001\u0000\u0000\u0000\u019e\u019f"+
+    "\u0006\t\u0000\u0000\u019f\u001f\u0001\u0000\u0000\u0000\u01a0\u01a1\u0005"+
+    "m\u0000\u0000\u01a1\u01a2\u0005e\u0000\u0000\u01a2\u01a3\u0005t\u0000"+
+    "\u0000\u01a3\u01a4\u0005a\u0000\u0000\u01a4\u01a5\u0001\u0000\u0000\u0000"+
+    "\u01a5\u01a6\u0006\n\u0005\u0000\u01a6!\u0001\u0000\u0000\u0000\u01a7"+
+    "\u01a8\u0005m\u0000\u0000\u01a8\u01a9\u0005v\u0000\u0000\u01a9\u01aa\u0005"+
+    "_\u0000\u0000\u01aa\u01ab\u0005e\u0000\u0000\u01ab\u01ac\u0005x\u0000"+
+    "\u0000\u01ac\u01ad\u0005p\u0000\u0000\u01ad\u01ae\u0005a\u0000\u0000\u01ae"+
+    "\u01af\u0005n\u0000\u0000\u01af\u01b0\u0005d\u0000\u0000\u01b0\u01b1\u0001"+
+    "\u0000\u0000\u0000\u01b1\u01b2\u0006\u000b\u0006\u0000\u01b2#\u0001\u0000"+
+    "\u0000\u0000\u01b3\u01b4\u0005r\u0000\u0000\u01b4\u01b5\u0005e\u0000\u0000"+
+    "\u01b5\u01b6\u0005n\u0000\u0000\u01b6\u01b7\u0005a\u0000\u0000\u01b7\u01b8"+
+    "\u0005m\u0000\u0000\u01b8\u01b9\u0005e\u0000\u0000\u01b9\u01ba\u0001\u0000"+
+    "\u0000\u0000\u01ba\u01bb\u0006\f\u0007\u0000\u01bb%\u0001\u0000\u0000"+
+    "\u0000\u01bc\u01bd\u0005r\u0000\u0000\u01bd\u01be\u0005o\u0000\u0000\u01be"+
+    "\u01bf\u0005w\u0000\u0000\u01bf\u01c0\u0001\u0000\u0000\u0000\u01c0\u01c1"+
+    "\u0006\r\u0000\u0000\u01c1\'\u0001\u0000\u0000\u0000\u01c2\u01c3\u0005"+
+    "s\u0000\u0000\u01c3\u01c4\u0005h\u0000\u0000\u01c4\u01c5\u0005o\u0000"+
+    "\u0000\u01c5\u01c6\u0005w\u0000\u0000\u01c6\u01c7\u0001\u0000\u0000\u0000"+
+    "\u01c7\u01c8\u0006\u000e\b\u0000\u01c8)\u0001\u0000\u0000\u0000\u01c9"+
+    "\u01ca\u0005s\u0000\u0000\u01ca\u01cb\u0005o\u0000\u0000\u01cb\u01cc\u0005"+
+    "r\u0000\u0000\u01cc\u01cd\u0005t\u0000\u0000\u01cd\u01ce\u0001\u0000\u0000"+
+    "\u0000\u01ce\u01cf\u0006\u000f\u0000\u0000\u01cf+\u0001\u0000\u0000\u0000"+
+    "\u01d0\u01d1\u0005s\u0000\u0000\u01d1\u01d2\u0005t\u0000\u0000\u01d2\u01d3"+
+    "\u0005a\u0000\u0000\u01d3\u01d4\u0005t\u0000\u0000\u01d4\u01d5\u0005s"+
+    "\u0000\u0000\u01d5\u01d6\u0001\u0000\u0000\u0000\u01d6\u01d7\u0006\u0010"+
+    "\u0000\u0000\u01d7-\u0001\u0000\u0000\u0000\u01d8\u01d9\u0005w\u0000\u0000"+
+    "\u01d9\u01da\u0005h\u0000\u0000\u01da\u01db\u0005e\u0000\u0000\u01db\u01dc"+
+    "\u0005r\u0000\u0000\u01dc\u01dd\u0005e\u0000\u0000\u01dd\u01de\u0001\u0000"+
+    "\u0000\u0000\u01de\u01df\u0006\u0011\u0000\u0000\u01df/\u0001\u0000\u0000"+
+    "\u0000\u01e0\u01e2\b\u0000\u0000\u0000\u01e1\u01e0\u0001\u0000\u0000\u0000"+
+    "\u01e2\u01e3\u0001\u0000\u0000\u0000\u01e3\u01e1\u0001\u0000\u0000\u0000"+
+    "\u01e3\u01e4\u0001\u0000\u0000\u0000\u01e4\u01e5\u0001\u0000\u0000\u0000"+
+    "\u01e5\u01e6\u0006\u0012\u0000\u0000\u01e61\u0001\u0000\u0000\u0000\u01e7"+
+    "\u01e8\u0005/\u0000\u0000\u01e8\u01e9\u0005/\u0000\u0000\u01e9\u01ed\u0001"+
+    "\u0000\u0000\u0000\u01ea\u01ec\b\u0001\u0000\u0000\u01eb\u01ea\u0001\u0000"+
+    "\u0000\u0000\u01ec\u01ef\u0001\u0000\u0000\u0000\u01ed\u01eb\u0001\u0000"+
+    "\u0000\u0000\u01ed\u01ee\u0001\u0000\u0000\u0000\u01ee\u01f1\u0001\u0000"+
+    "\u0000\u0000\u01ef\u01ed\u0001\u0000\u0000\u0000\u01f0\u01f2\u0005\r\u0000"+
+    "\u0000\u01f1\u01f0\u0001\u0000\u0000\u0000\u01f1\u01f2\u0001\u0000\u0000"+
+    "\u0000\u01f2\u01f4\u0001\u0000\u0000\u0000\u01f3\u01f5\u0005\n\u0000\u0000"+
+    "\u01f4\u01f3\u0001\u0000\u0000\u0000\u01f4\u01f5\u0001\u0000\u0000\u0000"+
+    "\u01f5\u01f6\u0001\u0000\u0000\u0000\u01f6\u01f7\u0006\u0013\t\u0000\u01f7"+
+    "3\u0001\u0000\u0000\u0000\u01f8\u01f9\u0005/\u0000\u0000\u01f9\u01fa\u0005"+
+    "*\u0000\u0000\u01fa\u01ff\u0001\u0000\u0000\u0000\u01fb\u01fe\u00034\u0014"+
+    "\u0000\u01fc\u01fe\t\u0000\u0000\u0000\u01fd\u01fb\u0001\u0000\u0000\u0000"+
+    "\u01fd\u01fc\u0001\u0000\u0000\u0000\u01fe\u0201\u0001\u0000\u0000\u0000"+
+    "\u01ff\u0200\u0001\u0000\u0000\u0000\u01ff\u01fd\u0001\u0000\u0000\u0000"+
+    "\u0200\u0202\u0001\u0000\u0000\u0000\u0201\u01ff\u0001\u0000\u0000\u0000"+
+    "\u0202\u0203\u0005*\u0000\u0000\u0203\u0204\u0005/\u0000\u0000\u0204\u0205"+
+    "\u0001\u0000\u0000\u0000\u0205\u0206\u0006\u0014\t\u0000\u02065\u0001"+
+    "\u0000\u0000\u0000\u0207\u0209\u0007\u0002\u0000\u0000\u0208\u0207\u0001"+
+    "\u0000\u0000\u0000\u0209\u020a\u0001\u0000\u0000\u0000\u020a\u0208\u0001"+
+    "\u0000\u0000\u0000\u020a\u020b\u0001\u0000\u0000\u0000\u020b\u020c\u0001"+
+    "\u0000\u0000\u0000\u020c\u020d\u0006\u0015\t\u0000\u020d7\u0001\u0000"+
+    "\u0000\u0000\u020e\u020f\u0003\u00a2K\u0000\u020f\u0210\u0001\u0000\u0000"+
+    "\u0000\u0210\u0211\u0006\u0016\n\u0000\u0211\u0212\u0006\u0016\u000b\u0000"+
+    "\u02129\u0001\u0000\u0000\u0000\u0213\u0214\u0003B\u001b\u0000\u0214\u0215"+
+    "\u0001\u0000\u0000\u0000\u0215\u0216\u0006\u0017\f\u0000\u0216\u0217\u0006"+
+    "\u0017\r\u0000\u0217;\u0001\u0000\u0000\u0000\u0218\u0219\u00036\u0015"+
+    "\u0000\u0219\u021a\u0001\u0000\u0000\u0000\u021a\u021b\u0006\u0018\t\u0000"+
+    "\u021b=\u0001\u0000\u0000\u0000\u021c\u021d\u00032\u0013\u0000\u021d\u021e"+
+    "\u0001\u0000\u0000\u0000\u021e\u021f\u0006\u0019\t\u0000\u021f?\u0001"+
+    "\u0000\u0000\u0000\u0220\u0221\u00034\u0014\u0000\u0221\u0222\u0001\u0000"+
+    "\u0000\u0000\u0222\u0223\u0006\u001a\t\u0000\u0223A\u0001\u0000\u0000"+
+    "\u0000\u0224\u0225\u0005|\u0000\u0000\u0225\u0226\u0001\u0000\u0000\u0000"+
+    "\u0226\u0227\u0006\u001b\r\u0000\u0227C\u0001\u0000\u0000\u0000\u0228"+
+    "\u0229\u0007\u0003\u0000\u0000\u0229E\u0001\u0000\u0000\u0000\u022a\u022b"+
+    "\u0007\u0004\u0000\u0000\u022bG\u0001\u0000\u0000\u0000\u022c\u022d\u0005"+
+    "\\\u0000\u0000\u022d\u022e\u0007\u0005\u0000\u0000\u022eI\u0001\u0000"+
+    "\u0000\u0000\u022f\u0230\b\u0006\u0000\u0000\u0230K\u0001\u0000\u0000"+
+    "\u0000\u0231\u0233\u0007\u0007\u0000\u0000\u0232\u0234\u0007\b\u0000\u0000"+
+    "\u0233\u0232\u0001\u0000\u0000\u0000\u0233\u0234\u0001\u0000\u0000\u0000"+
+    "\u0234\u0236\u0001\u0000\u0000\u0000\u0235\u0237\u0003D\u001c\u0000\u0236"+
+    "\u0235\u0001\u0000\u0000\u0000\u0237\u0238\u0001\u0000\u0000\u0000\u0238"+
+    "\u0236\u0001\u0000\u0000\u0000\u0238\u0239\u0001\u0000\u0000\u0000\u0239"+
+    "M\u0001\u0000\u0000\u0000\u023a\u023b\u0005@\u0000\u0000\u023bO\u0001"+
+    "\u0000\u0000\u0000\u023c\u023d\u0005`\u0000\u0000\u023dQ\u0001\u0000\u0000"+
+    "\u0000\u023e\u0242\b\t\u0000\u0000\u023f\u0240\u0005`\u0000\u0000\u0240"+
+    "\u0242\u0005`\u0000\u0000\u0241\u023e\u0001\u0000\u0000\u0000\u0241\u023f"+
+    "\u0001\u0000\u0000\u0000\u0242S\u0001\u0000\u0000\u0000\u0243\u0244\u0005"+
+    "_\u0000\u0000\u0244U\u0001\u0000\u0000\u0000\u0245\u0249\u0003F\u001d"+
+    "\u0000\u0246\u0249\u0003D\u001c\u0000\u0247\u0249\u0003T$\u0000\u0248"+
+    "\u0245\u0001\u0000\u0000\u0000\u0248\u0246\u0001\u0000\u0000\u0000\u0248"+
+    "\u0247\u0001\u0000\u0000\u0000\u0249W\u0001\u0000\u0000\u0000\u024a\u024f"+
+    "\u0005\"\u0000\u0000\u024b\u024e\u0003H\u001e\u0000\u024c\u024e\u0003"+
+    "J\u001f\u0000\u024d\u024b\u0001\u0000\u0000\u0000\u024d\u024c\u0001\u0000"+
+    "\u0000\u0000\u024e\u0251\u0001\u0000\u0000\u0000\u024f\u024d\u0001\u0000"+
+    "\u0000\u0000\u024f\u0250\u0001\u0000\u0000\u0000\u0250\u0252\u0001\u0000"+
+    "\u0000\u0000\u0251\u024f\u0001\u0000\u0000\u0000\u0252\u0268\u0005\"\u0000"+
+    "\u0000\u0253\u0254\u0005\"\u0000\u0000\u0254\u0255\u0005\"\u0000\u0000"+
+    "\u0255\u0256\u0005\"\u0000\u0000\u0256\u025a\u0001\u0000\u0000\u0000\u0257"+
+    "\u0259\b\u0001\u0000\u0000\u0258\u0257\u0001\u0000\u0000\u0000\u0259\u025c"+
+    "\u0001\u0000\u0000\u0000\u025a\u025b\u0001\u0000\u0000\u0000\u025a\u0258"+
+    "\u0001\u0000\u0000\u0000\u025b\u025d\u0001\u0000\u0000\u0000\u025c\u025a"+
+    "\u0001\u0000\u0000\u0000\u025d\u025e\u0005\"\u0000\u0000\u025e\u025f\u0005"+
+    "\"\u0000\u0000\u025f\u0260\u0005\"\u0000\u0000\u0260\u0262\u0001\u0000"+
+    "\u0000\u0000\u0261\u0263\u0005\"\u0000\u0000\u0262\u0261\u0001\u0000\u0000"+
+    "\u0000\u0262\u0263\u0001\u0000\u0000\u0000\u0263\u0265\u0001\u0000\u0000"+
+    "\u0000\u0264\u0266\u0005\"\u0000\u0000\u0265\u0264\u0001\u0000\u0000\u0000"+
+    "\u0265\u0266\u0001\u0000\u0000\u0000\u0266\u0268\u0001\u0000\u0000\u0000"+
+    "\u0267\u024a\u0001\u0000\u0000\u0000\u0267\u0253\u0001\u0000\u0000\u0000"+
+    "\u0268Y\u0001\u0000\u0000\u0000\u0269\u026b\u0003D\u001c\u0000\u026a\u0269"+
+    "\u0001\u0000\u0000\u0000\u026b\u026c\u0001\u0000\u0000\u0000\u026c\u026a"+
+    "\u0001\u0000\u0000\u0000\u026c\u026d\u0001\u0000\u0000\u0000\u026d[\u0001"+
+    "\u0000\u0000\u0000\u026e\u0270\u0003D\u001c\u0000\u026f\u026e\u0001\u0000"+
+    "\u0000\u0000\u0270\u0271\u0001\u0000\u0000\u0000\u0271\u026f\u0001\u0000"+
+    "\u0000\u0000\u0271\u0272\u0001\u0000\u0000\u0000\u0272\u0273\u0001\u0000"+
+    "\u0000\u0000\u0273\u0277\u0003j/\u0000\u0274\u0276\u0003D\u001c\u0000"+
+    "\u0275\u0274\u0001\u0000\u0000\u0000\u0276\u0279\u0001\u0000\u0000\u0000"+
+    "\u0277\u0275\u0001\u0000\u0000\u0000\u0277\u0278\u0001\u0000\u0000\u0000"+
+    "\u0278\u0299\u0001\u0000\u0000\u0000\u0279\u0277\u0001\u0000\u0000\u0000"+
+    "\u027a\u027c\u0003j/\u0000\u027b\u027d\u0003D\u001c\u0000\u027c\u027b"+
+    "\u0001\u0000\u0000\u0000\u027d\u027e\u0001\u0000\u0000\u0000\u027e\u027c"+
+    "\u0001\u0000\u0000\u0000\u027e\u027f\u0001\u0000\u0000\u0000\u027f\u0299"+
+    "\u0001\u0000\u0000\u0000\u0280\u0282\u0003D\u001c\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\u028c\u0001"+
+    "\u0000\u0000\u0000\u0285\u0289\u0003j/\u0000\u0286\u0288\u0003D\u001c"+
+    "\u0000\u0287\u0286\u0001\u0000\u0000\u0000\u0288\u028b\u0001\u0000\u0000"+
+    "\u0000\u0289\u0287\u0001\u0000\u0000\u0000\u0289\u028a\u0001\u0000\u0000"+
+    "\u0000\u028a\u028d\u0001\u0000\u0000\u0000\u028b\u0289\u0001\u0000\u0000"+
+    "\u0000\u028c\u0285\u0001\u0000\u0000\u0000\u028c\u028d\u0001\u0000\u0000"+
+    "\u0000\u028d\u028e\u0001\u0000\u0000\u0000\u028e\u028f\u0003L \u0000\u028f"+
+    "\u0299\u0001\u0000\u0000\u0000\u0290\u0292\u0003j/\u0000\u0291\u0293\u0003"+
+    "D\u001c\u0000\u0292\u0291\u0001\u0000\u0000\u0000\u0293\u0294\u0001\u0000"+
+    "\u0000\u0000\u0294\u0292\u0001\u0000\u0000\u0000\u0294\u0295\u0001\u0000"+
+    "\u0000\u0000\u0295\u0296\u0001\u0000\u0000\u0000\u0296\u0297\u0003L \u0000"+
+    "\u0297\u0299\u0001\u0000\u0000\u0000\u0298\u026f\u0001\u0000\u0000\u0000"+
+    "\u0298\u027a\u0001\u0000\u0000\u0000\u0298\u0281\u0001\u0000\u0000\u0000"+
+    "\u0298\u0290\u0001\u0000\u0000\u0000\u0299]\u0001\u0000\u0000\u0000\u029a"+
+    "\u029b\u0005b\u0000\u0000\u029b\u029c\u0005y\u0000\u0000\u029c_\u0001"+
+    "\u0000\u0000\u0000\u029d\u029e\u0005a\u0000\u0000\u029e\u029f\u0005n\u0000"+
+    "\u0000\u029f\u02a0\u0005d\u0000\u0000\u02a0a\u0001\u0000\u0000\u0000\u02a1"+
+    "\u02a2\u0005a\u0000\u0000\u02a2\u02a3\u0005s\u0000\u0000\u02a3\u02a4\u0005"+
+    "c\u0000\u0000\u02a4c\u0001\u0000\u0000\u0000\u02a5\u02a6\u0005=\u0000"+
+    "\u0000\u02a6e\u0001\u0000\u0000\u0000\u02a7\u02a8\u0005,\u0000\u0000\u02a8"+
+    "g\u0001\u0000\u0000\u0000\u02a9\u02aa\u0005d\u0000\u0000\u02aa\u02ab\u0005"+
+    "e\u0000\u0000\u02ab\u02ac\u0005s\u0000\u0000\u02ac\u02ad\u0005c\u0000"+
+    "\u0000\u02adi\u0001\u0000\u0000\u0000\u02ae\u02af\u0005.\u0000\u0000\u02af"+
+    "k\u0001\u0000\u0000\u0000\u02b0\u02b1\u0005f\u0000\u0000\u02b1\u02b2\u0005"+
+    "a\u0000\u0000\u02b2\u02b3\u0005l\u0000\u0000\u02b3\u02b4\u0005s\u0000"+
+    "\u0000\u02b4\u02b5\u0005e\u0000\u0000\u02b5m\u0001\u0000\u0000\u0000\u02b6"+
+    "\u02b7\u0005f\u0000\u0000\u02b7\u02b8\u0005i\u0000\u0000\u02b8\u02b9\u0005"+
+    "r\u0000\u0000\u02b9\u02ba\u0005s\u0000\u0000\u02ba\u02bb\u0005t\u0000"+
+    "\u0000\u02bbo\u0001\u0000\u0000\u0000\u02bc\u02bd\u0005l\u0000\u0000\u02bd"+
+    "\u02be\u0005a\u0000\u0000\u02be\u02bf\u0005s\u0000\u0000\u02bf\u02c0\u0005"+
+    "t\u0000\u0000\u02c0q\u0001\u0000\u0000\u0000\u02c1\u02c2\u0005(\u0000"+
+    "\u0000\u02c2s\u0001\u0000\u0000\u0000\u02c3\u02c4\u0005i\u0000\u0000\u02c4"+
+    "\u02c5\u0005n\u0000\u0000\u02c5u\u0001\u0000\u0000\u0000\u02c6\u02c7\u0005"+
+    "i\u0000\u0000\u02c7\u02c8\u0005s\u0000\u0000\u02c8w\u0001\u0000\u0000"+
+    "\u0000\u02c9\u02ca\u0005l\u0000\u0000\u02ca\u02cb\u0005i\u0000\u0000\u02cb"+
+    "\u02cc\u0005k\u0000\u0000\u02cc\u02cd\u0005e\u0000\u0000\u02cdy\u0001"+
+    "\u0000\u0000\u0000\u02ce\u02cf\u0005n\u0000\u0000\u02cf\u02d0\u0005o\u0000"+
+    "\u0000\u02d0\u02d1\u0005t\u0000\u0000\u02d1{\u0001\u0000\u0000\u0000\u02d2"+
+    "\u02d3\u0005n\u0000\u0000\u02d3\u02d4\u0005u\u0000\u0000\u02d4\u02d5\u0005"+
+    "l\u0000\u0000\u02d5\u02d6\u0005l\u0000\u0000\u02d6}\u0001\u0000\u0000"+
+    "\u0000\u02d7\u02d8\u0005n\u0000\u0000\u02d8\u02d9\u0005u\u0000\u0000\u02d9"+
+    "\u02da\u0005l\u0000\u0000\u02da\u02db\u0005l\u0000\u0000\u02db\u02dc\u0005"+
+    "s\u0000\u0000\u02dc\u007f\u0001\u0000\u0000\u0000\u02dd\u02de\u0005o\u0000"+
+    "\u0000\u02de\u02df\u0005r\u0000\u0000\u02df\u0081\u0001\u0000\u0000\u0000"+
+    "\u02e0\u02e1\u0005?\u0000\u0000\u02e1\u0083\u0001\u0000\u0000\u0000\u02e2"+
+    "\u02e3\u0005r\u0000\u0000\u02e3\u02e4\u0005l\u0000\u0000\u02e4\u02e5\u0005"+
+    "i\u0000\u0000\u02e5\u02e6\u0005k\u0000\u0000\u02e6\u02e7\u0005e\u0000"+
+    "\u0000\u02e7\u0085\u0001\u0000\u0000\u0000\u02e8\u02e9\u0005)\u0000\u0000"+
+    "\u02e9\u0087\u0001\u0000\u0000\u0000\u02ea\u02eb\u0005t\u0000\u0000\u02eb"+
+    "\u02ec\u0005r\u0000\u0000\u02ec\u02ed\u0005u\u0000\u0000\u02ed\u02ee\u0005"+
+    "e\u0000\u0000\u02ee\u0089\u0001\u0000\u0000\u0000\u02ef\u02f0\u0005=\u0000"+
+    "\u0000\u02f0\u02f1\u0005=\u0000\u0000\u02f1\u008b\u0001\u0000\u0000\u0000"+
+    "\u02f2\u02f3\u0005=\u0000\u0000\u02f3\u02f4\u0005~\u0000\u0000\u02f4\u008d"+
+    "\u0001\u0000\u0000\u0000\u02f5\u02f6\u0005!\u0000\u0000\u02f6\u02f7\u0005"+
+    "=\u0000\u0000\u02f7\u008f\u0001\u0000\u0000\u0000\u02f8\u02f9\u0005<\u0000"+
+    "\u0000\u02f9\u0091\u0001\u0000\u0000\u0000\u02fa\u02fb\u0005<\u0000\u0000"+
+    "\u02fb\u02fc\u0005=\u0000\u0000\u02fc\u0093\u0001\u0000\u0000\u0000\u02fd"+
+    "\u02fe\u0005>\u0000\u0000\u02fe\u0095\u0001\u0000\u0000\u0000\u02ff\u0300"+
+    "\u0005>\u0000\u0000\u0300\u0301\u0005=\u0000\u0000\u0301\u0097\u0001\u0000"+
+    "\u0000\u0000\u0302\u0303\u0005+\u0000\u0000\u0303\u0099\u0001\u0000\u0000"+
+    "\u0000\u0304\u0305\u0005-\u0000\u0000\u0305\u009b\u0001\u0000\u0000\u0000"+
+    "\u0306\u0307\u0005*\u0000\u0000\u0307\u009d\u0001\u0000\u0000\u0000\u0308"+
+    "\u0309\u0005/\u0000\u0000\u0309\u009f\u0001\u0000\u0000\u0000\u030a\u030b"+
+    "\u0005%\u0000\u0000\u030b\u00a1\u0001\u0000\u0000\u0000\u030c\u030d\u0005"+
+    "[\u0000\u0000\u030d\u030e\u0001\u0000\u0000\u0000\u030e\u030f\u0006K\u0000"+
+    "\u0000\u030f\u0310\u0006K\u0000\u0000\u0310\u00a3\u0001\u0000\u0000\u0000"+
+    "\u0311\u0312\u0005]\u0000\u0000\u0312\u0313\u0001\u0000\u0000\u0000\u0313"+
+    "\u0314\u0006L\r\u0000\u0314\u0315\u0006L\r\u0000\u0315\u00a5\u0001\u0000"+
+    "\u0000\u0000\u0316\u031a\u0003F\u001d\u0000\u0317\u0319\u0003V%\u0000"+
+    "\u0318\u0317\u0001\u0000\u0000\u0000\u0319\u031c\u0001\u0000\u0000\u0000"+
+    "\u031a\u0318\u0001\u0000\u0000\u0000\u031a\u031b\u0001\u0000\u0000\u0000"+
+    "\u031b\u0327\u0001\u0000\u0000\u0000\u031c\u031a\u0001\u0000\u0000\u0000"+
+    "\u031d\u0320\u0003T$\u0000\u031e\u0320\u0003N!\u0000\u031f\u031d\u0001"+
+    "\u0000\u0000\u0000\u031f\u031e\u0001\u0000\u0000\u0000\u0320\u0322\u0001"+
+    "\u0000\u0000\u0000\u0321\u0323\u0003V%\u0000\u0322\u0321\u0001\u0000\u0000"+
+    "\u0000\u0323\u0324\u0001\u0000\u0000\u0000\u0324\u0322\u0001\u0000\u0000"+
+    "\u0000\u0324\u0325\u0001\u0000\u0000\u0000\u0325\u0327\u0001\u0000\u0000"+
+    "\u0000\u0326\u0316\u0001\u0000\u0000\u0000\u0326\u031f\u0001\u0000\u0000"+
+    "\u0000\u0327\u00a7\u0001\u0000\u0000\u0000\u0328\u032a\u0003P\"\u0000"+
+    "\u0329\u032b\u0003R#\u0000\u032a\u0329\u0001\u0000\u0000\u0000\u032b\u032c"+
+    "\u0001\u0000\u0000\u0000\u032c\u032a\u0001\u0000\u0000\u0000\u032c\u032d"+
+    "\u0001\u0000\u0000\u0000\u032d\u032e\u0001\u0000\u0000\u0000\u032e\u032f"+
+    "\u0003P\"\u0000\u032f\u00a9\u0001\u0000\u0000\u0000\u0330\u0331\u0003"+
+    "\u00a8N\u0000\u0331\u00ab\u0001\u0000\u0000\u0000\u0332\u0333\u00032\u0013"+
+    "\u0000\u0333\u0334\u0001\u0000\u0000\u0000\u0334\u0335\u0006P\t\u0000"+
+    "\u0335\u00ad\u0001\u0000\u0000\u0000\u0336\u0337\u00034\u0014\u0000\u0337"+
+    "\u0338\u0001\u0000\u0000\u0000\u0338\u0339\u0006Q\t\u0000\u0339\u00af"+
+    "\u0001\u0000\u0000\u0000\u033a\u033b\u00036\u0015\u0000\u033b\u033c\u0001"+
+    "\u0000\u0000\u0000\u033c\u033d\u0006R\t\u0000\u033d\u00b1\u0001\u0000"+
+    "\u0000\u0000\u033e\u033f\u0003B\u001b\u0000\u033f\u0340\u0001\u0000\u0000"+
+    "\u0000\u0340\u0341\u0006S\f\u0000\u0341\u0342\u0006S\r\u0000\u0342\u00b3"+
+    "\u0001\u0000\u0000\u0000\u0343\u0344\u0003\u00a2K\u0000\u0344\u0345\u0001"+
+    "\u0000\u0000\u0000\u0345\u0346\u0006T\n\u0000\u0346\u00b5\u0001\u0000"+
+    "\u0000\u0000\u0347\u0348\u0003\u00a4L\u0000\u0348\u0349\u0001\u0000\u0000"+
+    "\u0000\u0349\u034a\u0006U\u000e\u0000\u034a\u00b7\u0001\u0000\u0000\u0000"+
+    "\u034b\u034c\u0003f-\u0000\u034c\u034d\u0001\u0000\u0000\u0000\u034d\u034e"+
+    "\u0006V\u000f\u0000\u034e\u00b9\u0001\u0000\u0000\u0000\u034f\u0350\u0003"+
+    "d,\u0000\u0350\u0351\u0001\u0000\u0000\u0000\u0351\u0352\u0006W\u0010"+
+    "\u0000\u0352\u00bb\u0001\u0000\u0000\u0000\u0353\u0354\u0003X&\u0000\u0354"+
+    "\u0355\u0001\u0000\u0000\u0000\u0355\u0356\u0006X\u0011\u0000\u0356\u00bd"+
+    "\u0001\u0000\u0000\u0000\u0357\u0358\u0005o\u0000\u0000\u0358\u0359\u0005"+
+    "p\u0000\u0000\u0359\u035a\u0005t\u0000\u0000\u035a\u035b\u0005i\u0000"+
+    "\u0000\u035b\u035c\u0005o\u0000\u0000\u035c\u035d\u0005n\u0000\u0000\u035d"+
+    "\u035e\u0005s\u0000\u0000\u035e\u00bf\u0001\u0000\u0000\u0000\u035f\u0360"+
+    "\u0005m\u0000\u0000\u0360\u0361\u0005e\u0000\u0000\u0361\u0362\u0005t"+
+    "\u0000\u0000\u0362\u0363\u0005a\u0000\u0000\u0363\u0364\u0005d\u0000\u0000"+
+    "\u0364\u0365\u0005a\u0000\u0000\u0365\u0366\u0005t\u0000\u0000\u0366\u0367"+
+    "\u0005a\u0000\u0000\u0367\u00c1\u0001\u0000\u0000\u0000\u0368\u036c\b"+
+    "\n\u0000\u0000\u0369\u036a\u0005/\u0000\u0000\u036a\u036c\b\u000b\u0000"+
+    "\u0000\u036b\u0368\u0001\u0000\u0000\u0000\u036b\u0369\u0001\u0000\u0000"+
+    "\u0000\u036c\u00c3\u0001\u0000\u0000\u0000\u036d\u036f\u0003\u00c2[\u0000"+
+    "\u036e\u036d\u0001\u0000\u0000\u0000\u036f\u0370\u0001\u0000\u0000\u0000"+
+    "\u0370\u036e\u0001\u0000\u0000\u0000\u0370\u0371\u0001\u0000\u0000\u0000"+
+    "\u0371\u00c5\u0001\u0000\u0000\u0000\u0372\u0373\u0003\u00aaO\u0000\u0373"+
+    "\u0374\u0001\u0000\u0000\u0000\u0374\u0375\u0006]\u0012\u0000\u0375\u00c7"+
+    "\u0001\u0000\u0000\u0000\u0376\u0377\u00032\u0013\u0000\u0377\u0378\u0001"+
+    "\u0000\u0000\u0000\u0378\u0379\u0006^\t\u0000\u0379\u00c9\u0001\u0000"+
+    "\u0000\u0000\u037a\u037b\u00034\u0014\u0000\u037b\u037c\u0001\u0000\u0000"+
+    "\u0000\u037c\u037d\u0006_\t\u0000\u037d\u00cb\u0001\u0000\u0000\u0000"+
+    "\u037e\u037f\u00036\u0015\u0000\u037f\u0380\u0001\u0000\u0000\u0000\u0380"+
+    "\u0381\u0006`\t\u0000\u0381\u00cd\u0001\u0000\u0000\u0000\u0382\u0383"+
+    "\u0003B\u001b\u0000\u0383\u0384\u0001\u0000\u0000\u0000\u0384\u0385\u0006"+
+    "a\f\u0000\u0385\u0386\u0006a\r\u0000\u0386\u00cf\u0001\u0000\u0000\u0000"+
+    "\u0387\u0388\u0003j/\u0000\u0388\u0389\u0001\u0000\u0000\u0000\u0389\u038a"+
+    "\u0006b\u0013\u0000\u038a\u00d1\u0001\u0000\u0000\u0000\u038b\u038c\u0003"+
+    "f-\u0000\u038c\u038d\u0001\u0000\u0000\u0000\u038d\u038e\u0006c\u000f"+
+    "\u0000\u038e\u00d3\u0001\u0000\u0000\u0000\u038f\u0394\u0003F\u001d\u0000"+
+    "\u0390\u0394\u0003D\u001c\u0000\u0391\u0394\u0003T$\u0000\u0392\u0394"+
+    "\u0003\u009cH\u0000\u0393\u038f\u0001\u0000\u0000\u0000\u0393\u0390\u0001"+
+    "\u0000\u0000\u0000\u0393\u0391\u0001\u0000\u0000\u0000\u0393\u0392\u0001"+
+    "\u0000\u0000\u0000\u0394\u00d5\u0001\u0000\u0000\u0000\u0395\u0398\u0003"+
+    "F\u001d\u0000\u0396\u0398\u0003\u009cH\u0000\u0397\u0395\u0001\u0000\u0000"+
+    "\u0000\u0397\u0396\u0001\u0000\u0000\u0000\u0398\u039c\u0001\u0000\u0000"+
+    "\u0000\u0399\u039b\u0003\u00d4d\u0000\u039a\u0399\u0001\u0000\u0000\u0000"+
+    "\u039b\u039e\u0001\u0000\u0000\u0000\u039c\u039a\u0001\u0000\u0000\u0000"+
+    "\u039c\u039d\u0001\u0000\u0000\u0000\u039d\u03a9\u0001\u0000\u0000\u0000"+
+    "\u039e\u039c\u0001\u0000\u0000\u0000\u039f\u03a2\u0003T$\u0000\u03a0\u03a2"+
+    "\u0003N!\u0000\u03a1\u039f\u0001\u0000\u0000\u0000\u03a1\u03a0\u0001\u0000"+
+    "\u0000\u0000\u03a2\u03a4\u0001\u0000\u0000\u0000\u03a3\u03a5\u0003\u00d4"+
+    "d\u0000\u03a4\u03a3\u0001\u0000\u0000\u0000\u03a5\u03a6\u0001\u0000\u0000"+
+    "\u0000\u03a6\u03a4\u0001\u0000\u0000\u0000\u03a6\u03a7\u0001\u0000\u0000"+
+    "\u0000\u03a7\u03a9\u0001\u0000\u0000\u0000\u03a8\u0397\u0001\u0000\u0000"+
+    "\u0000\u03a8\u03a1\u0001\u0000\u0000\u0000\u03a9\u00d7\u0001\u0000\u0000"+
+    "\u0000\u03aa\u03ad\u0003\u00d6e\u0000\u03ab\u03ad\u0003\u00a8N\u0000\u03ac"+
+    "\u03aa\u0001\u0000\u0000\u0000\u03ac\u03ab\u0001\u0000\u0000\u0000\u03ad"+
+    "\u03ae\u0001\u0000\u0000\u0000\u03ae\u03ac\u0001\u0000\u0000\u0000\u03ae"+
+    "\u03af\u0001\u0000\u0000\u0000\u03af\u00d9\u0001\u0000\u0000\u0000\u03b0"+
+    "\u03b1\u00032\u0013\u0000\u03b1\u03b2\u0001\u0000\u0000\u0000\u03b2\u03b3"+
+    "\u0006g\t\u0000\u03b3\u00db\u0001\u0000\u0000\u0000\u03b4\u03b5\u0003"+
+    "4\u0014\u0000\u03b5\u03b6\u0001\u0000\u0000\u0000\u03b6\u03b7\u0006h\t"+
+    "\u0000\u03b7\u00dd\u0001\u0000\u0000\u0000\u03b8\u03b9\u00036\u0015\u0000"+
+    "\u03b9\u03ba\u0001\u0000\u0000\u0000\u03ba\u03bb\u0006i\t\u0000\u03bb"+
+    "\u00df\u0001\u0000\u0000\u0000\u03bc\u03bd\u0003B\u001b\u0000\u03bd\u03be"+
+    "\u0001\u0000\u0000\u0000\u03be\u03bf\u0006j\f\u0000\u03bf\u03c0\u0006"+
+    "j\r\u0000\u03c0\u00e1\u0001\u0000\u0000\u0000\u03c1\u03c2\u0003d,\u0000"+
+    "\u03c2\u03c3\u0001\u0000\u0000\u0000\u03c3\u03c4\u0006k\u0010\u0000\u03c4"+
+    "\u00e3\u0001\u0000\u0000\u0000\u03c5\u03c6\u0003f-\u0000\u03c6\u03c7\u0001"+
+    "\u0000\u0000\u0000\u03c7\u03c8\u0006l\u000f\u0000\u03c8\u00e5\u0001\u0000"+
+    "\u0000\u0000\u03c9\u03ca\u0003j/\u0000\u03ca\u03cb\u0001\u0000\u0000\u0000"+
+    "\u03cb\u03cc\u0006m\u0013\u0000\u03cc\u00e7\u0001\u0000\u0000\u0000\u03cd"+
+    "\u03ce\u0005a\u0000\u0000\u03ce\u03cf\u0005s\u0000\u0000\u03cf\u00e9\u0001"+
+    "\u0000\u0000\u0000\u03d0\u03d1\u0003\u00d8f\u0000\u03d1\u03d2\u0001\u0000"+
+    "\u0000\u0000\u03d2\u03d3\u0006o\u0014\u0000\u03d3\u00eb\u0001\u0000\u0000"+
+    "\u0000\u03d4\u03d5\u00032\u0013\u0000\u03d5\u03d6\u0001\u0000\u0000\u0000"+
+    "\u03d6\u03d7\u0006p\t\u0000\u03d7\u00ed\u0001\u0000\u0000\u0000\u03d8"+
+    "\u03d9\u00034\u0014\u0000\u03d9\u03da\u0001\u0000\u0000\u0000\u03da\u03db"+
+    "\u0006q\t\u0000\u03db\u00ef\u0001\u0000\u0000\u0000\u03dc\u03dd\u0003"+
+    "6\u0015\u0000\u03dd\u03de\u0001\u0000\u0000\u0000\u03de\u03df\u0006r\t"+
+    "\u0000\u03df\u00f1\u0001\u0000\u0000\u0000\u03e0\u03e1\u0003B\u001b\u0000"+
+    "\u03e1\u03e2\u0001\u0000\u0000\u0000\u03e2\u03e3\u0006s\f\u0000\u03e3"+
+    "\u03e4\u0006s\r\u0000\u03e4\u00f3\u0001\u0000\u0000\u0000\u03e5\u03e6"+
+    "\u0003\u00a2K\u0000\u03e6\u03e7\u0001\u0000\u0000\u0000\u03e7\u03e8\u0006"+
+    "t\n\u0000\u03e8\u03e9\u0006t\u0015\u0000\u03e9\u00f5\u0001\u0000\u0000"+
+    "\u0000\u03ea\u03eb\u0005o\u0000\u0000\u03eb\u03ec\u0005n\u0000\u0000\u03ec"+
+    "\u03ed\u0001\u0000\u0000\u0000\u03ed\u03ee\u0006u\u0016\u0000\u03ee\u00f7"+
+    "\u0001\u0000\u0000\u0000\u03ef\u03f0\u0005w\u0000\u0000\u03f0\u03f1\u0005"+
+    "i\u0000\u0000\u03f1\u03f2\u0005t\u0000\u0000\u03f2\u03f3\u0005h\u0000"+
+    "\u0000\u03f3\u03f4\u0001\u0000\u0000\u0000\u03f4\u03f5\u0006v\u0016\u0000"+
+    "\u03f5\u00f9\u0001\u0000\u0000\u0000\u03f6\u03f7\b\f\u0000\u0000\u03f7"+
+    "\u00fb\u0001\u0000\u0000\u0000\u03f8\u03fa\u0003\u00faw\u0000\u03f9\u03f8"+
+    "\u0001\u0000\u0000\u0000\u03fa\u03fb\u0001\u0000\u0000\u0000\u03fb\u03f9"+
+    "\u0001\u0000\u0000\u0000\u03fb\u03fc\u0001\u0000\u0000\u0000\u03fc\u03fd"+
+    "\u0001\u0000\u0000\u0000\u03fd\u03fe\u0003\u0140\u009a\u0000\u03fe\u0400"+
+    "\u0001\u0000\u0000\u0000\u03ff\u03f9\u0001\u0000\u0000\u0000\u03ff\u0400"+
+    "\u0001\u0000\u0000\u0000\u0400\u0402\u0001\u0000\u0000\u0000\u0401\u0403"+
+    "\u0003\u00faw\u0000\u0402\u0401\u0001\u0000\u0000\u0000\u0403\u0404\u0001"+
+    "\u0000\u0000\u0000\u0404\u0402\u0001\u0000\u0000\u0000\u0404\u0405\u0001"+
+    "\u0000\u0000\u0000\u0405\u00fd\u0001\u0000\u0000\u0000\u0406\u0407\u0003"+
+    "\u00aaO\u0000\u0407\u0408\u0001\u0000\u0000\u0000\u0408\u0409\u0006y\u0012"+
+    "\u0000\u0409\u00ff\u0001\u0000\u0000\u0000\u040a\u040b\u0003\u00fcx\u0000"+
+    "\u040b\u040c\u0001\u0000\u0000\u0000\u040c\u040d\u0006z\u0017\u0000\u040d"+
+    "\u0101\u0001\u0000\u0000\u0000\u040e\u040f\u00032\u0013\u0000\u040f\u0410"+
+    "\u0001\u0000\u0000\u0000\u0410\u0411\u0006{\t\u0000\u0411\u0103\u0001"+
+    "\u0000\u0000\u0000\u0412\u0413\u00034\u0014\u0000\u0413\u0414\u0001\u0000"+
+    "\u0000\u0000\u0414\u0415\u0006|\t\u0000\u0415\u0105\u0001\u0000\u0000"+
+    "\u0000\u0416\u0417\u00036\u0015\u0000\u0417\u0418\u0001\u0000\u0000\u0000"+
+    "\u0418\u0419\u0006}\t\u0000\u0419\u0107\u0001\u0000\u0000\u0000\u041a"+
+    "\u041b\u0003B\u001b\u0000\u041b\u041c\u0001\u0000\u0000\u0000\u041c\u041d"+
+    "\u0006~\f\u0000\u041d\u041e\u0006~\r\u0000\u041e\u041f\u0006~\r\u0000"+
+    "\u041f\u0109\u0001\u0000\u0000\u0000\u0420\u0421\u0003d,\u0000\u0421\u0422"+
+    "\u0001\u0000\u0000\u0000\u0422\u0423\u0006\u007f\u0010\u0000\u0423\u010b"+
+    "\u0001\u0000\u0000\u0000\u0424\u0425\u0003f-\u0000\u0425\u0426\u0001\u0000"+
+    "\u0000\u0000\u0426\u0427\u0006\u0080\u000f\u0000\u0427\u010d\u0001\u0000"+
+    "\u0000\u0000\u0428\u0429\u0003j/\u0000\u0429\u042a\u0001\u0000\u0000\u0000"+
+    "\u042a\u042b\u0006\u0081\u0013\u0000\u042b\u010f\u0001\u0000\u0000\u0000"+
+    "\u042c\u042d\u0003\u00f8v\u0000\u042d\u042e\u0001\u0000\u0000\u0000\u042e"+
+    "\u042f\u0006\u0082\u0018\u0000\u042f\u0111\u0001\u0000\u0000\u0000\u0430"+
+    "\u0431\u0003\u00d8f\u0000\u0431\u0432\u0001\u0000\u0000\u0000\u0432\u0433"+
+    "\u0006\u0083\u0014\u0000\u0433\u0113\u0001\u0000\u0000\u0000\u0434\u0435"+
+    "\u0003\u00aaO\u0000\u0435\u0436\u0001\u0000\u0000\u0000\u0436\u0437\u0006"+
+    "\u0084\u0012\u0000\u0437\u0115\u0001\u0000\u0000\u0000\u0438\u0439\u0003"+
+    "2\u0013\u0000\u0439\u043a\u0001\u0000\u0000\u0000\u043a\u043b\u0006\u0085"+
+    "\t\u0000\u043b\u0117\u0001\u0000\u0000\u0000\u043c\u043d\u00034\u0014"+
+    "\u0000\u043d\u043e\u0001\u0000\u0000\u0000\u043e\u043f\u0006\u0086\t\u0000"+
+    "\u043f\u0119\u0001\u0000\u0000\u0000\u0440\u0441\u00036\u0015\u0000\u0441"+
+    "\u0442\u0001\u0000\u0000\u0000\u0442\u0443\u0006\u0087\t\u0000\u0443\u011b"+
+    "\u0001\u0000\u0000\u0000\u0444\u0445\u0003B\u001b\u0000\u0445\u0446\u0001"+
+    "\u0000\u0000\u0000\u0446\u0447\u0006\u0088\f\u0000\u0447\u0448\u0006\u0088"+
+    "\r\u0000\u0448\u011d\u0001\u0000\u0000\u0000\u0449\u044a\u0003j/\u0000"+
+    "\u044a\u044b\u0001\u0000\u0000\u0000\u044b\u044c\u0006\u0089\u0013\u0000"+
+    "\u044c\u011f\u0001\u0000\u0000\u0000\u044d\u044e\u0003\u00aaO\u0000\u044e"+
+    "\u044f\u0001\u0000\u0000\u0000\u044f\u0450\u0006\u008a\u0012\u0000\u0450"+
+    "\u0121\u0001\u0000\u0000\u0000\u0451\u0452\u0003\u00a6M\u0000\u0452\u0453"+
+    "\u0001\u0000\u0000\u0000\u0453\u0454\u0006\u008b\u0019\u0000\u0454\u0123"+
+    "\u0001\u0000\u0000\u0000\u0455\u0456\u00032\u0013\u0000\u0456\u0457\u0001"+
+    "\u0000\u0000\u0000\u0457\u0458\u0006\u008c\t\u0000\u0458\u0125\u0001\u0000"+
+    "\u0000\u0000\u0459\u045a\u00034\u0014\u0000\u045a\u045b\u0001\u0000\u0000"+
+    "\u0000\u045b\u045c\u0006\u008d\t\u0000\u045c\u0127\u0001\u0000\u0000\u0000"+
+    "\u045d\u045e\u00036\u0015\u0000\u045e\u045f\u0001\u0000\u0000\u0000\u045f"+
+    "\u0460\u0006\u008e\t\u0000\u0460\u0129\u0001\u0000\u0000\u0000\u0461\u0462"+
+    "\u0003B\u001b\u0000\u0462\u0463\u0001\u0000\u0000\u0000\u0463\u0464\u0006"+
+    "\u008f\f\u0000\u0464\u0465\u0006\u008f\r\u0000\u0465\u012b\u0001\u0000"+
+    "\u0000\u0000\u0466\u0467\u0005i\u0000\u0000\u0467\u0468\u0005n\u0000\u0000"+
+    "\u0468\u0469\u0005f\u0000\u0000\u0469\u046a\u0005o\u0000\u0000\u046a\u012d"+
+    "\u0001\u0000\u0000\u0000\u046b\u046c\u00032\u0013\u0000\u046c\u046d\u0001"+
+    "\u0000\u0000\u0000\u046d\u046e\u0006\u0091\t\u0000\u046e\u012f\u0001\u0000"+
+    "\u0000\u0000\u046f\u0470\u00034\u0014\u0000\u0470\u0471\u0001\u0000\u0000"+
+    "\u0000\u0471\u0472\u0006\u0092\t\u0000\u0472\u0131\u0001\u0000\u0000\u0000"+
+    "\u0473\u0474\u00036\u0015\u0000\u0474\u0475\u0001\u0000\u0000\u0000\u0475"+
+    "\u0476\u0006\u0093\t\u0000\u0476\u0133\u0001\u0000\u0000\u0000\u0477\u0478"+
+    "\u0003B\u001b\u0000\u0478\u0479\u0001\u0000\u0000\u0000\u0479\u047a\u0006"+
+    "\u0094\f\u0000\u047a\u047b\u0006\u0094\r\u0000\u047b\u0135\u0001\u0000"+
+    "\u0000\u0000\u047c\u047d\u0005f\u0000\u0000\u047d\u047e\u0005u\u0000\u0000"+
+    "\u047e\u047f\u0005n\u0000\u0000\u047f\u0480\u0005c\u0000\u0000\u0480\u0481"+
+    "\u0005t\u0000\u0000\u0481\u0482\u0005i\u0000\u0000\u0482\u0483\u0005o"+
+    "\u0000\u0000\u0483\u0484\u0005n\u0000\u0000\u0484\u0485\u0005s\u0000\u0000"+
+    "\u0485\u0137\u0001\u0000\u0000\u0000\u0486\u0487\u00032\u0013\u0000\u0487"+
+    "\u0488\u0001\u0000\u0000\u0000\u0488\u0489\u0006\u0096\t\u0000\u0489\u0139"+
+    "\u0001\u0000\u0000\u0000\u048a\u048b\u00034\u0014\u0000\u048b\u048c\u0001"+
+    "\u0000\u0000\u0000\u048c\u048d\u0006\u0097\t\u0000\u048d\u013b\u0001\u0000"+
+    "\u0000\u0000\u048e\u048f\u00036\u0015\u0000\u048f\u0490\u0001\u0000\u0000"+
+    "\u0000\u0490\u0491\u0006\u0098\t\u0000\u0491\u013d\u0001\u0000\u0000\u0000"+
+    "\u0492\u0493\u0003\u00a4L\u0000\u0493\u0494\u0001\u0000\u0000\u0000\u0494"+
+    "\u0495\u0006\u0099\u000e\u0000\u0495\u0496\u0006\u0099\r\u0000\u0496\u013f"+
+    "\u0001\u0000\u0000\u0000\u0497\u0498\u0005:\u0000\u0000\u0498\u0141\u0001"+
+    "\u0000\u0000\u0000\u0499\u049f\u0003N!\u0000\u049a\u049f\u0003D\u001c"+
+    "\u0000\u049b\u049f\u0003j/\u0000\u049c\u049f\u0003F\u001d\u0000\u049d"+
+    "\u049f\u0003T$\u0000\u049e\u0499\u0001\u0000\u0000\u0000\u049e\u049a\u0001"+
+    "\u0000\u0000\u0000\u049e\u049b\u0001\u0000\u0000\u0000\u049e\u049c\u0001"+
+    "\u0000\u0000\u0000\u049e\u049d\u0001\u0000\u0000\u0000\u049f\u04a0\u0001"+
+    "\u0000\u0000\u0000\u04a0\u049e\u0001\u0000\u0000\u0000\u04a0\u04a1\u0001"+
+    "\u0000\u0000\u0000\u04a1\u0143\u0001\u0000\u0000\u0000\u04a2\u04a3\u0003"+
+    "2\u0013\u0000\u04a3\u04a4\u0001\u0000\u0000\u0000\u04a4\u04a5\u0006\u009c"+
+    "\t\u0000\u04a5\u0145\u0001\u0000\u0000\u0000\u04a6\u04a7\u00034\u0014"+
+    "\u0000\u04a7\u04a8\u0001\u0000\u0000\u0000\u04a8\u04a9\u0006\u009d\t\u0000"+
+    "\u04a9\u0147\u0001\u0000\u0000\u0000\u04aa\u04ab\u00036\u0015\u0000\u04ab"+
+    "\u04ac\u0001\u0000\u0000\u0000\u04ac\u04ad\u0006\u009e\t\u0000\u04ad\u0149"+
+    "\u0001\u0000\u0000\u0000:\u0000\u0001\u0002\u0003\u0004\u0005\u0006\u0007"+
+    "\b\t\n\u000b\u01e3\u01ed\u01f1\u01f4\u01fd\u01ff\u020a\u0233\u0238\u0241"+
+    "\u0248\u024d\u024f\u025a\u0262\u0265\u0267\u026c\u0271\u0277\u027e\u0283"+
+    "\u0289\u028c\u0294\u0298\u031a\u031f\u0324\u0326\u032c\u036b\u0370\u0393"+
+    "\u0397\u039c\u03a1\u03a6\u03a8\u03ac\u03ae\u03fb\u03ff\u0404\u049e\u04a0"+
+    "\u001a\u0005\u0002\u0000\u0005\u0004\u0000\u0005\u0006\u0000\u0005\u0001"+
+    "\u0000\u0005\u0003\u0000\u0005\n\u0000\u0005\b\u0000\u0005\u0005\u0000"+
+    "\u0005\t\u0000\u0000\u0001\u0000\u0007@\u0000\u0005\u0000\u0000\u0007"+
+    "\u001a\u0000\u0004\u0000\u0000\u0007A\u0000\u0007\"\u0000\u0007!\u0000"+
+    "\u0007\u001b\u0000\u0007C\u0000\u0007$\u0000\u0007M\u0000\u0005\u000b"+
+    "\u0000\u0005\u0007\u0000\u0007W\u0000\u0007V\u0000\u0007B\u0000";
   public static final ATN _ATN =
     new ATNDeserializer().deserialize(_serializedATN.toCharArray());
   static {

ファイルの差分が大きいため隠しています
+ 6 - 2
x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/parser/EsqlBaseParser.interp


ファイルの差分が大きいため隠しています
+ 371 - 173
x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/parser/EsqlBaseParser.java


+ 36 - 12
x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/parser/EsqlBaseParserBaseListener.java

@@ -336,6 +336,42 @@ public class EsqlBaseParserBaseListener implements EsqlBaseParserListener {
    * <p>The default implementation does nothing.</p>
    */
   @Override public void exitFromCommand(EsqlBaseParser.FromCommandContext ctx) { }
+  /**
+   * {@inheritDoc}
+   *
+   * <p>The default implementation does nothing.</p>
+   */
+  @Override public void enterFromIdentifier(EsqlBaseParser.FromIdentifierContext ctx) { }
+  /**
+   * {@inheritDoc}
+   *
+   * <p>The default implementation does nothing.</p>
+   */
+  @Override public void exitFromIdentifier(EsqlBaseParser.FromIdentifierContext ctx) { }
+  /**
+   * {@inheritDoc}
+   *
+   * <p>The default implementation does nothing.</p>
+   */
+  @Override public void enterFromOptions(EsqlBaseParser.FromOptionsContext ctx) { }
+  /**
+   * {@inheritDoc}
+   *
+   * <p>The default implementation does nothing.</p>
+   */
+  @Override public void exitFromOptions(EsqlBaseParser.FromOptionsContext ctx) { }
+  /**
+   * {@inheritDoc}
+   *
+   * <p>The default implementation does nothing.</p>
+   */
+  @Override public void enterConfigOption(EsqlBaseParser.ConfigOptionContext ctx) { }
+  /**
+   * {@inheritDoc}
+   *
+   * <p>The default implementation does nothing.</p>
+   */
+  @Override public void exitConfigOption(EsqlBaseParser.ConfigOptionContext ctx) { }
   /**
    * {@inheritDoc}
    *
@@ -408,18 +444,6 @@ public class EsqlBaseParserBaseListener implements EsqlBaseParserListener {
    * <p>The default implementation does nothing.</p>
    */
   @Override public void exitInlinestatsCommand(EsqlBaseParser.InlinestatsCommandContext ctx) { }
-  /**
-   * {@inheritDoc}
-   *
-   * <p>The default implementation does nothing.</p>
-   */
-  @Override public void enterFromIdentifier(EsqlBaseParser.FromIdentifierContext ctx) { }
-  /**
-   * {@inheritDoc}
-   *
-   * <p>The default implementation does nothing.</p>
-   */
-  @Override public void exitFromIdentifier(EsqlBaseParser.FromIdentifierContext ctx) { }
   /**
    * {@inheritDoc}
    *

+ 21 - 7
x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/parser/EsqlBaseParserBaseVisitor.java

@@ -207,49 +207,63 @@ public class EsqlBaseParserBaseVisitor<T> extends AbstractParseTreeVisitor<T> im
    * <p>The default implementation returns the result of calling
    * {@link #visitChildren} on {@code ctx}.</p>
    */
-  @Override public T visitMetadata(EsqlBaseParser.MetadataContext ctx) { return visitChildren(ctx); }
+  @Override public T visitFromIdentifier(EsqlBaseParser.FromIdentifierContext ctx) { return visitChildren(ctx); }
   /**
    * {@inheritDoc}
    *
    * <p>The default implementation returns the result of calling
    * {@link #visitChildren} on {@code ctx}.</p>
    */
-  @Override public T visitMetadataOption(EsqlBaseParser.MetadataOptionContext ctx) { return visitChildren(ctx); }
+  @Override public T visitFromOptions(EsqlBaseParser.FromOptionsContext ctx) { return visitChildren(ctx); }
   /**
    * {@inheritDoc}
    *
    * <p>The default implementation returns the result of calling
    * {@link #visitChildren} on {@code ctx}.</p>
    */
-  @Override public T visitDeprecated_metadata(EsqlBaseParser.Deprecated_metadataContext ctx) { return visitChildren(ctx); }
+  @Override public T visitConfigOption(EsqlBaseParser.ConfigOptionContext ctx) { return visitChildren(ctx); }
   /**
    * {@inheritDoc}
    *
    * <p>The default implementation returns the result of calling
    * {@link #visitChildren} on {@code ctx}.</p>
    */
-  @Override public T visitEvalCommand(EsqlBaseParser.EvalCommandContext ctx) { return visitChildren(ctx); }
+  @Override public T visitMetadata(EsqlBaseParser.MetadataContext ctx) { return visitChildren(ctx); }
   /**
    * {@inheritDoc}
    *
    * <p>The default implementation returns the result of calling
    * {@link #visitChildren} on {@code ctx}.</p>
    */
-  @Override public T visitStatsCommand(EsqlBaseParser.StatsCommandContext ctx) { return visitChildren(ctx); }
+  @Override public T visitMetadataOption(EsqlBaseParser.MetadataOptionContext ctx) { return visitChildren(ctx); }
   /**
    * {@inheritDoc}
    *
    * <p>The default implementation returns the result of calling
    * {@link #visitChildren} on {@code ctx}.</p>
    */
-  @Override public T visitInlinestatsCommand(EsqlBaseParser.InlinestatsCommandContext ctx) { return visitChildren(ctx); }
+  @Override public T visitDeprecated_metadata(EsqlBaseParser.Deprecated_metadataContext ctx) { return visitChildren(ctx); }
   /**
    * {@inheritDoc}
    *
    * <p>The default implementation returns the result of calling
    * {@link #visitChildren} on {@code ctx}.</p>
    */
-  @Override public T visitFromIdentifier(EsqlBaseParser.FromIdentifierContext ctx) { return visitChildren(ctx); }
+  @Override public T visitEvalCommand(EsqlBaseParser.EvalCommandContext ctx) { return visitChildren(ctx); }
+  /**
+   * {@inheritDoc}
+   *
+   * <p>The default implementation returns the result of calling
+   * {@link #visitChildren} on {@code ctx}.</p>
+   */
+  @Override public T visitStatsCommand(EsqlBaseParser.StatsCommandContext ctx) { return visitChildren(ctx); }
+  /**
+   * {@inheritDoc}
+   *
+   * <p>The default implementation returns the result of calling
+   * {@link #visitChildren} on {@code ctx}.</p>
+   */
+  @Override public T visitInlinestatsCommand(EsqlBaseParser.InlinestatsCommandContext ctx) { return visitChildren(ctx); }
   /**
    * {@inheritDoc}
    *

+ 30 - 10
x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/parser/EsqlBaseParserListener.java

@@ -311,6 +311,36 @@ public interface EsqlBaseParserListener extends ParseTreeListener {
    * @param ctx the parse tree
    */
   void exitFromCommand(EsqlBaseParser.FromCommandContext ctx);
+  /**
+   * Enter a parse tree produced by {@link EsqlBaseParser#fromIdentifier}.
+   * @param ctx the parse tree
+   */
+  void enterFromIdentifier(EsqlBaseParser.FromIdentifierContext ctx);
+  /**
+   * Exit a parse tree produced by {@link EsqlBaseParser#fromIdentifier}.
+   * @param ctx the parse tree
+   */
+  void exitFromIdentifier(EsqlBaseParser.FromIdentifierContext ctx);
+  /**
+   * Enter a parse tree produced by {@link EsqlBaseParser#fromOptions}.
+   * @param ctx the parse tree
+   */
+  void enterFromOptions(EsqlBaseParser.FromOptionsContext ctx);
+  /**
+   * Exit a parse tree produced by {@link EsqlBaseParser#fromOptions}.
+   * @param ctx the parse tree
+   */
+  void exitFromOptions(EsqlBaseParser.FromOptionsContext ctx);
+  /**
+   * Enter a parse tree produced by {@link EsqlBaseParser#configOption}.
+   * @param ctx the parse tree
+   */
+  void enterConfigOption(EsqlBaseParser.ConfigOptionContext ctx);
+  /**
+   * Exit a parse tree produced by {@link EsqlBaseParser#configOption}.
+   * @param ctx the parse tree
+   */
+  void exitConfigOption(EsqlBaseParser.ConfigOptionContext ctx);
   /**
    * Enter a parse tree produced by {@link EsqlBaseParser#metadata}.
    * @param ctx the parse tree
@@ -371,16 +401,6 @@ public interface EsqlBaseParserListener extends ParseTreeListener {
    * @param ctx the parse tree
    */
   void exitInlinestatsCommand(EsqlBaseParser.InlinestatsCommandContext ctx);
-  /**
-   * Enter a parse tree produced by {@link EsqlBaseParser#fromIdentifier}.
-   * @param ctx the parse tree
-   */
-  void enterFromIdentifier(EsqlBaseParser.FromIdentifierContext ctx);
-  /**
-   * Exit a parse tree produced by {@link EsqlBaseParser#fromIdentifier}.
-   * @param ctx the parse tree
-   */
-  void exitFromIdentifier(EsqlBaseParser.FromIdentifierContext ctx);
   /**
    * Enter a parse tree produced by {@link EsqlBaseParser#qualifiedName}.
    * @param ctx the parse tree

+ 18 - 6
x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/parser/EsqlBaseParserVisitor.java

@@ -189,6 +189,24 @@ public interface EsqlBaseParserVisitor<T> extends ParseTreeVisitor<T> {
    * @return the visitor result
    */
   T visitFromCommand(EsqlBaseParser.FromCommandContext ctx);
+  /**
+   * Visit a parse tree produced by {@link EsqlBaseParser#fromIdentifier}.
+   * @param ctx the parse tree
+   * @return the visitor result
+   */
+  T visitFromIdentifier(EsqlBaseParser.FromIdentifierContext ctx);
+  /**
+   * Visit a parse tree produced by {@link EsqlBaseParser#fromOptions}.
+   * @param ctx the parse tree
+   * @return the visitor result
+   */
+  T visitFromOptions(EsqlBaseParser.FromOptionsContext ctx);
+  /**
+   * Visit a parse tree produced by {@link EsqlBaseParser#configOption}.
+   * @param ctx the parse tree
+   * @return the visitor result
+   */
+  T visitConfigOption(EsqlBaseParser.ConfigOptionContext ctx);
   /**
    * Visit a parse tree produced by {@link EsqlBaseParser#metadata}.
    * @param ctx the parse tree
@@ -225,12 +243,6 @@ public interface EsqlBaseParserVisitor<T> extends ParseTreeVisitor<T> {
    * @return the visitor result
    */
   T visitInlinestatsCommand(EsqlBaseParser.InlinestatsCommandContext ctx);
-  /**
-   * Visit a parse tree produced by {@link EsqlBaseParser#fromIdentifier}.
-   * @param ctx the parse tree
-   * @return the visitor result
-   */
-  T visitFromIdentifier(EsqlBaseParser.FromIdentifierContext ctx);
   /**
    * Visit a parse tree produced by {@link EsqlBaseParser#qualifiedName}.
    * @param ctx the parse tree

+ 16 - 1
x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/parser/LogicalPlanBuilder.java

@@ -42,6 +42,7 @@ import org.elasticsearch.xpack.ql.expression.Order;
 import org.elasticsearch.xpack.ql.expression.ReferenceAttribute;
 import org.elasticsearch.xpack.ql.expression.UnresolvedAttribute;
 import org.elasticsearch.xpack.ql.expression.UnresolvedStar;
+import org.elasticsearch.xpack.ql.options.EsSourceOptions;
 import org.elasticsearch.xpack.ql.parser.ParserUtils;
 import org.elasticsearch.xpack.ql.plan.TableIdentifier;
 import org.elasticsearch.xpack.ql.plan.logical.Aggregate;
@@ -210,7 +211,21 @@ public class LogicalPlanBuilder extends ExpressionBuilder {
                 }
             }
         }
-        return new EsqlUnresolvedRelation(source, table, Arrays.asList(metadataMap.values().toArray(Attribute[]::new)));
+        EsSourceOptions esSourceOptions = new EsSourceOptions();
+        if (ctx.fromOptions() != null) {
+            for (var o : ctx.fromOptions().configOption()) {
+                var nameContext = o.string().get(0);
+                String name = visitString(nameContext).fold().toString();
+                String value = visitString(o.string().get(1)).fold().toString();
+                try {
+                    esSourceOptions.addOption(name, value);
+                } catch (IllegalArgumentException iae) {
+                    var cause = iae.getCause() != null ? ". " + iae.getCause().getMessage() : "";
+                    throw new ParsingException(iae, source(nameContext), "invalid options provided: " + iae.getMessage() + cause);
+                }
+            }
+        }
+        return new EsqlUnresolvedRelation(source, table, Arrays.asList(metadataMap.values().toArray(Attribute[]::new)), esSourceOptions);
     }
 
     @Override

+ 27 - 4
x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/plan/logical/EsqlUnresolvedRelation.java

@@ -8,32 +8,55 @@
 package org.elasticsearch.xpack.esql.plan.logical;
 
 import org.elasticsearch.xpack.ql.expression.Attribute;
+import org.elasticsearch.xpack.ql.options.EsSourceOptions;
 import org.elasticsearch.xpack.ql.plan.TableIdentifier;
 import org.elasticsearch.xpack.ql.plan.logical.UnresolvedRelation;
 import org.elasticsearch.xpack.ql.tree.NodeInfo;
 import org.elasticsearch.xpack.ql.tree.Source;
 
 import java.util.List;
+import java.util.Objects;
 
 public class EsqlUnresolvedRelation extends UnresolvedRelation {
 
     private final List<Attribute> metadataFields;
-
-    public EsqlUnresolvedRelation(Source source, TableIdentifier table, List<Attribute> metadataFields, String unresolvedMessage) {
+    private final EsSourceOptions esSourceOptions;
+
+    public EsqlUnresolvedRelation(
+        Source source,
+        TableIdentifier table,
+        List<Attribute> metadataFields,
+        EsSourceOptions esSourceOptions,
+        String unresolvedMessage
+    ) {
         super(source, table, "", false, unresolvedMessage);
         this.metadataFields = metadataFields;
+        Objects.requireNonNull(esSourceOptions);
+        this.esSourceOptions = esSourceOptions;
+    }
+
+    public EsqlUnresolvedRelation(Source source, TableIdentifier table, List<Attribute> metadataFields, String unresolvedMessage) {
+        this(source, table, metadataFields, EsSourceOptions.NO_OPTIONS, unresolvedMessage);
+    }
+
+    public EsqlUnresolvedRelation(Source source, TableIdentifier table, List<Attribute> metadataFields, EsSourceOptions esSourceOptions) {
+        this(source, table, metadataFields, esSourceOptions, null);
     }
 
     public EsqlUnresolvedRelation(Source source, TableIdentifier table, List<Attribute> metadataFields) {
-        this(source, table, metadataFields, null);
+        this(source, table, metadataFields, EsSourceOptions.NO_OPTIONS, null);
     }
 
     public List<Attribute> metadataFields() {
         return metadataFields;
     }
 
+    public EsSourceOptions esSourceOptions() {
+        return esSourceOptions;
+    }
+
     @Override
     protected NodeInfo<UnresolvedRelation> info() {
-        return NodeInfo.create(this, EsqlUnresolvedRelation::new, table(), metadataFields(), unresolvedMessage());
+        return NodeInfo.create(this, EsqlUnresolvedRelation::new, table(), metadataFields(), esSourceOptions(), unresolvedMessage());
     }
 }

+ 7 - 0
x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/planner/PlannerUtils.java

@@ -36,6 +36,7 @@ import org.elasticsearch.xpack.ql.expression.AttributeSet;
 import org.elasticsearch.xpack.ql.expression.Expression;
 import org.elasticsearch.xpack.ql.expression.FieldAttribute;
 import org.elasticsearch.xpack.ql.expression.predicate.Predicates;
+import org.elasticsearch.xpack.ql.options.EsSourceOptions;
 import org.elasticsearch.xpack.ql.plan.logical.EsRelation;
 import org.elasticsearch.xpack.ql.plan.logical.Filter;
 import org.elasticsearch.xpack.ql.tree.Source;
@@ -182,6 +183,12 @@ public class PlannerUtils {
         return Queries.combine(FILTER, asList(requestFilter));
     }
 
+    public static EsSourceOptions esSourceOptions(PhysicalPlan plan) {
+        Holder<EsSourceOptions> holder = new Holder<>();
+        plan.forEachUp(FragmentExec.class, f -> f.fragment().forEachUp(EsRelation.class, r -> holder.set(r.esSourceOptions())));
+        return holder.get();
+    }
+
     /**
      * Map QL's {@link DataType} to the compute engine's {@link ElementType}, for sortable types only.
      * This specifically excludes spatial data types, which are not themselves sortable.

+ 49 - 31
x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/plugin/ComputeService.java

@@ -70,6 +70,7 @@ import org.elasticsearch.xpack.esql.planner.EsPhysicalOperationProviders;
 import org.elasticsearch.xpack.esql.planner.LocalExecutionPlanner;
 import org.elasticsearch.xpack.esql.planner.PlannerUtils;
 import org.elasticsearch.xpack.esql.session.EsqlConfiguration;
+import org.elasticsearch.xpack.ql.options.EsSourceOptions;
 
 import java.util.ArrayList;
 import java.util.Collections;
@@ -293,35 +294,51 @@ public class ComputeService {
         // Since it's used only for @timestamp, it is relatively safe to assume it's not needed
         // but it would be better to have a proper impl.
         QueryBuilder requestFilter = PlannerUtils.requestFilter(dataNodePlan, x -> true);
-        lookupDataNodes(parentTask, clusterAlias, requestFilter, concreteIndices, originalIndices, ActionListener.wrap(dataNodes -> {
-            try (RefCountingRunnable refs = new RefCountingRunnable(() -> parentListener.onResponse(null))) {
-                // For each target node, first open a remote exchange on the remote node, then link the exchange source to
-                // the new remote exchange sink, and initialize the computation on the target node via data-node-request.
-                for (DataNode node : dataNodes) {
-                    var dataNodeListener = ActionListener.releaseAfter(dataNodeListenerSupplier.get(), refs.acquire());
-                    var queryPragmas = configuration.pragmas();
-                    ExchangeService.openExchange(
-                        transportService,
-                        node.connection,
-                        sessionId,
-                        queryPragmas.exchangeBufferSize(),
-                        esqlExecutor,
-                        dataNodeListener.delegateFailureAndWrap((delegate, unused) -> {
-                            var remoteSink = exchangeService.newRemoteSink(parentTask, sessionId, transportService, node.connection);
-                            exchangeSource.addRemoteSink(remoteSink, queryPragmas.concurrentExchangeClients());
-                            transportService.sendChildRequest(
-                                node.connection,
-                                DATA_ACTION_NAME,
-                                new DataNodeRequest(sessionId, configuration, clusterAlias, node.shardIds, node.aliasFilters, dataNodePlan),
-                                parentTask,
-                                TransportRequestOptions.EMPTY,
-                                new ActionListenerResponseHandler<>(delegate, ComputeResponse::new, esqlExecutor)
-                            );
-                        })
-                    );
+        EsSourceOptions esSourceOptions = PlannerUtils.esSourceOptions(dataNodePlan);
+        lookupDataNodes(
+            parentTask,
+            clusterAlias,
+            requestFilter,
+            concreteIndices,
+            originalIndices,
+            esSourceOptions,
+            ActionListener.wrap(dataNodes -> {
+                try (RefCountingRunnable refs = new RefCountingRunnable(() -> parentListener.onResponse(null))) {
+                    // For each target node, first open a remote exchange on the remote node, then link the exchange source to
+                    // the new remote exchange sink, and initialize the computation on the target node via data-node-request.
+                    for (DataNode node : dataNodes) {
+                        var dataNodeListener = ActionListener.releaseAfter(dataNodeListenerSupplier.get(), refs.acquire());
+                        var queryPragmas = configuration.pragmas();
+                        ExchangeService.openExchange(
+                            transportService,
+                            node.connection,
+                            sessionId,
+                            queryPragmas.exchangeBufferSize(),
+                            esqlExecutor,
+                            dataNodeListener.delegateFailureAndWrap((delegate, unused) -> {
+                                var remoteSink = exchangeService.newRemoteSink(parentTask, sessionId, transportService, node.connection);
+                                exchangeSource.addRemoteSink(remoteSink, queryPragmas.concurrentExchangeClients());
+                                transportService.sendChildRequest(
+                                    node.connection,
+                                    DATA_ACTION_NAME,
+                                    new DataNodeRequest(
+                                        sessionId,
+                                        configuration,
+                                        clusterAlias,
+                                        node.shardIds,
+                                        node.aliasFilters,
+                                        dataNodePlan
+                                    ),
+                                    parentTask,
+                                    TransportRequestOptions.EMPTY,
+                                    new ActionListenerResponseHandler<>(delegate, ComputeResponse::new, esqlExecutor)
+                                );
+                            })
+                        );
+                    }
                 }
-            }
-        }, parentListener::onFailure));
+            }, parentListener::onFailure)
+        );
     }
 
     private void startComputeOnRemoteClusters(
@@ -518,12 +535,13 @@ public class ComputeService {
      * Ideally, the search_shards API should be called before the field-caps API; however, this can lead
      * to a situation where the column structure (i.e., matched data types) differs depending on the query.
      */
-    void lookupDataNodes(
+    private void lookupDataNodes(
         Task parentTask,
         String clusterAlias,
         QueryBuilder filter,
         Set<String> concreteIndices,
         String[] originalIndices,
+        EsSourceOptions esSourceOptions,
         ActionListener<List<DataNode>> listener
     ) {
         ThreadContext threadContext = transportService.getThreadPool().getThreadContext();
@@ -567,10 +585,10 @@ public class ComputeService {
             threadContext.markAsSystemContext();
             SearchShardsRequest searchShardsRequest = new SearchShardsRequest(
                 originalIndices,
-                SearchRequest.DEFAULT_INDICES_OPTIONS,
+                esSourceOptions.indicesOptions(SearchRequest.DEFAULT_INDICES_OPTIONS),
                 filter,
                 null,
-                null,
+                esSourceOptions.preference(),
                 false,
                 clusterAlias
             );

+ 6 - 1
x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/plugin/EsqlFeatures.java

@@ -70,9 +70,14 @@ public class EsqlFeatures implements FeatureSpecification {
      */
     public static final NodeFeature ASYNC_QUERY = new NodeFeature("esql.async_query");
 
+    /**
+     * Does ESQL support FROM OPTIONS?
+     */
+    public static final NodeFeature FROM_OPTIONS = new NodeFeature("esql.from_options");
+
     @Override
     public Set<NodeFeature> getFeatures() {
-        return Set.of(ASYNC_QUERY, AGG_VALUES, MV_SORT, DISABLE_NULLABLE_OPTS, ST_X_Y);
+        return Set.of(ASYNC_QUERY, AGG_VALUES, MV_SORT, DISABLE_NULLABLE_OPTS, ST_X_Y, FROM_OPTIONS);
     }
 
     @Override

+ 10 - 5
x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/session/EsqlIndexResolver.java

@@ -11,13 +11,13 @@ import org.elasticsearch.action.fieldcaps.FieldCapabilitiesIndexResponse;
 import org.elasticsearch.action.fieldcaps.FieldCapabilitiesRequest;
 import org.elasticsearch.action.fieldcaps.FieldCapabilitiesResponse;
 import org.elasticsearch.action.fieldcaps.IndexFieldCapabilities;
+import org.elasticsearch.action.support.IndicesOptions;
 import org.elasticsearch.client.internal.Client;
 import org.elasticsearch.common.Strings;
 import org.elasticsearch.index.mapper.TimeSeriesParams;
 import org.elasticsearch.threadpool.ThreadPool;
 import org.elasticsearch.xpack.ql.index.EsIndex;
 import org.elasticsearch.xpack.ql.index.IndexResolution;
-import org.elasticsearch.xpack.ql.index.IndexResolver;
 import org.elasticsearch.xpack.ql.type.DataType;
 import org.elasticsearch.xpack.ql.type.DataTypeRegistry;
 import org.elasticsearch.xpack.ql.type.DateEsField;
@@ -55,9 +55,14 @@ public class EsqlIndexResolver {
     /**
      * Resolves a pattern to one (potentially compound meaning that spawns multiple indices) mapping.
      */
-    public void resolveAsMergedMapping(String indexWildcard, Set<String> fieldNames, ActionListener<IndexResolution> listener) {
+    public void resolveAsMergedMapping(
+        String indexWildcard,
+        Set<String> fieldNames,
+        IndicesOptions indicesOptions,
+        ActionListener<IndexResolution> listener
+    ) {
         client.fieldCaps(
-            createFieldCapsRequest(indexWildcard, fieldNames),
+            createFieldCapsRequest(indexWildcard, fieldNames, indicesOptions),
             listener.delegateFailureAndWrap((l, response) -> l.onResponse(mergedMappings(indexWildcard, response)))
         );
     }
@@ -239,13 +244,13 @@ public class EsqlIndexResolver {
         return new InvalidMappedField(name, "mapped as different metric types in indices: " + indices);
     }
 
-    private static FieldCapabilitiesRequest createFieldCapsRequest(String index, Set<String> fieldNames) {
+    private static FieldCapabilitiesRequest createFieldCapsRequest(String index, Set<String> fieldNames, IndicesOptions indicesOptions) {
         FieldCapabilitiesRequest req = new FieldCapabilitiesRequest().indices(Strings.commaDelimitedListToStringArray(index));
         req.fields(fieldNames.toArray(String[]::new));
         req.includeUnmapped(true);
         // lenient because we throw our own errors looking at the response e.g. if something was not resolved
         // also because this way security doesn't throw authorization exceptions but rather honors ignore_unavailable
-        req.indicesOptions(IndexResolver.FIELD_CAPS_INDICES_OPTIONS);
+        req.indicesOptions(indicesOptions);
         req.setMergeResults(false);
         return req;
     }

+ 7 - 3
x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/session/EsqlSession.java

@@ -9,6 +9,7 @@ package org.elasticsearch.xpack.esql.session;
 
 import org.elasticsearch.action.ActionListener;
 import org.elasticsearch.action.fieldcaps.FieldCapabilities;
+import org.elasticsearch.action.support.IndicesOptions;
 import org.elasticsearch.common.Strings;
 import org.elasticsearch.common.regex.Regex;
 import org.elasticsearch.core.Assertions;
@@ -207,11 +208,13 @@ public class EsqlSession {
             TableInfo tableInfo = preAnalysis.indices.get(0);
             TableIdentifier table = tableInfo.id();
             var fieldNames = fieldNames(parsed, enrichPolicyMatchFields);
+            assert preAnalysis.esSourceOptions.size() == 1 : "Unexpected source options count: " + preAnalysis.esSourceOptions.size();
+            var indicesOptions = preAnalysis.esSourceOptions.get(0).indicesOptions(IndexResolver.FIELD_CAPS_INDICES_OPTIONS);
 
             if (Assertions.ENABLED) {
-                resolveMergedMappingAgainstBothResolvers(table.index(), fieldNames, listener);
+                resolveMergedMappingAgainstBothResolvers(table.index(), fieldNames, indicesOptions, listener);
             } else {
-                esqlIndexResolver.resolveAsMergedMapping(table.index(), fieldNames, listener);
+                esqlIndexResolver.resolveAsMergedMapping(table.index(), fieldNames, indicesOptions, listener);
             }
         } else {
             try {
@@ -231,12 +234,13 @@ public class EsqlSession {
     private void resolveMergedMappingAgainstBothResolvers(
         String indexWildcard,
         Set<String> fieldNames,
+        IndicesOptions indicesOptions,
         ActionListener<IndexResolution> listener
     ) {
         indexResolver.resolveAsMergedMapping(indexWildcard, fieldNames, false, Map.of(), new ActionListener<>() {
             @Override
             public void onResponse(IndexResolution fromQl) {
-                esqlIndexResolver.resolveAsMergedMapping(indexWildcard, fieldNames, new ActionListener<>() {
+                esqlIndexResolver.resolveAsMergedMapping(indexWildcard, fieldNames, indicesOptions, new ActionListener<>() {
                     @Override
                     public void onResponse(IndexResolution fromEsql) {
                         if (fromQl.isValid() == false) {

+ 35 - 3
x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/io/stream/PlanNamedTypesTests.java

@@ -86,6 +86,7 @@ import org.elasticsearch.xpack.ql.expression.function.aggregate.AggregateFunctio
 import org.elasticsearch.xpack.ql.expression.predicate.operator.arithmetic.ArithmeticOperation;
 import org.elasticsearch.xpack.ql.expression.predicate.operator.comparison.BinaryComparison;
 import org.elasticsearch.xpack.ql.index.EsIndex;
+import org.elasticsearch.xpack.ql.options.EsSourceOptions;
 import org.elasticsearch.xpack.ql.plan.logical.Aggregate;
 import org.elasticsearch.xpack.ql.plan.logical.EsRelation;
 import org.elasticsearch.xpack.ql.plan.logical.Filter;
@@ -466,7 +467,7 @@ public class PlanNamedTypesTests extends ESTestCase {
     }
 
     public void testEsRelation() throws IOException {
-        var orig = new EsRelation(Source.EMPTY, randomEsIndex(), List.of(randomFieldAttribute()), randomBoolean());
+        var orig = new EsRelation(Source.EMPTY, randomEsIndex(), List.of(randomFieldAttribute()), randomEsSourceOptions(), randomBoolean());
         BytesStreamOutput bso = new BytesStreamOutput();
         PlanStreamOutput out = new PlanStreamOutput(bso, planNameRegistry);
         PlanNamedTypes.writeEsRelation(out, orig);
@@ -477,7 +478,7 @@ public class PlanNamedTypesTests extends ESTestCase {
     public void testEsqlProject() throws IOException {
         var orig = new EsqlProject(
             Source.EMPTY,
-            new EsRelation(Source.EMPTY, randomEsIndex(), List.of(randomFieldAttribute()), randomBoolean()),
+            new EsRelation(Source.EMPTY, randomEsIndex(), List.of(randomFieldAttribute()), randomEsSourceOptions(), randomBoolean()),
             List.of(randomFieldAttribute())
         );
         BytesStreamOutput bso = new BytesStreamOutput();
@@ -488,7 +489,13 @@ public class PlanNamedTypesTests extends ESTestCase {
     }
 
     public void testMvExpand() throws IOException {
-        var esRelation = new EsRelation(Source.EMPTY, randomEsIndex(), List.of(randomFieldAttribute()), randomBoolean());
+        var esRelation = new EsRelation(
+            Source.EMPTY,
+            randomEsIndex(),
+            List.of(randomFieldAttribute()),
+            randomEsSourceOptions(),
+            randomBoolean()
+        );
         var orig = new MvExpand(Source.EMPTY, esRelation, randomFieldAttribute(), randomFieldAttribute());
         BytesStreamOutput bso = new BytesStreamOutput();
         PlanStreamOutput out = new PlanStreamOutput(bso, planNameRegistry);
@@ -685,6 +692,31 @@ public class PlanNamedTypesTests extends ESTestCase {
         return Map.copyOf(map);
     }
 
+    static EsSourceOptions randomEsSourceOptions() {
+        EsSourceOptions eso = new EsSourceOptions();
+        if (randomBoolean()) {
+            eso.addOption("allow_no_indices", String.valueOf(randomBoolean()));
+        }
+        if (randomBoolean()) {
+            eso.addOption("ignore_unavailable", String.valueOf(randomBoolean()));
+        }
+        if (randomBoolean()) {
+            String idsList = String.join(",", randomList(1, 5, PlanNamedTypesTests::randomName));
+            eso.addOption(
+                "preference",
+                randomFrom(
+                    "_only_local",
+                    "_local",
+                    "_only_nodes:" + idsList,
+                    "_prefer_nodes:" + idsList,
+                    "_shards:" + idsList,
+                    randomName()
+                )
+            );
+        }
+        return eso;
+    }
+
     static List<DataType> DATA_TYPES = EsqlDataTypes.types().stream().toList();
 
     static DataType randomDataType() {

+ 103 - 1
x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/parser/StatementParserTests.java

@@ -7,6 +7,8 @@
 
 package org.elasticsearch.xpack.esql.parser;
 
+import org.elasticsearch.action.search.SearchRequest;
+import org.elasticsearch.common.Randomness;
 import org.elasticsearch.core.Tuple;
 import org.elasticsearch.test.ESTestCase;
 import org.elasticsearch.xpack.esql.evaluator.predicate.operator.comparison.Equals;
@@ -587,7 +589,7 @@ public class StatementParserTests extends ESTestCase {
         expectError("show info metadata _index", "line 1:11: token recognition error at: 'm'");
         expectError(
             "explain [from foo] metadata _index",
-            "line 1:20: mismatched input 'metadata' expecting {'|', ',', OPENING_BRACKET, ']', 'metadata'}"
+            "line 1:20: mismatched input 'metadata' expecting {'|', ',', OPENING_BRACKET, ']', 'options', 'metadata'}"
         );
     }
 
@@ -611,6 +613,106 @@ public class StatementParserTests extends ESTestCase {
         expectError("from test metadata emp_no", "line 1:21: unsupported metadata field [emp_no]");
     }
 
+    public void testFromOptionsUnknownName() {
+        expectError(FROM + " options \"foo\"=\"oof\",\"bar\"=\"rab\"", "line 1:20: invalid options provided: unknown option named [foo]");
+    }
+
+    public void testFromOptionsPartialInvalid() {
+        expectError(
+            FROM + " options \"allow_no_indices\"=\"true\",\"bar\"=\"rab\"",
+            "line 1:46: invalid options provided: unknown option named [bar]"
+        );
+    }
+
+    public void testFromOptionsInvalidIndicesOptionValue() {
+        expectError(
+            FROM + " options \"allow_no_indices\"=\"foo\"",
+            "line 1:20: invalid options provided: Could not convert [allow_no_indices] to boolean"
+        );
+    }
+
+    public void testFromOptionsEmptyIndicesOptionName() {
+        expectError(FROM + " options \"\"=\"true\"", "line 1:20: invalid options provided: unknown option named []");
+    }
+
+    public void testFromOptionsEmptyIndicesOptionValue() {
+        expectError(
+            FROM + " options \"allow_no_indices\"=\"\"",
+            "line 1:20: invalid options provided: Could not convert [allow_no_indices] to boolean. "
+                + "Failed to parse value [] as only [true] or [false] are allowed."
+        );
+        expectError(
+            FROM + " options \"ignore_unavailable\"=\"TRUE\"",
+            "line 1:20: invalid options provided: Could not convert [ignore_unavailable] to boolean. "
+                + "Failed to parse value [TRUE] as only [true] or [false] are allowed."
+        );
+        expectError(FROM + " options \"preference\"=\"\"", "line 1:20: invalid options provided: no Preference for []");
+    }
+
+    public void testFromOptionsSuggestedOptionName() {
+        expectError(
+            FROM + " options \"allow_indices\"=\"true\"",
+            "line 1:20: invalid options provided: unknown option named [allow_indices], did you mean [allow_no_indices]?"
+        );
+    }
+
+    public void testFromOptionsInvalidPreferValue() {
+        expectError(FROM + " options \"preference\"=\"_foo\"", "line 1:20: invalid options provided: no Preference for [_foo]");
+    }
+
+    public void testFromOptionsUnquotedName() {
+        expectError(FROM + " options allow_no_indices=\"oof\"", "line 1:19: mismatched input 'allow_no_indices' expecting QUOTED_STRING");
+    }
+
+    public void testFromOptionsUnquotedValue() {
+        expectError(FROM + " options \"allow_no_indices\"=oof", "line 1:38: mismatched input 'oof' expecting QUOTED_STRING");
+    }
+
+    public void testFromOptionsDuplicates() {
+        for (var name : List.of("allow_no_indices", "ignore_unavailable", "preference")) {
+            String options = '"' + name + "\"=\"false\"";
+            options += ',' + options;
+            expectError(FROM + " options " + options, "invalid options provided: option [" + name + "] has already been provided");
+        }
+    }
+
+    public void testFromOptionsValues() {
+        boolean allowNoIndices = randomBoolean();
+        boolean ignoreUnavailable = randomBoolean();
+        String idsList = String.join(",", randomList(1, 5, () -> randomAlphaOfLengthBetween(1, 25)));
+        String preference = randomFrom(
+            "_only_local",
+            "_local",
+            "_only_nodes:" + idsList,
+            "_prefer_nodes:" + idsList,
+            "_shards:" + idsList,
+            randomAlphaOfLengthBetween(1, 25)
+        );
+        List<String> options = new ArrayList<>(3);
+        options.add("\"allow_no_indices\"=\"" + allowNoIndices + "\"");
+        options.add("\"ignore_unavailable\"=\"" + ignoreUnavailable + "\"");
+        options.add("\"preference\"=\"" + preference + "\"");
+        Randomness.shuffle(options);
+        String optionsList = String.join(",", options);
+
+        var plan = statement(FROM + " OPTIONS " + optionsList);
+        var unresolved = as(plan, EsqlUnresolvedRelation.class);
+        assertNotNull(unresolved.esSourceOptions());
+        var indicesOptions = unresolved.esSourceOptions().indicesOptions(SearchRequest.DEFAULT_INDICES_OPTIONS);
+        assertThat(indicesOptions.allowNoIndices(), is(allowNoIndices));
+        assertThat(indicesOptions.ignoreUnavailable(), is(ignoreUnavailable));
+        assertThat(unresolved.esSourceOptions().preference(), is(preference));
+    }
+
+    public void testFromOptionsWithMetadata() {
+        var plan = statement(FROM + " OPTIONS \"preference\"=\"foo\" METADATA _id");
+        var unresolved = as(plan, EsqlUnresolvedRelation.class);
+        assertNotNull(unresolved.esSourceOptions());
+        assertThat(unresolved.esSourceOptions().preference(), is("foo"));
+        assertFalse(unresolved.metadataFields().isEmpty());
+        assertThat(unresolved.metadataFields().get(0).qualifiedName(), is("_id"));
+    }
+
     public void testDissectPattern() {
         LogicalPlan cmd = processingCommand("dissect a \"%{foo}\"");
         assertEquals(Dissect.class, cmd.getClass());

+ 135 - 0
x-pack/plugin/ql/src/main/java/org/elasticsearch/xpack/ql/options/EsSourceOptions.java

@@ -0,0 +1,135 @@
+/*
+ * 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.ql.options;
+
+import org.elasticsearch.action.support.IndicesOptions;
+import org.elasticsearch.cluster.routing.Preference;
+import org.elasticsearch.common.io.stream.StreamInput;
+import org.elasticsearch.common.io.stream.StreamOutput;
+import org.elasticsearch.core.Nullable;
+import org.elasticsearch.xpack.ql.util.StringUtils;
+
+import java.io.IOException;
+import java.util.List;
+import java.util.Objects;
+
+import static org.elasticsearch.action.support.IndicesOptions.ConcreteTargetOptions.IGNORE_UNAVAILABLE;
+import static org.elasticsearch.action.support.IndicesOptions.WildcardOptions.ALLOW_NO_INDICES;
+
+/*
+ * This provides a repository for index resolution and/or search-time configuration options.
+ * Such as: [search] preference and [search / index resolution] allow_no_indices, ignore_unavailable.
+ *
+ * Some of the options end up in a IndicesOptions instance. However, FieldCaps and Search APIs use IndicesOptions
+ * defaults having conflicting values. So this class will just validate and record the user-provided settings first, and then apply these
+ * onto a base (an API-specific default).
+ */
+public class EsSourceOptions {
+
+    private static final String OPTION_PREFERENCE = "preference";
+    public static final EsSourceOptions NO_OPTIONS = new EsSourceOptions();
+
+    @Nullable
+    private String allowNoIndices;
+    @Nullable
+    private String ignoreUnavailable;
+    @Nullable
+    private String preference;
+
+    public EsSourceOptions() {}
+
+    public EsSourceOptions(StreamInput in) throws IOException {
+        this.allowNoIndices = in.readOptionalString();
+        this.ignoreUnavailable = in.readOptionalString();
+        this.preference = in.readOptionalString();
+    }
+
+    public IndicesOptions indicesOptions(IndicesOptions base) {
+        if (allowNoIndices == null && ignoreUnavailable == null) {
+            return base;
+        }
+        var wildcardOptions = allowNoIndices != null
+            ? IndicesOptions.WildcardOptions.parseParameters(null, allowNoIndices, base.wildcardOptions())
+            : base.wildcardOptions();
+        var targetOptions = ignoreUnavailable != null
+            ? IndicesOptions.ConcreteTargetOptions.fromParameter(ignoreUnavailable, base.concreteTargetOptions())
+            : base.concreteTargetOptions();
+        return new IndicesOptions(targetOptions, wildcardOptions, base.gatekeeperOptions(), base.failureStoreOptions());
+    }
+
+    @Nullable
+    public String preference() {
+        return preference;
+    }
+
+    public void addOption(String name, String value) {
+        switch (name) {
+            case ALLOW_NO_INDICES -> {
+                requireUnset(name, allowNoIndices);
+                IndicesOptions.WildcardOptions.parseParameters(null, value, null);
+                allowNoIndices = value;
+            }
+            case IGNORE_UNAVAILABLE -> {
+                requireUnset(name, ignoreUnavailable);
+                IndicesOptions.ConcreteTargetOptions.fromParameter(value, null);
+                ignoreUnavailable = value;
+            }
+            case OPTION_PREFERENCE -> {
+                requireUnset(name, preference);
+                // The validation applies only for the predefined settings (i.e. prefixed by '_') or empty one (i.e. delegate handling
+                // of this case).
+                if (value.isEmpty() || value.charAt(0) == '_') {
+                    // Note: _search will neither fail, nor warn about something like `preference=_shards:0,1|_doesnotexist`
+                    Preference.parse(value);
+                }
+                preference = value;
+            }
+            default -> {
+                String message = "unknown option named [" + name + "]";
+                List<String> matches = StringUtils.findSimilar(name, List.of(ALLOW_NO_INDICES, IGNORE_UNAVAILABLE, OPTION_PREFERENCE));
+                if (matches.isEmpty() == false) {
+                    String suggestions = matches.size() == 1 ? "[" + matches.get(0) + "]" : "any of " + matches;
+                    message += ", did you mean " + suggestions + "?";
+                }
+                throw new IllegalArgumentException(message);
+            }
+        }
+    }
+
+    private static void requireUnset(String name, String value) {
+        if (value != null) {
+            throw new IllegalArgumentException("option [" + name + "] has already been provided");
+        }
+    }
+
+    public void writeEsSourceOptions(StreamOutput out) throws IOException {
+        out.writeOptionalString(allowNoIndices);
+        out.writeOptionalString(ignoreUnavailable);
+        out.writeOptionalString(preference);
+    }
+
+    @Override
+    public int hashCode() {
+        return Objects.hash(allowNoIndices, ignoreUnavailable, preference);
+    }
+
+    @Override
+    public boolean equals(Object obj) {
+        if (this == obj) {
+            return true;
+        }
+        if (obj == null || getClass() != obj.getClass()) {
+            return false;
+        }
+
+        EsSourceOptions other = (EsSourceOptions) obj;
+        return Objects.equals(allowNoIndices, other.allowNoIndices)
+            && Objects.equals(ignoreUnavailable, other.ignoreUnavailable)
+            && Objects.equals(preference, other.preference);
+    }
+}

+ 18 - 6
x-pack/plugin/ql/src/main/java/org/elasticsearch/xpack/ql/plan/logical/EsRelation.java

@@ -9,6 +9,7 @@ package org.elasticsearch.xpack.ql.plan.logical;
 import org.elasticsearch.xpack.ql.expression.Attribute;
 import org.elasticsearch.xpack.ql.expression.FieldAttribute;
 import org.elasticsearch.xpack.ql.index.EsIndex;
+import org.elasticsearch.xpack.ql.options.EsSourceOptions;
 import org.elasticsearch.xpack.ql.tree.NodeInfo;
 import org.elasticsearch.xpack.ql.tree.NodeUtils;
 import org.elasticsearch.xpack.ql.tree.Source;
@@ -24,26 +25,33 @@ public class EsRelation extends LeafPlan {
 
     private final EsIndex index;
     private final List<Attribute> attrs;
+    private final EsSourceOptions esSourceOptions;
     private final boolean frozen;
 
     public EsRelation(Source source, EsIndex index, boolean frozen) {
-        this(source, index, flatten(source, index.mapping()), frozen);
+        this(source, index, flatten(source, index.mapping()), EsSourceOptions.NO_OPTIONS, frozen);
     }
 
     public EsRelation(Source source, EsIndex index, List<Attribute> attributes) {
-        this(source, index, attributes, false);
+        this(source, index, attributes, EsSourceOptions.NO_OPTIONS, false);
     }
 
-    public EsRelation(Source source, EsIndex index, List<Attribute> attributes, boolean frozen) {
+    public EsRelation(Source source, EsIndex index, List<Attribute> attributes, EsSourceOptions esSourceOptions) {
+        this(source, index, attributes, esSourceOptions, false);
+    }
+
+    public EsRelation(Source source, EsIndex index, List<Attribute> attributes, EsSourceOptions esSourceOptions, boolean frozen) {
         super(source);
         this.index = index;
         this.attrs = attributes;
+        Objects.requireNonNull(esSourceOptions);
+        this.esSourceOptions = esSourceOptions;
         this.frozen = frozen;
     }
 
     @Override
     protected NodeInfo<EsRelation> info() {
-        return NodeInfo.create(this, EsRelation::new, index, attrs, frozen);
+        return NodeInfo.create(this, EsRelation::new, index, attrs, esSourceOptions, frozen);
     }
 
     private static List<Attribute> flatten(Source source, Map<String, EsField> mapping) {
@@ -73,6 +81,10 @@ public class EsRelation extends LeafPlan {
         return index;
     }
 
+    public EsSourceOptions esSourceOptions() {
+        return esSourceOptions;
+    }
+
     public boolean frozen() {
         return frozen;
     }
@@ -89,7 +101,7 @@ public class EsRelation extends LeafPlan {
 
     @Override
     public int hashCode() {
-        return Objects.hash(index, frozen);
+        return Objects.hash(index, esSourceOptions, frozen);
     }
 
     @Override
@@ -103,7 +115,7 @@ public class EsRelation extends LeafPlan {
         }
 
         EsRelation other = (EsRelation) obj;
-        return Objects.equals(index, other.index) && frozen == other.frozen;
+        return Objects.equals(index, other.index) && Objects.equals(esSourceOptions, other.esSourceOptions) && frozen == other.frozen;
     }
 
     @Override

この差分においてかなりの量のファイルが変更されているため、一部のファイルを表示していません