Răsfoiți Sursa

ESQL: Initial support for unmapped fields (#119886)

This PR adds initial support for unmapped fields, using the INSIST clause. For starters, this unmapped fields without a cast.
Note that the INSIST keyword is potentially a placeholder, as the method of defining an unmapped field might change in the future, e.g., use a special magic function. As this is currently under development, the actual syntax is INSIST_🐔.

First stage of #120072.

Specifically, the following features are implemented in this PR:

* Support for INSIST keyword without a cast. In particular, if the type being INSISTed upon is mapped to anything other than KEYWORD, it will result in an InvalidMappedField. There is no support for union type resolution on top of INSIST. Future PRs will handle these conflicts. There is support for multiple parameters, or INSIST on top of INSIST which is equivalent.
* Enforcing that INSIST must always be on top of a FROM or another INSIST. While this may change in the future, e.g., handling cases like `FROM foo | EVAL x = 1 | INSIST bar` will not be done in this PR, as it makes handling INSIST too complicated.
Gal Lalouche 8 luni în urmă
părinte
comite
d3ed999356
53 a modificat fișierele cu 3339 adăugiri și 1764 ștergeri
  1. 5 0
      docs/changelog/119886.yaml
  2. 2 1
      server/src/main/java/org/elasticsearch/index/mapper/BlockSourceReader.java
  3. 2 1
      x-pack/plugin/esql-core/src/main/java/org/elasticsearch/xpack/esql/core/type/EsField.java
  4. 18 4
      x-pack/plugin/esql-core/src/main/java/org/elasticsearch/xpack/esql/core/type/InvalidMappedField.java
  5. 30 0
      x-pack/plugin/esql-core/src/main/java/org/elasticsearch/xpack/esql/core/type/PotentiallyUnmappedKeywordEsField.java
  6. 6 0
      x-pack/plugin/esql/qa/server/mixed-cluster/src/javaRestTest/java/org/elasticsearch/xpack/esql/qa/mixed/MixedClusterEsqlSpecIT.java
  7. 8 0
      x-pack/plugin/esql/qa/server/multi-clusters/src/javaRestTest/java/org/elasticsearch/xpack/esql/ccq/MultiClusterSpecIT.java
  8. 4 2
      x-pack/plugin/esql/qa/server/multi-node/src/javaRestTest/java/org/elasticsearch/xpack/esql/qa/multi_node/EsqlSpecIT.java
  9. 5 0
      x-pack/plugin/esql/qa/server/single-node/src/javaRestTest/java/org/elasticsearch/xpack/esql/qa/single_node/EsqlSpecIT.java
  10. 13 2
      x-pack/plugin/esql/qa/server/src/main/java/org/elasticsearch/xpack/esql/qa/rest/EsqlSpecTestCase.java
  11. 1 1
      x-pack/plugin/esql/qa/server/src/main/java/org/elasticsearch/xpack/esql/qa/rest/generative/GenerativeRestTest.java
  12. 68 24
      x-pack/plugin/esql/qa/testFixtures/src/main/java/org/elasticsearch/xpack/esql/CsvTestsDataLoader.java
  13. 8 0
      x-pack/plugin/esql/qa/testFixtures/src/main/java/org/elasticsearch/xpack/esql/EsqlTestUtils.java
  14. 8 0
      x-pack/plugin/esql/qa/testFixtures/src/main/resources/data/partial_mapping_sample_data.csv
  15. 4 0
      x-pack/plugin/esql/qa/testFixtures/src/main/resources/mapping-no_mapping_sample_data.json
  16. 13 0
      x-pack/plugin/esql/qa/testFixtures/src/main/resources/mapping-partial_mapping_excluded_source_sample_data.json
  17. 11 0
      x-pack/plugin/esql/qa/testFixtures/src/main/resources/mapping-partial_mapping_no_source_sample_data.json
  18. 17 0
      x-pack/plugin/esql/qa/testFixtures/src/main/resources/mapping-partial_mapping_sample_data.json
  19. 582 0
      x-pack/plugin/esql/qa/testFixtures/src/main/resources/unmapped_fields.csv-spec
  20. 14 1
      x-pack/plugin/esql/src/main/antlr/EsqlBaseLexer.g4
  21. 166 162
      x-pack/plugin/esql/src/main/antlr/EsqlBaseLexer.tokens
  22. 5 0
      x-pack/plugin/esql/src/main/antlr/EsqlBaseParser.g4
  23. 166 162
      x-pack/plugin/esql/src/main/antlr/EsqlBaseParser.tokens
  24. 10 0
      x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/action/EsqlCapabilities.java
  25. 56 7
      x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/analysis/Analyzer.java
  26. 13 1
      x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/analysis/Verifier.java
  27. 20 3
      x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/index/EsIndex.java
  28. 2 1
      x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/optimizer/LogicalPlanOptimizer.java
  29. 43 0
      x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/optimizer/rules/logical/PropgateUnmappedFields.java
  30. 8 2
      x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/optimizer/rules/logical/local/ReplaceMissingFieldWithNull.java
  31. 15 0
      x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/parser/EsqlBaseLexer.interp
  32. 1182 1139
      x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/parser/EsqlBaseLexer.java
  33. 9 0
      x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/parser/EsqlBaseParser.interp
  34. 189 174
      x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/parser/EsqlBaseParser.java
  35. 12 0
      x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/parser/EsqlBaseParserBaseListener.java
  36. 7 0
      x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/parser/EsqlBaseParserBaseVisitor.java
  37. 10 0
      x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/parser/EsqlBaseParserListener.java
  38. 6 0
      x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/parser/EsqlBaseParserVisitor.java
  39. 17 0
      x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/parser/LogicalPlanBuilder.java
  40. 1 1
      x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/plan/PlanWritables.java
  41. 4 0
      x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/plan/logical/EsRelation.java
  42. 91 0
      x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/plan/logical/Insist.java
  43. 3 2
      x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/plan/physical/EnrichExec.java
  44. 45 21
      x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/planner/EsPhysicalOperationProviders.java
  45. 17 11
      x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/session/IndexResolver.java
  46. 21 4
      x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/CsvTests.java
  47. 178 1
      x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/analysis/AnalyzerTests.java
  48. 9 0
      x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/analysis/VerifierTests.java
  49. 68 6
      x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/optimizer/LogicalPlanOptimizerTests.java
  50. 6 0
      x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/parser/StatementParserTests.java
  51. 62 30
      x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/planner/TestPhysicalOperationProviders.java
  52. 78 0
      x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/session/IndexResolverFieldNamesTests.java
  53. 1 1
      x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/type/EsqlDataTypeRegistryTests.java

+ 5 - 0
docs/changelog/119886.yaml

@@ -0,0 +1,5 @@
+pr: 119886
+summary: Initial support for unmapped fields
+area: ES|QL
+type: feature
+issues: []

+ 2 - 1
server/src/main/java/org/elasticsearch/index/mapper/BlockSourceReader.java

@@ -22,6 +22,7 @@ import org.elasticsearch.search.fetch.StoredFieldsSpec;
 import java.io.IOException;
 import java.util.ArrayList;
 import java.util.List;
+import java.util.Objects;
 
 /**
  * Loads values from {@code _source}. This whole process is very slow and cast-tastic,
@@ -230,7 +231,7 @@ public abstract class BlockSourceReader implements BlockLoader.RowStrideReader {
 
         @Override
         protected void append(BlockLoader.Builder builder, Object v) {
-            ((BlockLoader.BytesRefBuilder) builder).appendBytesRef(toBytesRef(scratch, (String) v));
+            ((BlockLoader.BytesRefBuilder) builder).appendBytesRef(toBytesRef(scratch, Objects.toString(v)));
         }
 
         @Override

+ 2 - 1
x-pack/plugin/esql-core/src/main/java/org/elasticsearch/xpack/esql/core/type/EsField.java

@@ -27,11 +27,12 @@ import static org.elasticsearch.xpack.esql.core.util.PlanStreamOutput.writeCache
 public class EsField implements Writeable {
 
     private static Map<String, Writeable.Reader<? extends EsField>> readers = Map.ofEntries(
-        Map.entry("EsField", EsField::new),
         Map.entry("DateEsField", DateEsField::new),
+        Map.entry("EsField", EsField::new),
         Map.entry("InvalidMappedField", InvalidMappedField::new),
         Map.entry("KeywordEsField", KeywordEsField::new),
         Map.entry("MultiTypeEsField", MultiTypeEsField::new),
+        Map.entry("PotentiallyUnmappedKeywordEsField", PotentiallyUnmappedKeywordEsField::new),
         Map.entry("TextEsField", TextEsField::new),
         Map.entry("UnsupportedEsField", UnsupportedEsField::new)
     );

+ 18 - 4
x-pack/plugin/esql-core/src/main/java/org/elasticsearch/xpack/esql/core/type/InvalidMappedField.java

@@ -45,7 +45,7 @@ public class InvalidMappedField extends EsField {
      * Constructor supporting union types, used in ES|QL.
      */
     public InvalidMappedField(String name, Map<String, Set<String>> typesToIndices) {
-        this(name, makeErrorMessage(typesToIndices), new TreeMap<>(), typesToIndices);
+        this(name, makeErrorMessage(typesToIndices, false), new TreeMap<>(), typesToIndices);
     }
 
     private InvalidMappedField(String name, String errorMessage, Map<String, EsField> properties, Map<String, Set<String>> typesToIndices) {
@@ -107,12 +107,21 @@ public class InvalidMappedField extends EsField {
         return typesToIndices;
     }
 
-    private static String makeErrorMessage(Map<String, Set<String>> typesToIndices) {
+    public static String makeErrorsMessageIncludingInsistKeyword(Map<String, Set<String>> typesToIndices) {
+        return makeErrorMessage(typesToIndices, true);
+    }
+
+    private static String makeErrorMessage(Map<String, Set<String>> typesToIndices, boolean includeInsistKeyword) {
         StringBuilder errorMessage = new StringBuilder();
+        var isInsistKeywordOnlyKeyword = includeInsistKeyword && typesToIndices.containsKey(DataType.KEYWORD.typeName()) == false;
         errorMessage.append("mapped as [");
-        errorMessage.append(typesToIndices.size());
+        errorMessage.append(typesToIndices.size() + (isInsistKeywordOnlyKeyword ? 1 : 0));
         errorMessage.append("] incompatible types: ");
         boolean first = true;
+        if (isInsistKeywordOnlyKeyword) {
+            first = false;
+            errorMessage.append("[keyword] enforced by INSIST command");
+        }
         for (Map.Entry<String, Set<String>> e : typesToIndices.entrySet()) {
             if (first) {
                 first = false;
@@ -121,7 +130,12 @@ public class InvalidMappedField extends EsField {
             }
             errorMessage.append("[");
             errorMessage.append(e.getKey());
-            errorMessage.append("] in ");
+            errorMessage.append("] ");
+            if (e.getKey().equals(DataType.KEYWORD.typeName()) && includeInsistKeyword) {
+                errorMessage.append("enforced by INSIST command and in ");
+            } else {
+                errorMessage.append("in ");
+            }
             if (e.getValue().size() <= 3) {
                 errorMessage.append(e.getValue());
             } else {

+ 30 - 0
x-pack/plugin/esql-core/src/main/java/org/elasticsearch/xpack/esql/core/type/PotentiallyUnmappedKeywordEsField.java

@@ -0,0 +1,30 @@
+/*
+ * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
+ * or more contributor license agreements. Licensed under the Elastic License
+ * 2.0; you may not use this file except in compliance with the Elastic License
+ * 2.0.
+ */
+package org.elasticsearch.xpack.esql.core.type;
+
+import org.elasticsearch.common.io.stream.StreamInput;
+
+import java.io.IOException;
+
+/**
+ * This class is used as a marker for fields that may be unmapped, where an unmapped field is a field which exists in the _source but is not
+ * mapped in the index. Note that this field may be mapped for some indices, but is unmapped in at least one of them.
+ * For indices where the field is unmapped, we will try to load them directly from _source.
+ */
+public class PotentiallyUnmappedKeywordEsField extends KeywordEsField {
+    public PotentiallyUnmappedKeywordEsField(String name) {
+        super(name);
+    }
+
+    public PotentiallyUnmappedKeywordEsField(StreamInput in) throws IOException {
+        super(in);
+    }
+
+    public String getWriteableName() {
+        return "PotentiallyUnmappedKeywordEsField";
+    }
+}

+ 6 - 0
x-pack/plugin/esql/qa/server/mixed-cluster/src/javaRestTest/java/org/elasticsearch/xpack/esql/qa/mixed/MixedClusterEsqlSpecIT.java

@@ -21,6 +21,7 @@ import java.util.List;
 
 import static org.elasticsearch.xpack.esql.CsvTestUtils.isEnabled;
 import static org.elasticsearch.xpack.esql.action.EsqlCapabilities.Cap.JOIN_LOOKUP_V12;
+import static org.elasticsearch.xpack.esql.action.EsqlCapabilities.Cap.SOURCE_FIELD_MAPPING;
 
 public class MixedClusterEsqlSpecIT extends EsqlSpecTestCase {
     @ClassRule
@@ -90,6 +91,11 @@ public class MixedClusterEsqlSpecIT extends EsqlSpecTestCase {
         return hasCapabilities(List.of(JOIN_LOOKUP_V12.capabilityName()));
     }
 
+    @Override
+    protected boolean supportsSourceFieldMapping() throws IOException {
+        return hasCapabilities(List.of(SOURCE_FIELD_MAPPING.capabilityName()));
+    }
+
     @Override
     protected boolean deduplicateExactWarnings() {
         /*

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

@@ -52,6 +52,7 @@ import static org.elasticsearch.xpack.esql.action.EsqlCapabilities.Cap.INLINESTA
 import static org.elasticsearch.xpack.esql.action.EsqlCapabilities.Cap.JOIN_LOOKUP_V12;
 import static org.elasticsearch.xpack.esql.action.EsqlCapabilities.Cap.JOIN_PLANNING_V1;
 import static org.elasticsearch.xpack.esql.action.EsqlCapabilities.Cap.METADATA_FIELDS_REMOTE_TEST;
+import static org.elasticsearch.xpack.esql.action.EsqlCapabilities.Cap.UNMAPPED_FIELDS;
 import static org.elasticsearch.xpack.esql.qa.rest.EsqlSpecTestCase.Mode.SYNC;
 import static org.mockito.ArgumentMatchers.any;
 import static org.mockito.Mockito.doAnswer;
@@ -127,6 +128,8 @@ public class MultiClusterSpecIT extends EsqlSpecTestCase {
         assumeFalse("INLINESTATS not yet supported in CCS", testCase.requiredCapabilities.contains(JOIN_PLANNING_V1.capabilityName()));
         assumeFalse("INLINESTATS not yet supported in CCS", testCase.requiredCapabilities.contains(INLINESTATS_V3.capabilityName()));
         assumeFalse("LOOKUP JOIN not yet supported in CCS", testCase.requiredCapabilities.contains(JOIN_LOOKUP_V12.capabilityName()));
+        // Unmapped fields require a coorect capability response from every cluster, which isn't currently implemented.
+        assumeFalse("UNMAPPED FIELDS not yet supported in CCS", testCase.requiredCapabilities.contains(UNMAPPED_FIELDS.capabilityName()));
     }
 
     @Override
@@ -294,4 +297,9 @@ public class MultiClusterSpecIT extends EsqlSpecTestCase {
         // return hasCapabilities(List.of(JOIN_LOOKUP_V10.capabilityName()));
         return false;
     }
+
+    @Override
+    protected boolean supportsSourceFieldMapping() {
+        return false;
+    }
 }

+ 4 - 2
x-pack/plugin/esql/qa/server/multi-node/src/javaRestTest/java/org/elasticsearch/xpack/esql/qa/multi_node/EsqlSpecIT.java

@@ -12,6 +12,8 @@ import org.elasticsearch.xpack.esql.CsvSpecReader.CsvTestCase;
 import org.elasticsearch.xpack.esql.qa.rest.EsqlSpecTestCase;
 import org.junit.ClassRule;
 
+import java.io.IOException;
+
 public class EsqlSpecIT extends EsqlSpecTestCase {
     @ClassRule
     public static ElasticsearchCluster cluster = Clusters.testCluster(spec -> spec.plugin("inference-service-test"));
@@ -39,7 +41,7 @@ public class EsqlSpecIT extends EsqlSpecTestCase {
     }
 
     @Override
-    protected boolean shouldSkipTestsWithSemanticTextFields() {
-        return true;
+    protected boolean supportsSourceFieldMapping() throws IOException {
+        return false;
     }
 }

+ 5 - 0
x-pack/plugin/esql/qa/server/single-node/src/javaRestTest/java/org/elasticsearch/xpack/esql/qa/single_node/EsqlSpecIT.java

@@ -47,4 +47,9 @@ public class EsqlSpecIT extends EsqlSpecTestCase {
     protected boolean shouldSkipTestsWithSemanticTextFields() {
         return cluster.getNumNodes() > 1;
     }
+
+    @Override
+    protected boolean supportsSourceFieldMapping() {
+        return cluster.getNumNodes() == 1;
+    }
 }

+ 13 - 2
x-pack/plugin/esql/qa/server/src/main/java/org/elasticsearch/xpack/esql/qa/rest/EsqlSpecTestCase.java

@@ -71,6 +71,7 @@ import static org.elasticsearch.xpack.esql.CsvTestsDataLoader.deleteInferenceEnd
 import static org.elasticsearch.xpack.esql.CsvTestsDataLoader.loadDataSetIntoEs;
 import static org.elasticsearch.xpack.esql.EsqlTestUtils.classpathResources;
 import static org.elasticsearch.xpack.esql.action.EsqlCapabilities.Cap.SEMANTIC_TEXT_TYPE;
+import static org.elasticsearch.xpack.esql.action.EsqlCapabilities.Cap.SOURCE_FIELD_MAPPING;
 
 // This test can run very long in serverless configurations
 @TimeoutSuite(millis = 30 * TimeUnits.MINUTE)
@@ -135,8 +136,11 @@ public abstract class EsqlSpecTestCase extends ESRestTestCase {
         if (supportsInferenceTestService() && clusterHasInferenceEndpoint(client()) == false) {
             createInferenceEndpoint(client());
         }
-        if (indexExists(availableDatasetsForEs(client(), supportsIndexModeLookup()).iterator().next().indexName()) == false) {
-            loadDataSetIntoEs(client(), supportsIndexModeLookup());
+
+        boolean supportsLookup = supportsIndexModeLookup();
+        boolean supportsSourceMapping = supportsSourceFieldMapping();
+        if (indexExists(availableDatasetsForEs(client(), supportsLookup, supportsSourceMapping).iterator().next().indexName()) == false) {
+            loadDataSetIntoEs(client(), supportsLookup, supportsSourceMapping);
         }
     }
 
@@ -183,6 +187,9 @@ public abstract class EsqlSpecTestCase extends ESRestTestCase {
         if (shouldSkipTestsWithSemanticTextFields()) {
             assumeFalse("semantic_text tests are muted", testCase.requiredCapabilities.contains(SEMANTIC_TEXT_TYPE.capabilityName()));
         }
+        if (supportsSourceFieldMapping() == false) {
+            assumeFalse("source mapping tests are muted", testCase.requiredCapabilities.contains(SOURCE_FIELD_MAPPING.capabilityName()));
+        }
     }
 
     protected static void checkCapabilities(RestClient client, TestFeatureService testFeatureService, String testName, CsvTestCase testCase)
@@ -240,6 +247,10 @@ public abstract class EsqlSpecTestCase extends ESRestTestCase {
         return true;
     }
 
+    protected boolean supportsSourceFieldMapping() throws IOException {
+        return true;
+    }
+
     protected final void doTest() throws Throwable {
         RequestObjectBuilder builder = new RequestObjectBuilder(randomFrom(XContentType.values()));
 

+ 1 - 1
x-pack/plugin/esql/qa/server/src/main/java/org/elasticsearch/xpack/esql/qa/rest/generative/GenerativeRestTest.java

@@ -57,7 +57,7 @@ public abstract class GenerativeRestTest extends ESRestTestCase {
     @Before
     public void setup() throws IOException {
         if (indexExists(CSV_DATASET_MAP.keySet().iterator().next()) == false) {
-            loadDataSetIntoEs(client(), true);
+            loadDataSetIntoEs(client(), true, true);
         }
     }
 

+ 68 - 24
x-pack/plugin/esql/qa/testFixtures/src/main/java/org/elasticsearch/xpack/esql/CsvTestsDataLoader.java

@@ -42,6 +42,8 @@ import java.util.HashSet;
 import java.util.List;
 import java.util.Map;
 import java.util.Set;
+import java.util.stream.Collectors;
+import java.util.stream.Stream;
 
 import static org.elasticsearch.common.logging.LoggerMessageFormat.format;
 import static org.elasticsearch.xpack.esql.CsvTestUtils.COMMA_ESCAPING_REGEX;
@@ -83,6 +85,22 @@ public class CsvTestsDataLoader {
         .withData("sample_data_ts_nanos.csv")
         .withTypeMapping(Map.of("@timestamp", "date_nanos"));
     private static final TestDataset MISSING_IP_SAMPLE_DATA = new TestDataset("missing_ip_sample_data");
+    private static final TestDataset SAMPLE_DATA_PARTIAL_MAPPING = new TestDataset("partial_mapping_sample_data");
+    private static final TestDataset SAMPLE_DATA_NO_MAPPING = new TestDataset(
+        "no_mapping_sample_data",
+        "mapping-no_mapping_sample_data.json",
+        "partial_mapping_sample_data.csv"
+    ).withTypeMapping(Stream.of("timestamp", "client_ip", "event_duration").collect(Collectors.toMap(k -> k, k -> "keyword")));
+    private static final TestDataset SAMPLE_DATA_PARTIAL_MAPPING_NO_SOURCE = new TestDataset(
+        "partial_mapping_no_source_sample_data",
+        "mapping-partial_mapping_no_source_sample_data.json",
+        "partial_mapping_sample_data.csv"
+    ).withSetting("source_parameters-settings.json");
+    private static final TestDataset SAMPLE_DATA_PARTIAL_MAPPING_EXCLUDED_SOURCE = new TestDataset(
+        "partial_mapping_excluded_source_sample_data",
+        "mapping-partial_mapping_excluded_source_sample_data.json",
+        "partial_mapping_sample_data.csv"
+    ).withSetting("source_parameters-settings.json");
     private static final TestDataset CLIENT_IPS = new TestDataset("clientips");
     private static final TestDataset CLIENT_IPS_LOOKUP = CLIENT_IPS.withIndex("clientips_lookup")
         .withSetting("clientips_lookup-settings.json");
@@ -128,6 +146,10 @@ public class CsvTestsDataLoader {
         Map.entry(LANGUAGES_NESTED_FIELDS.indexName, LANGUAGES_NESTED_FIELDS),
         Map.entry(UL_LOGS.indexName, UL_LOGS),
         Map.entry(SAMPLE_DATA.indexName, SAMPLE_DATA),
+        Map.entry(SAMPLE_DATA_PARTIAL_MAPPING.indexName, SAMPLE_DATA_PARTIAL_MAPPING),
+        Map.entry(SAMPLE_DATA_NO_MAPPING.indexName, SAMPLE_DATA_NO_MAPPING),
+        Map.entry(SAMPLE_DATA_PARTIAL_MAPPING_NO_SOURCE.indexName, SAMPLE_DATA_PARTIAL_MAPPING_NO_SOURCE),
+        Map.entry(SAMPLE_DATA_PARTIAL_MAPPING_EXCLUDED_SOURCE.indexName, SAMPLE_DATA_PARTIAL_MAPPING_EXCLUDED_SOURCE),
         Map.entry(MV_SAMPLE_DATA.indexName, MV_SAMPLE_DATA),
         Map.entry(ALERTS.indexName, ALERTS),
         Map.entry(SAMPLE_DATA_STR.indexName, SAMPLE_DATA_STR),
@@ -248,7 +270,7 @@ public class CsvTestsDataLoader {
         }
 
         try (RestClient client = builder.build()) {
-            loadDataSetIntoEs(client, true, (restClient, indexName, indexMapping, indexSettings) -> {
+            loadDataSetIntoEs(client, true, true, (restClient, indexName, indexMapping, indexSettings) -> {
                 // don't use ESRestTestCase methods here or, if you do, test running the main method before making the change
                 StringBuilder jsonBody = new StringBuilder("{");
                 if (indexSettings != null && indexSettings.isEmpty() == false) {
@@ -267,14 +289,19 @@ public class CsvTestsDataLoader {
         }
     }
 
-    public static Set<TestDataset> availableDatasetsForEs(RestClient client, boolean supportsIndexModeLookup) throws IOException {
+    public static Set<TestDataset> availableDatasetsForEs(
+        RestClient client,
+        boolean supportsIndexModeLookup,
+        boolean supportsSourceFieldMapping
+    ) throws IOException {
         boolean inferenceEnabled = clusterHasInferenceEndpoint(client);
 
         Set<TestDataset> testDataSets = new HashSet<>();
 
         for (TestDataset dataset : CSV_DATASET_MAP.values()) {
             if ((inferenceEnabled || dataset.requiresInferenceEndpoint == false)
-                && (supportsIndexModeLookup || isLookupDataset(dataset) == false)) {
+                && (supportsIndexModeLookup || isLookupDataset(dataset) == false)
+                && (supportsSourceFieldMapping || isSourceMappingDataset(dataset) == false)) {
                 testDataSets.add(dataset);
             }
         }
@@ -282,24 +309,44 @@ public class CsvTestsDataLoader {
         return testDataSets;
     }
 
-    public static boolean isLookupDataset(TestDataset dataset) throws IOException {
+    private static boolean isLookupDataset(TestDataset dataset) throws IOException {
         Settings settings = dataset.readSettingsFile();
         String mode = settings.get("index.mode");
         return (mode != null && mode.equalsIgnoreCase("lookup"));
     }
 
-    public static void loadDataSetIntoEs(RestClient client, boolean supportsIndexModeLookup) throws IOException {
-        loadDataSetIntoEs(client, supportsIndexModeLookup, (restClient, indexName, indexMapping, indexSettings) -> {
-            ESRestTestCase.createIndex(restClient, indexName, indexSettings, indexMapping, null);
-        });
+    private static boolean isSourceMappingDataset(TestDataset dataset) throws IOException {
+        if (dataset.mappingFileName() == null) {
+            return true;
+        }
+        String mappingJsonText = readTextFile(getResource("/" + dataset.mappingFileName()));
+        JsonNode mappingNode = new ObjectMapper().readTree(mappingJsonText);
+        // BWC tests don't support _source field mappings, so don't load those datasets.
+        return mappingNode.get("_source") != null;
     }
 
-    private static void loadDataSetIntoEs(RestClient client, boolean supportsIndexModeLookup, IndexCreator indexCreator)
+    public static void loadDataSetIntoEs(RestClient client, boolean supportsIndexModeLookup, boolean supportsSourceFieldMapping)
         throws IOException {
+        loadDataSetIntoEs(
+            client,
+            supportsIndexModeLookup,
+            supportsSourceFieldMapping,
+            (restClient, indexName, indexMapping, indexSettings) -> {
+                ESRestTestCase.createIndex(restClient, indexName, indexSettings, indexMapping, null);
+            }
+        );
+    }
+
+    private static void loadDataSetIntoEs(
+        RestClient client,
+        boolean supportsIndexModeLookup,
+        boolean supportsSourceFieldMapping,
+        IndexCreator indexCreator
+    ) throws IOException {
         Logger logger = LogManager.getLogger(CsvTestsDataLoader.class);
 
         Set<String> loadedDatasets = new HashSet<>();
-        for (var dataset : availableDatasetsForEs(client, supportsIndexModeLookup)) {
+        for (var dataset : availableDatasetsForEs(client, supportsIndexModeLookup, supportsSourceFieldMapping)) {
             load(client, dataset, logger, indexCreator);
             loadedDatasets.add(dataset.indexName);
         }
@@ -351,10 +398,7 @@ public class CsvTestsDataLoader {
     }
 
     private static void loadEnrichPolicy(RestClient client, String policyName, String policyFileName, Logger logger) throws IOException {
-        URL policyMapping = CsvTestsDataLoader.class.getResource("/" + policyFileName);
-        if (policyMapping == null) {
-            throw new IllegalArgumentException("Cannot find resource " + policyFileName);
-        }
+        URL policyMapping = getResource("/" + policyFileName);
         String entity = readTextFile(policyMapping);
         Request request = new Request("PUT", "/_enrich/policy/" + policyName);
         request.setJsonEntity(entity);
@@ -364,17 +408,17 @@ public class CsvTestsDataLoader {
         client.performRequest(request);
     }
 
-    private static void load(RestClient client, TestDataset dataset, Logger logger, IndexCreator indexCreator) throws IOException {
-        final String mappingName = "/" + dataset.mappingFileName;
-        URL mapping = CsvTestsDataLoader.class.getResource(mappingName);
-        if (mapping == null) {
-            throw new IllegalArgumentException("Cannot find resource " + mappingName);
-        }
-        final String dataName = "/data/" + dataset.dataFileName;
-        URL data = CsvTestsDataLoader.class.getResource(dataName);
-        if (data == null) {
-            throw new IllegalArgumentException("Cannot find resource " + dataName);
+    private static URL getResource(String name) {
+        URL result = CsvTestsDataLoader.class.getResource(name);
+        if (result == null) {
+            throw new IllegalArgumentException("Cannot find resource " + name);
         }
+        return result;
+    }
+
+    private static void load(RestClient client, TestDataset dataset, Logger logger, IndexCreator indexCreator) throws IOException {
+        URL mapping = getResource("/" + dataset.mappingFileName);
+        URL data = getResource("/data/" + dataset.dataFileName);
 
         Settings indexSettings = dataset.readSettingsFile();
         indexCreator.createIndex(client, dataset.indexName, readMappingFile(mapping, dataset.typeMapping), indexSettings);

+ 8 - 0
x-pack/plugin/esql/qa/testFixtures/src/main/java/org/elasticsearch/xpack/esql/EsqlTestUtils.java

@@ -100,6 +100,7 @@ import java.nio.file.attribute.BasicFileAttributes;
 import java.time.Duration;
 import java.time.Period;
 import java.util.ArrayList;
+import java.util.Collection;
 import java.util.EnumSet;
 import java.util.HashMap;
 import java.util.HashSet;
@@ -141,6 +142,8 @@ import static org.elasticsearch.xpack.esql.core.util.SpatialCoordinateTypes.GEO;
 import static org.elasticsearch.xpack.esql.parser.ParserUtils.ParamClassification.IDENTIFIER;
 import static org.elasticsearch.xpack.esql.parser.ParserUtils.ParamClassification.PATTERN;
 import static org.elasticsearch.xpack.esql.parser.ParserUtils.ParamClassification.VALUE;
+import static org.hamcrest.MatcherAssert.assertThat;
+import static org.hamcrest.Matchers.hasSize;
 import static org.hamcrest.Matchers.instanceOf;
 import static org.junit.Assert.assertNotNull;
 import static org.junit.Assert.assertNull;
@@ -841,4 +844,9 @@ public final class EsqlTestUtils {
         ExceptionsHelper.unwrapCausesAndSuppressed(e, t -> t instanceof RemoteTransportException)
             .ifPresent(transportFailure -> assertNull("remote transport exception must be unwrapped", transportFailure.getCause()));
     }
+
+    public static <T> T singleValue(Collection<T> collection) {
+        assertThat(collection, hasSize(1));
+        return collection.iterator().next();
+    }
 }

+ 8 - 0
x-pack/plugin/esql/qa/testFixtures/src/main/resources/data/partial_mapping_sample_data.csv

@@ -0,0 +1,8 @@
+@timestamp:date,client_ip:ip,event_duration:long,message:keyword,unmapped_message:keyword,unmapped_event_duration:keyword,unmapped.nested:keyword
+2024-10-23T13:55:01.543Z,173.21.3.15,1756466,Connected to 10.1.0.1!,Disconnected from 10.1.0.1,1756468,a
+2024-10-23T13:53:55.832Z,173.21.3.15,5033754,Connection error?,Disconnection error,5033756,b
+2024-10-23T13:52:55.015Z,173.21.3.15,8268152,Connection error?,Disconnection error,8268154,c
+2024-10-23T13:51:54.732Z,173.21.3.15,725447,Connection error?,Disconnection error,725449,d
+2024-10-23T13:33:34.937Z,173.21.0.5,1232381,42,43,1232383,e
+2024-10-23T12:27:28.948Z,173.21.2.113,2764888,Connected to 10.1.0.2!,Disconnected from 10.1.0.2,2764890,f
+2024-10-23T12:15:03.360Z,173.21.2.162,3450232,Connected to 10.1.0.3!,Disconnected from 10.1.0.3,3450234,g

+ 4 - 0
x-pack/plugin/esql/qa/testFixtures/src/main/resources/mapping-no_mapping_sample_data.json

@@ -0,0 +1,4 @@
+{
+    "dynamic": "false",
+    "properties": {}
+}

+ 13 - 0
x-pack/plugin/esql/qa/testFixtures/src/main/resources/mapping-partial_mapping_excluded_source_sample_data.json

@@ -0,0 +1,13 @@
+{
+    "dynamic": "false",
+    "properties": {
+        "@timestamp": {
+            "type": "date"
+        }
+    },
+    "_source": {
+        "excludes": [
+            "message"
+        ]
+    }
+}

+ 11 - 0
x-pack/plugin/esql/qa/testFixtures/src/main/resources/mapping-partial_mapping_no_source_sample_data.json

@@ -0,0 +1,11 @@
+{
+    "dynamic": "false",
+    "properties": {
+      "@timestamp": {
+        "type": "date"
+      }
+    },
+    "_source": {
+        "enabled": false
+    }
+}

+ 17 - 0
x-pack/plugin/esql/qa/testFixtures/src/main/resources/mapping-partial_mapping_sample_data.json

@@ -0,0 +1,17 @@
+{
+    "dynamic": "false",
+    "properties": {
+        "@timestamp": {
+            "type": "date"
+        },
+        "client_ip": {
+            "type": "ip"
+        },
+        "event_duration": {
+            "type": "long"
+        },
+        "message": {
+            "type": "keyword"
+        }
+    }
+}

+ 582 - 0
x-pack/plugin/esql/qa/testFixtures/src/main/resources/unmapped_fields.csv-spec

@@ -0,0 +1,582 @@
+######################
+# Single index tests #
+######################
+
+// This one is more of a test of the configuration than the unmapped fields feature.
+doesNotLoadUnmappedFields
+required_capability: unmapped_fields
+FROM partial_mapping_sample_data
+| SORT @timestamp DESC
+;
+
+@timestamp:datetime      | client_ip:ip | event_duration:long | message:keyword
+2024-10-23T13:55:01.543Z | 173.21.3.15  | 1756466             | Connected to 10.1.0.1!
+2024-10-23T13:53:55.832Z | 173.21.3.15  | 5033754             | Connection error?
+2024-10-23T13:52:55.015Z | 173.21.3.15  | 8268152             | Connection error?
+2024-10-23T13:51:54.732Z | 173.21.3.15  | 725447              | Connection error?
+2024-10-23T13:33:34.937Z | 173.21.0.5   | 1232381             | 42
+2024-10-23T12:27:28.948Z | 173.21.2.113 | 2764888             | Connected to 10.1.0.2!
+2024-10-23T12:15:03.360Z | 173.21.2.162 | 3450232             | Connected to 10.1.0.3!
+;
+
+fieldIsMappedToNonKeywordSingleIndex
+required_capability: unmapped_fields
+FROM partial_mapping_sample_data
+| INSIST_🐔 client_ip
+| KEEP @timestamp, client_ip
+| SORT @timestamp DESC
+;
+
+@timestamp:date          | client_ip:ip
+2024-10-23T13:55:01.543Z | 173.21.3.15
+2024-10-23T13:53:55.832Z | 173.21.3.15
+2024-10-23T13:52:55.015Z | 173.21.3.15
+2024-10-23T13:51:54.732Z | 173.21.3.15
+2024-10-23T13:33:34.937Z | 173.21.0.5
+2024-10-23T12:27:28.948Z | 173.21.2.113
+2024-10-23T12:15:03.360Z | 173.21.2.162
+;
+
+fieldIsMappedToKeywordSingleIndex
+required_capability: unmapped_fields
+FROM partial_mapping_sample_data
+| INSIST_🐔 message
+| KEEP @timestamp, message
+| SORT @timestamp DESC
+;
+
+@timestamp:datetime      | message:keyword
+2024-10-23T13:55:01.543Z | Connected to 10.1.0.1!
+2024-10-23T13:53:55.832Z | Connection error?
+2024-10-23T13:52:55.015Z | Connection error?
+2024-10-23T13:51:54.732Z | Connection error?
+2024-10-23T13:33:34.937Z | 42
+2024-10-23T12:27:28.948Z | Connected to 10.1.0.2!
+2024-10-23T12:15:03.360Z | Connected to 10.1.0.3!
+;
+
+unmappedFieldAppearsLast
+required_capability: unmapped_fields
+FROM partial_mapping_sample_data
+| INSIST_🐔 event_duration
+| SORT @timestamp DESC
+| Limit 1
+;
+
+@timestamp:date          | client_ip:ip | message:keyword        | event_duration:long
+2024-10-23T13:55:01.543Z | 173.21.3.15  | Connected to 10.1.0.1! | 1756466
+;
+
+fieldDoesNotExistSingleIndex
+required_capability: unmapped_fields
+FROM partial_mapping_sample_data
+| INSIST_🐔 foo
+| KEEP @timestamp, foo
+| SORT @timestamp DESC
+;
+
+@timestamp:date           |  foo:keyword
+2024-10-23T13:55:01.543Z  |  null
+2024-10-23T13:53:55.832Z  |  null
+2024-10-23T13:52:55.015Z  |  null
+2024-10-23T13:51:54.732Z  |  null
+2024-10-23T13:33:34.937Z  |  null
+2024-10-23T12:27:28.948Z  |  null
+2024-10-23T12:15:03.360Z  |  null
+;
+
+fieldIsUnmappedSingleIndex
+required_capability: unmapped_fields
+FROM partial_mapping_sample_data
+| INSIST_🐔 unmapped_message
+| KEEP @timestamp, message, unmapped_message
+| SORT @timestamp DESC
+;
+
+@timestamp:date          | message:keyword        | unmapped_message:keyword
+2024-10-23T13:55:01.543Z | Connected to 10.1.0.1! | Disconnected from 10.1.0.1
+2024-10-23T13:53:55.832Z | Connection error?      | Disconnection error
+2024-10-23T13:52:55.015Z | Connection error?      | Disconnection error
+2024-10-23T13:51:54.732Z | Connection error?      | Disconnection error
+2024-10-23T13:33:34.937Z | 42                     | 43
+2024-10-23T12:27:28.948Z | Connected to 10.1.0.2! | Disconnected from 10.1.0.2
+2024-10-23T12:15:03.360Z | Connected to 10.1.0.3! | Disconnected from 10.1.0.3
+;
+
+fieldIsUnmappedButSourceIsDisabledSingleIndex
+required_capability: source_field_mapping
+required_capability: unmapped_fields
+FROM partial_mapping_no_source_sample_data
+| INSIST_🐔 message
+;
+
+@timestamp:date          | message:keyword
+2024-10-23T13:55:01.543Z | null
+2024-10-23T13:53:55.832Z | null
+2024-10-23T13:52:55.015Z | null
+2024-10-23T13:51:54.732Z | null
+2024-10-23T13:33:34.937Z | null
+2024-10-23T12:27:28.948Z | null
+2024-10-23T12:15:03.360Z | null
+;
+
+fieldIsUnmappedButExcludedFromSourceSingleIndex
+required_capability: source_field_mapping
+required_capability: unmapped_fields
+FROM partial_mapping_excluded_source_sample_data
+| INSIST_🐔 message
+| SORT @timestamp DESC
+;
+
+@timestamp:date          | message:keyword
+2024-10-23T13:55:01.543Z | null
+2024-10-23T13:53:55.832Z | null
+2024-10-23T13:52:55.015Z | null
+2024-10-23T13:51:54.732Z | null
+2024-10-23T13:33:34.937Z | null
+2024-10-23T12:27:28.948Z | null
+2024-10-23T12:15:03.360Z | null
+;
+
+fieldIsNestedAndMapped
+required_capability: unmapped_fields
+FROM addresses
+| INSIST_🐔 city.name
+| KEEP city.name
+| SORT city.name DESC
+;
+
+city.name:keyword
+Tokyo
+San Francisco
+Amsterdam
+;
+
+fieldIsNestedAndUnmapped
+required_capability: unmapped_fields
+FROM partial_mapping_sample_data
+| INSIST_🐔 unmapped.nested
+| KEEP @timestamp, unmapped.nested
+| SORT @timestamp
+;
+
+@timestamp:date          | unmapped.nested:keyword
+2024-10-23T12:15:03.360Z | g
+2024-10-23T12:27:28.948Z | f
+2024-10-23T13:33:34.937Z | e
+2024-10-23T13:51:54.732Z | d
+2024-10-23T13:52:55.015Z | c
+2024-10-23T13:53:55.832Z | b
+2024-10-23T13:55:01.543Z | a
+;
+
+fieldIsNestedAndNonExistent
+required_capability: unmapped_fields
+FROM partial_mapping_sample_data
+| INSIST_🐔 unmapped.nested.nonexistent
+| KEEP @timestamp, unmapped.nested.nonexistent
+| SORT @timestamp
+;
+
+@timestamp:date          | unmapped.nested.nonexistent:keyword
+2024-10-23T12:15:03.360Z | null
+2024-10-23T12:27:28.948Z | null
+2024-10-23T13:33:34.937Z | null
+2024-10-23T13:51:54.732Z | null
+2024-10-23T13:52:55.015Z | null
+2024-10-23T13:53:55.832Z | null
+2024-10-23T13:55:01.543Z | null
+;
+
+#########################
+# Multi-parameter tests #
+#########################
+
+noFieldExistsMultiParametersSingleIndex
+required_capability: unmapped_fields
+FROM partial_mapping_sample_data
+| INSIST_🐔 foo, bar, bazz
+| KEEP @timestamp, foo, bar, bazz
+| SORT @timestamp DESC
+;
+
+@timestamp:date          | foo:keyword | bar:keyword | bazz:keyword
+2024-10-23T13:55:01.543Z | null        | null        | null
+2024-10-23T13:53:55.832Z | null        | null        | null
+2024-10-23T13:52:55.015Z | null        | null        | null
+2024-10-23T13:51:54.732Z | null        | null        | null
+2024-10-23T13:33:34.937Z | null        | null        | null
+2024-10-23T12:27:28.948Z | null        | null        | null
+2024-10-23T12:15:03.360Z | null        | null        | null
+;
+
+mixedFieldsMultiParametersSingleIndex
+required_capability: unmapped_fields
+FROM partial_mapping_sample_data
+| INSIST_🐔 foo, message, unmapped_message
+| KEEP @timestamp, foo, message, unmapped_message
+| SORT @timestamp DESC
+;
+
+@timestamp:date          | foo:keyword | message:keyword        | unmapped_message:keyword
+2024-10-23T13:55:01.543Z | null        | Connected to 10.1.0.1! | Disconnected from 10.1.0.1
+2024-10-23T13:53:55.832Z | null        | Connection error?      | Disconnection error
+2024-10-23T13:52:55.015Z | null        | Connection error?      | Disconnection error
+2024-10-23T13:51:54.732Z | null        | Connection error?      | Disconnection error
+2024-10-23T13:33:34.937Z | null        | 42                     | 43
+2024-10-23T12:27:28.948Z | null        | Connected to 10.1.0.2! | Disconnected from 10.1.0.2
+2024-10-23T12:15:03.360Z | null        | Connected to 10.1.0.3! | Disconnected from 10.1.0.3
+;
+
+repeatedInsistFieldsUseTheLastEntry
+required_capability: unmapped_fields
+FROM partial_mapping_sample_data
+| INSIST_🐔 unmapped_message, foo, message, foo, message, unmapped_message
+| KEEP @timestamp, foo, message, unmapped_message
+| SORT @timestamp DESC
+;
+
+@timestamp:date          | foo:keyword | message:keyword        | unmapped_message:keyword
+2024-10-23T13:55:01.543Z | null        | Connected to 10.1.0.1! | Disconnected from 10.1.0.1
+2024-10-23T13:53:55.832Z | null        | Connection error?      | Disconnection error
+2024-10-23T13:52:55.015Z | null        | Connection error?      | Disconnection error
+2024-10-23T13:51:54.732Z | null        | Connection error?      | Disconnection error
+2024-10-23T13:33:34.937Z | null        | 42                     | 43
+2024-10-23T12:27:28.948Z | null        | Connected to 10.1.0.2! | Disconnected from 10.1.0.2
+2024-10-23T12:15:03.360Z | null        | Connected to 10.1.0.3! | Disconnected from 10.1.0.3
+;
+
+#####################
+# Multi index tests #
+#####################
+
+mixedFieldsMultiParametersMultiIndex
+required_capability: unmapped_fields
+required_capability: index_metadata_field
+FROM partial_mapping_sample_data, sample_data METADATA _index
+| INSIST_🐔 foo, message, unmapped_message
+| KEEP _index, @timestamp, foo, message, unmapped_message
+| SORT @timestamp DESC
+;
+
+_index:keyword              | @timestamp:datetime      | foo:keyword | message:keyword        | unmapped_message:keyword  
+partial_mapping_sample_data | 2024-10-23T13:55:01.543Z | null        | Connected to 10.1.0.1! | Disconnected from 10.1.0.1
+partial_mapping_sample_data | 2024-10-23T13:53:55.832Z | null        | Connection error?      | Disconnection error       
+partial_mapping_sample_data | 2024-10-23T13:52:55.015Z | null        | Connection error?      | Disconnection error       
+partial_mapping_sample_data | 2024-10-23T13:51:54.732Z | null        | Connection error?      | Disconnection error       
+partial_mapping_sample_data | 2024-10-23T13:33:34.937Z | null        | 42                     | 43                        
+partial_mapping_sample_data | 2024-10-23T12:27:28.948Z | null        | Connected to 10.1.0.2! | Disconnected from 10.1.0.2
+partial_mapping_sample_data | 2024-10-23T12:15:03.360Z | null        | Connected to 10.1.0.3! | Disconnected from 10.1.0.3
+sample_data                 | 2023-10-23T13:55:01.543Z | null        | Connected to 10.1.0.1  | null                      
+sample_data                 | 2023-10-23T13:53:55.832Z | null        | Connection error       | null                      
+sample_data                 | 2023-10-23T13:52:55.015Z | null        | Connection error       | null                      
+sample_data                 | 2023-10-23T13:51:54.732Z | null        | Connection error       | null                      
+sample_data                 | 2023-10-23T13:33:34.937Z | null        | Disconnected           | null                      
+sample_data                 | 2023-10-23T12:27:28.948Z | null        | Connected to 10.1.0.2  | null                      
+sample_data                 | 2023-10-23T12:15:03.360Z | null        | Connected to 10.1.0.3  | null
+;
+
+insistOnTopOfInsistMultiIndex
+required_capability: unmapped_fields
+required_capability: index_metadata_field
+FROM partial_mapping_sample_data, sample_data METADATA _index
+| INSIST_🐔 foo, message
+| INSIST_🐔 unmapped_message
+| KEEP _index, @timestamp, foo, message, unmapped_message
+| SORT @timestamp DESC
+;
+
+_index:keyword              | @timestamp:datetime      | foo:keyword | message:keyword        | unmapped_message:keyword  
+partial_mapping_sample_data | 2024-10-23T13:55:01.543Z | null        | Connected to 10.1.0.1! | Disconnected from 10.1.0.1
+partial_mapping_sample_data | 2024-10-23T13:53:55.832Z | null        | Connection error?      | Disconnection error       
+partial_mapping_sample_data | 2024-10-23T13:52:55.015Z | null        | Connection error?      | Disconnection error       
+partial_mapping_sample_data | 2024-10-23T13:51:54.732Z | null        | Connection error?      | Disconnection error       
+partial_mapping_sample_data | 2024-10-23T13:33:34.937Z | null        | 42                     | 43                        
+partial_mapping_sample_data | 2024-10-23T12:27:28.948Z | null        | Connected to 10.1.0.2! | Disconnected from 10.1.0.2
+partial_mapping_sample_data | 2024-10-23T12:15:03.360Z | null        | Connected to 10.1.0.3! | Disconnected from 10.1.0.3
+sample_data                 | 2023-10-23T13:55:01.543Z | null        | Connected to 10.1.0.1  | null                      
+sample_data                 | 2023-10-23T13:53:55.832Z | null        | Connection error       | null                      
+sample_data                 | 2023-10-23T13:52:55.015Z | null        | Connection error       | null                      
+sample_data                 | 2023-10-23T13:51:54.732Z | null        | Connection error       | null                      
+sample_data                 | 2023-10-23T13:33:34.937Z | null        | Disconnected           | null                      
+sample_data                 | 2023-10-23T12:27:28.948Z | null        | Connected to 10.1.0.2  | null                      
+sample_data                 | 2023-10-23T12:15:03.360Z | null        | Connected to 10.1.0.3  | null
+;
+
+fieldDoesNotExistMultiIndex
+required_capability: index_metadata_field
+required_capability: unmapped_fields
+FROM partial_mapping_sample_data, sample_data METADATA _index
+| INSIST_🐔 foo
+| KEEP _index, @timestamp, foo
+| SORT @timestamp DESC
+;
+
+_index:keyword              | @timestamp:date          | foo:keyword
+partial_mapping_sample_data | 2024-10-23T13:55:01.543Z | null
+partial_mapping_sample_data | 2024-10-23T13:53:55.832Z | null
+partial_mapping_sample_data | 2024-10-23T13:52:55.015Z | null
+partial_mapping_sample_data | 2024-10-23T13:51:54.732Z | null
+partial_mapping_sample_data | 2024-10-23T13:33:34.937Z | null
+partial_mapping_sample_data | 2024-10-23T12:27:28.948Z | null
+partial_mapping_sample_data | 2024-10-23T12:15:03.360Z | null
+sample_data                 | 2023-10-23T13:55:01.543Z | null
+sample_data                 | 2023-10-23T13:53:55.832Z | null
+sample_data                 | 2023-10-23T13:52:55.015Z | null
+sample_data                 | 2023-10-23T13:51:54.732Z | null
+sample_data                 | 2023-10-23T13:33:34.937Z | null
+sample_data                 | 2023-10-23T12:27:28.948Z | null
+sample_data                 | 2023-10-23T12:15:03.360Z | null
+;
+
+fieldIsUnmappedMultiIndex
+required_capability: index_metadata_field
+required_capability: unmapped_fields
+FROM partial_mapping_sample_data, sample_data METADATA _index
+| INSIST_🐔 unmapped_message
+| KEEP @timestamp, message, unmapped_message, _index
+| SORT @timestamp DESC
+;
+
+@timestamp:date          | message:keyword        | unmapped_message:keyword   | _index:keyword
+2024-10-23T13:55:01.543Z | Connected to 10.1.0.1! | Disconnected from 10.1.0.1 | partial_mapping_sample_data
+2024-10-23T13:53:55.832Z | Connection error?      | Disconnection error        | partial_mapping_sample_data
+2024-10-23T13:52:55.015Z | Connection error?      | Disconnection error        | partial_mapping_sample_data
+2024-10-23T13:51:54.732Z | Connection error?      | Disconnection error        | partial_mapping_sample_data
+2024-10-23T13:33:34.937Z | 42                     | 43                         | partial_mapping_sample_data
+2024-10-23T12:27:28.948Z | Connected to 10.1.0.2! | Disconnected from 10.1.0.2 | partial_mapping_sample_data
+2024-10-23T12:15:03.360Z | Connected to 10.1.0.3! | Disconnected from 10.1.0.3 | partial_mapping_sample_data
+2023-10-23T13:55:01.543Z | Connected to 10.1.0.1  | null                       | sample_data
+2023-10-23T13:53:55.832Z | Connection error       | null                       | sample_data
+2023-10-23T13:52:55.015Z | Connection error       | null                       | sample_data
+2023-10-23T13:51:54.732Z | Connection error       | null                       | sample_data
+2023-10-23T13:33:34.937Z | Disconnected           | null                       | sample_data
+2023-10-23T12:27:28.948Z | Connected to 10.1.0.2  | null                       | sample_data
+2023-10-23T12:15:03.360Z | Connected to 10.1.0.3  | null                       | sample_data
+;
+
+
+fieldIsMappedToDifferentTypesMultiIndex
+required_capability: index_metadata_field
+required_capability: unmapped_fields
+FROM sample_data_ts_long, sample_data METADATA _index
+| INSIST_🐔 @timestamp
+| KEEP _index, @timestamp
+| SORT _index
+;
+
+_index:keyword      | @timestamp:unsupported
+sample_data         | null
+sample_data         | null
+sample_data         | null
+sample_data         | null
+sample_data         | null
+sample_data         | null
+sample_data         | null
+sample_data_ts_long | null
+sample_data_ts_long | null
+sample_data_ts_long | null
+sample_data_ts_long | null
+sample_data_ts_long | null
+sample_data_ts_long | null
+sample_data_ts_long | null
+;
+
+fieldIsMappedToDifferentTypesButDropped
+required_capability: index_metadata_field
+required_capability: unmapped_fields
+FROM sample_data_ts_long, sample_data METADATA _index
+| INSIST_🐔 @timestamp
+| KEEP _index, @timestamp
+| DROP @timestamp
+| EVAL @timestamp = 42
+| SORT _index
+;
+
+_index:keyword      | @timestamp:integer
+sample_data         | 42
+sample_data         | 42
+sample_data         | 42
+sample_data         | 42
+sample_data         | 42
+sample_data         | 42
+sample_data         | 42
+sample_data_ts_long | 42
+sample_data_ts_long | 42
+sample_data_ts_long | 42
+sample_data_ts_long | 42
+sample_data_ts_long | 42
+sample_data_ts_long | 42
+sample_data_ts_long | 42
+;
+
+fieldIsPartiallyUnmappedMultiIndex
+required_capability: index_metadata_field
+required_capability: unmapped_fields
+FROM sample_data, no_mapping_sample_data METADATA _index
+| INSIST_🐔 message
+| KEEP _index, message
+| SORT _index, message DESC
+;
+
+_index:keyword         | message:keyword
+no_mapping_sample_data | Connection error?
+no_mapping_sample_data | Connection error?
+no_mapping_sample_data | Connection error?
+no_mapping_sample_data | Connected to 10.1.0.3!
+no_mapping_sample_data | Connected to 10.1.0.2!
+no_mapping_sample_data | Connected to 10.1.0.1!
+no_mapping_sample_data | 42
+sample_data            | Disconnected
+sample_data            | Connection error
+sample_data            | Connection error
+sample_data            | Connection error
+sample_data            | Connected to 10.1.0.3
+sample_data            | Connected to 10.1.0.2
+sample_data            | Connected to 10.1.0.1
+;
+
+fieldIsPartiallyUnmappedAndRenamedMultiIndex
+required_capability: unmapped_fields
+FROM sample_data, no_mapping_sample_data
+| INSIST_🐔 message
+| KEEP message
+| RENAME message AS msg
+| SORT msg DESC
+;
+
+msg:keyword
+Disconnected
+Connection error?
+Connection error?
+Connection error?
+Connection error
+Connection error
+Connection error
+Connected to 10.1.0.3!
+Connected to 10.1.0.3
+Connected to 10.1.0.2!
+Connected to 10.1.0.2
+Connected to 10.1.0.1!
+Connected to 10.1.0.1
+42
+;
+
+fieldIsPartiallyUnmappedPartiallySourceIsDisabledMultiIndex
+required_capability: index_metadata_field
+required_capability: source_field_mapping
+required_capability: unmapped_fields
+FROM partial_mapping_sample_data,partial_mapping_no_source_sample_data METADATA _index
+| INSIST_🐔 message
+| KEEP _index, @timestamp, message
+| SORT _index, @timestamp
+;
+
+_index:keyword                        | @timestamp:date          | message:keyword
+partial_mapping_no_source_sample_data | 2024-10-23T12:15:03.360Z | null
+partial_mapping_no_source_sample_data | 2024-10-23T12:27:28.948Z | null
+partial_mapping_no_source_sample_data | 2024-10-23T13:33:34.937Z | null
+partial_mapping_no_source_sample_data | 2024-10-23T13:51:54.732Z | null
+partial_mapping_no_source_sample_data | 2024-10-23T13:52:55.015Z | null
+partial_mapping_no_source_sample_data | 2024-10-23T13:53:55.832Z | null
+partial_mapping_no_source_sample_data | 2024-10-23T13:55:01.543Z | null
+partial_mapping_sample_data           | 2024-10-23T12:15:03.360Z | Connected to 10.1.0.3!
+partial_mapping_sample_data           | 2024-10-23T12:27:28.948Z | Connected to 10.1.0.2!
+partial_mapping_sample_data           | 2024-10-23T13:33:34.937Z | 42
+partial_mapping_sample_data           | 2024-10-23T13:51:54.732Z | Connection error?
+partial_mapping_sample_data           | 2024-10-23T13:52:55.015Z | Connection error?
+partial_mapping_sample_data           | 2024-10-23T13:53:55.832Z | Connection error?
+partial_mapping_sample_data           | 2024-10-23T13:55:01.543Z | Connected to 10.1.0.1!
+;
+
+partialMappingStats
+required_capability: index_metadata_field
+required_capability: source_field_mapping
+required_capability: unmapped_fields
+FROM partial_mapping_sample_data,partial_mapping_excluded_source_sample_data METADATA _index
+| INSIST_🐔 message
+| SORT message, @timestamp
+| STATS max(@timestamp), count(*) BY message
+;
+
+max(@timestamp):date     | count(*):long | message:keyword
+2024-10-23T13:55:01.543Z | 7             | null
+2024-10-23T13:33:34.937Z | 1             | 42
+2024-10-23T13:55:01.543Z | 1             | Connected to 10.1.0.1!
+2024-10-23T12:27:28.948Z | 1             | Connected to 10.1.0.2!
+2024-10-23T12:15:03.360Z | 1             | Connected to 10.1.0.3!
+2024-10-23T13:53:55.832Z | 3             | Connection error?
+;
+
+partialMappingCoalesce
+required_capability: index_metadata_field
+required_capability: source_field_mapping
+required_capability: unmapped_fields
+FROM partial_mapping_sample_data,partial_mapping_excluded_source_sample_data METADATA _index
+| INSIST_🐔 message
+| EVAL actual_value = COALESCE(message, "no _source")
+| DROP message
+| KEEP @timestamp, _index, actual_value
+| SORT _index, @timestamp ASC
+;
+
+@timestamp:date          | _index:keyword                              | actual_value:keyword
+2024-10-23T12:15:03.360Z | partial_mapping_excluded_source_sample_data | no _source
+2024-10-23T12:27:28.948Z | partial_mapping_excluded_source_sample_data | no _source
+2024-10-23T13:33:34.937Z | partial_mapping_excluded_source_sample_data | no _source
+2024-10-23T13:51:54.732Z | partial_mapping_excluded_source_sample_data | no _source
+2024-10-23T13:52:55.015Z | partial_mapping_excluded_source_sample_data | no _source
+2024-10-23T13:53:55.832Z | partial_mapping_excluded_source_sample_data | no _source
+2024-10-23T13:55:01.543Z | partial_mapping_excluded_source_sample_data | no _source
+2024-10-23T12:15:03.360Z | partial_mapping_sample_data                 | Connected to 10.1.0.3!
+2024-10-23T12:27:28.948Z | partial_mapping_sample_data                 | Connected to 10.1.0.2!
+2024-10-23T13:33:34.937Z | partial_mapping_sample_data                 | 42
+2024-10-23T13:51:54.732Z | partial_mapping_sample_data                 | Connection error?
+2024-10-23T13:52:55.015Z | partial_mapping_sample_data                 | Connection error?
+2024-10-23T13:53:55.832Z | partial_mapping_sample_data                 | Connection error?
+2024-10-23T13:55:01.543Z | partial_mapping_sample_data                 | Connected to 10.1.0.1!
+;
+
+partialMappingUnionTypes
+required_capability: index_metadata_field
+required_capability: source_field_mapping
+required_capability: unmapped_fields
+FROM partial_mapping_sample_data,partial_mapping_excluded_source_sample_data METADATA _index
+| INSIST_🐔 message
+| EVAL actual_value = message::STRING
+| KEEP @timestamp, _index, actual_value
+| SORT actual_value, @timestamp ASC
+;
+
+@timestamp:date          | _index:keyword                              | actual_value:string
+2024-10-23T13:33:34.937Z | partial_mapping_sample_data                 | 42
+2024-10-23T13:55:01.543Z | partial_mapping_sample_data                 | Connected to 10.1.0.1!
+2024-10-23T12:27:28.948Z | partial_mapping_sample_data                 | Connected to 10.1.0.2!
+2024-10-23T12:15:03.360Z | partial_mapping_sample_data                 | Connected to 10.1.0.3!
+2024-10-23T13:51:54.732Z | partial_mapping_sample_data                 | Connection error?
+2024-10-23T13:52:55.015Z | partial_mapping_sample_data                 | Connection error?
+2024-10-23T13:53:55.832Z | partial_mapping_sample_data                 | Connection error?
+2024-10-23T12:15:03.360Z | partial_mapping_excluded_source_sample_data | null
+2024-10-23T12:27:28.948Z | partial_mapping_excluded_source_sample_data | null
+2024-10-23T13:33:34.937Z | partial_mapping_excluded_source_sample_data | null
+2024-10-23T13:51:54.732Z | partial_mapping_excluded_source_sample_data | null
+2024-10-23T13:52:55.015Z | partial_mapping_excluded_source_sample_data | null
+2024-10-23T13:53:55.832Z | partial_mapping_excluded_source_sample_data | null
+2024-10-23T13:55:01.543Z | partial_mapping_excluded_source_sample_data | null
+;
+
+partialMappingStatsAfterCast
+required_capability: index_metadata_field
+required_capability: source_field_mapping
+required_capability: unmapped_fields
+FROM partial_mapping_sample_data,partial_mapping_excluded_source_sample_data
+| INSIST_🐔 message
+| STATS count(*) BY message::INT
+;
+warningRegex: Line 3:21: evaluation of \[message::INT\] failed, treating result as null. Only first 20 failures recorded.
+warningRegex: org.elasticsearch.xpack.esql.core.InvalidArgumentException: Cannot parse number \[.*\]
+
+count(*):long | message::INT:integer
+13            | null
+1             | 42
+;

+ 14 - 1
x-pack/plugin/esql/src/main/antlr/EsqlBaseLexer.g4

@@ -87,6 +87,7 @@ JOIN_LOOKUP : 'lookup'        -> pushMode(JOIN_MODE);
 // MYCOMMAND : 'mycommand' -> ...
 DEV_CHANGE_POINT : {this.isDevVersion()}? 'change_point'  -> pushMode(CHANGE_POINT_MODE);
 DEV_INLINESTATS :  {this.isDevVersion()}? 'inlinestats'   -> pushMode(EXPRESSION_MODE);
+DEV_INSIST :      {this.isDevVersion()}? 'insist_🐔'      -> pushMode(PROJECT_MODE);
 DEV_LOOKUP :       {this.isDevVersion()}? 'lookup_🐔'     -> pushMode(LOOKUP_MODE);
 DEV_METRICS :      {this.isDevVersion()}? 'metrics'       -> pushMode(METRICS_MODE);
 // list of all JOIN commands
@@ -308,8 +309,9 @@ FROM_MULTILINE_COMMENT
 FROM_WS
     : WS -> channel(HIDDEN)
     ;
+
 //
-// DROP, KEEP
+// DROP, KEEP, INSIST
 //
 mode PROJECT_MODE;
 PROJECT_PIPE : PIPE -> type(PIPE), popMode;
@@ -655,3 +657,14 @@ CHANGE_POINT_UNQUOTED_IDENTIFIER: UNQUOTED_IDENTIFIER -> type(UNQUOTED_IDENTIFIE
 CHANGE_POINT_LINE_COMMENT: LINE_COMMENT -> channel(HIDDEN);
 CHANGE_POINT_MULTILINE_COMMENT: MULTILINE_COMMENT -> channel(HIDDEN);
 CHANGE_POINT_WS: WS -> channel(HIDDEN);
+
+//
+// INSIST command
+//
+mode INSIST_MODE;
+INSIST_PIPE : PIPE -> type(PIPE), popMode;
+INSIST_IDENTIFIER: UNQUOTED_IDENTIFIER -> type(UNQUOTED_IDENTIFIER);
+
+INSIST_WS : WS -> channel(HIDDEN);
+INSIST_LINE_COMMENT : LINE_COMMENT -> channel(HIDDEN);
+INSIST_MULTILINE_COMMENT : MULTILINE_COMMENT -> channel(HIDDEN);

+ 166 - 162
x-pack/plugin/esql/src/main/antlr/EsqlBaseLexer.tokens

@@ -17,121 +17,125 @@ WHERE=16
 JOIN_LOOKUP=17
 DEV_CHANGE_POINT=18
 DEV_INLINESTATS=19
-DEV_LOOKUP=20
-DEV_METRICS=21
-DEV_JOIN_FULL=22
-DEV_JOIN_LEFT=23
-DEV_JOIN_RIGHT=24
-UNKNOWN_CMD=25
-LINE_COMMENT=26
-MULTILINE_COMMENT=27
-WS=28
-PIPE=29
-QUOTED_STRING=30
-INTEGER_LITERAL=31
-DECIMAL_LITERAL=32
-BY=33
-AND=34
-ASC=35
-ASSIGN=36
-CAST_OP=37
-COLON=38
-COMMA=39
-DESC=40
-DOT=41
-FALSE=42
-FIRST=43
-IN=44
-IS=45
-LAST=46
-LIKE=47
-LP=48
-NOT=49
-NULL=50
-NULLS=51
-OR=52
-PARAM=53
-RLIKE=54
-RP=55
-TRUE=56
-EQ=57
-CIEQ=58
-NEQ=59
-LT=60
-LTE=61
-GT=62
-GTE=63
-PLUS=64
-MINUS=65
-ASTERISK=66
-SLASH=67
-PERCENT=68
-LEFT_BRACES=69
-RIGHT_BRACES=70
-NAMED_OR_POSITIONAL_PARAM=71
-OPENING_BRACKET=72
-CLOSING_BRACKET=73
-UNQUOTED_IDENTIFIER=74
-QUOTED_IDENTIFIER=75
-EXPR_LINE_COMMENT=76
-EXPR_MULTILINE_COMMENT=77
-EXPR_WS=78
-EXPLAIN_WS=79
-EXPLAIN_LINE_COMMENT=80
-EXPLAIN_MULTILINE_COMMENT=81
-METADATA=82
-UNQUOTED_SOURCE=83
-FROM_LINE_COMMENT=84
-FROM_MULTILINE_COMMENT=85
-FROM_WS=86
-ID_PATTERN=87
-PROJECT_LINE_COMMENT=88
-PROJECT_MULTILINE_COMMENT=89
-PROJECT_WS=90
-AS=91
-RENAME_LINE_COMMENT=92
-RENAME_MULTILINE_COMMENT=93
-RENAME_WS=94
-ON=95
-WITH=96
-ENRICH_POLICY_NAME=97
-ENRICH_LINE_COMMENT=98
-ENRICH_MULTILINE_COMMENT=99
-ENRICH_WS=100
-ENRICH_FIELD_LINE_COMMENT=101
-ENRICH_FIELD_MULTILINE_COMMENT=102
-ENRICH_FIELD_WS=103
-MVEXPAND_LINE_COMMENT=104
-MVEXPAND_MULTILINE_COMMENT=105
-MVEXPAND_WS=106
-INFO=107
-SHOW_LINE_COMMENT=108
-SHOW_MULTILINE_COMMENT=109
-SHOW_WS=110
-SETTING=111
-SETTING_LINE_COMMENT=112
-SETTTING_MULTILINE_COMMENT=113
-SETTING_WS=114
-LOOKUP_LINE_COMMENT=115
-LOOKUP_MULTILINE_COMMENT=116
-LOOKUP_WS=117
-LOOKUP_FIELD_LINE_COMMENT=118
-LOOKUP_FIELD_MULTILINE_COMMENT=119
-LOOKUP_FIELD_WS=120
-JOIN=121
-USING=122
-JOIN_LINE_COMMENT=123
-JOIN_MULTILINE_COMMENT=124
-JOIN_WS=125
-METRICS_LINE_COMMENT=126
-METRICS_MULTILINE_COMMENT=127
-METRICS_WS=128
-CLOSING_METRICS_LINE_COMMENT=129
-CLOSING_METRICS_MULTILINE_COMMENT=130
-CLOSING_METRICS_WS=131
-CHANGE_POINT_LINE_COMMENT=132
-CHANGE_POINT_MULTILINE_COMMENT=133
-CHANGE_POINT_WS=134
+DEV_INSIST=20
+DEV_LOOKUP=21
+DEV_METRICS=22
+DEV_JOIN_FULL=23
+DEV_JOIN_LEFT=24
+DEV_JOIN_RIGHT=25
+UNKNOWN_CMD=26
+LINE_COMMENT=27
+MULTILINE_COMMENT=28
+WS=29
+PIPE=30
+QUOTED_STRING=31
+INTEGER_LITERAL=32
+DECIMAL_LITERAL=33
+BY=34
+AND=35
+ASC=36
+ASSIGN=37
+CAST_OP=38
+COLON=39
+COMMA=40
+DESC=41
+DOT=42
+FALSE=43
+FIRST=44
+IN=45
+IS=46
+LAST=47
+LIKE=48
+LP=49
+NOT=50
+NULL=51
+NULLS=52
+OR=53
+PARAM=54
+RLIKE=55
+RP=56
+TRUE=57
+EQ=58
+CIEQ=59
+NEQ=60
+LT=61
+LTE=62
+GT=63
+GTE=64
+PLUS=65
+MINUS=66
+ASTERISK=67
+SLASH=68
+PERCENT=69
+LEFT_BRACES=70
+RIGHT_BRACES=71
+NAMED_OR_POSITIONAL_PARAM=72
+OPENING_BRACKET=73
+CLOSING_BRACKET=74
+UNQUOTED_IDENTIFIER=75
+QUOTED_IDENTIFIER=76
+EXPR_LINE_COMMENT=77
+EXPR_MULTILINE_COMMENT=78
+EXPR_WS=79
+EXPLAIN_WS=80
+EXPLAIN_LINE_COMMENT=81
+EXPLAIN_MULTILINE_COMMENT=82
+METADATA=83
+UNQUOTED_SOURCE=84
+FROM_LINE_COMMENT=85
+FROM_MULTILINE_COMMENT=86
+FROM_WS=87
+ID_PATTERN=88
+PROJECT_LINE_COMMENT=89
+PROJECT_MULTILINE_COMMENT=90
+PROJECT_WS=91
+AS=92
+RENAME_LINE_COMMENT=93
+RENAME_MULTILINE_COMMENT=94
+RENAME_WS=95
+ON=96
+WITH=97
+ENRICH_POLICY_NAME=98
+ENRICH_LINE_COMMENT=99
+ENRICH_MULTILINE_COMMENT=100
+ENRICH_WS=101
+ENRICH_FIELD_LINE_COMMENT=102
+ENRICH_FIELD_MULTILINE_COMMENT=103
+ENRICH_FIELD_WS=104
+MVEXPAND_LINE_COMMENT=105
+MVEXPAND_MULTILINE_COMMENT=106
+MVEXPAND_WS=107
+INFO=108
+SHOW_LINE_COMMENT=109
+SHOW_MULTILINE_COMMENT=110
+SHOW_WS=111
+SETTING=112
+SETTING_LINE_COMMENT=113
+SETTTING_MULTILINE_COMMENT=114
+SETTING_WS=115
+LOOKUP_LINE_COMMENT=116
+LOOKUP_MULTILINE_COMMENT=117
+LOOKUP_WS=118
+LOOKUP_FIELD_LINE_COMMENT=119
+LOOKUP_FIELD_MULTILINE_COMMENT=120
+LOOKUP_FIELD_WS=121
+JOIN=122
+USING=123
+JOIN_LINE_COMMENT=124
+JOIN_MULTILINE_COMMENT=125
+JOIN_WS=126
+METRICS_LINE_COMMENT=127
+METRICS_MULTILINE_COMMENT=128
+METRICS_WS=129
+CLOSING_METRICS_LINE_COMMENT=130
+CLOSING_METRICS_MULTILINE_COMMENT=131
+CLOSING_METRICS_WS=132
+CHANGE_POINT_LINE_COMMENT=133
+CHANGE_POINT_MULTILINE_COMMENT=134
+CHANGE_POINT_WS=135
+INSIST_WS=136
+INSIST_LINE_COMMENT=137
+INSIST_MULTILINE_COMMENT=138
 'dissect'=1
 'drop'=2
 'enrich'=3
@@ -149,50 +153,50 @@ CHANGE_POINT_WS=134
 'stats'=15
 'where'=16
 'lookup'=17
-'|'=29
-'by'=33
-'and'=34
-'asc'=35
-'='=36
-'::'=37
-':'=38
-','=39
-'desc'=40
-'.'=41
-'false'=42
-'first'=43
-'in'=44
-'is'=45
-'last'=46
-'like'=47
-'('=48
-'not'=49
-'null'=50
-'nulls'=51
-'or'=52
-'?'=53
-'rlike'=54
-')'=55
-'true'=56
-'=='=57
-'=~'=58
-'!='=59
-'<'=60
-'<='=61
-'>'=62
-'>='=63
-'+'=64
-'-'=65
-'*'=66
-'/'=67
-'%'=68
-'{'=69
-'}'=70
-']'=73
-'metadata'=82
-'as'=91
-'on'=95
-'with'=96
-'info'=107
-'join'=121
-'USING'=122
+'|'=30
+'by'=34
+'and'=35
+'asc'=36
+'='=37
+'::'=38
+':'=39
+','=40
+'desc'=41
+'.'=42
+'false'=43
+'first'=44
+'in'=45
+'is'=46
+'last'=47
+'like'=48
+'('=49
+'not'=50
+'null'=51
+'nulls'=52
+'or'=53
+'?'=54
+'rlike'=55
+')'=56
+'true'=57
+'=='=58
+'=~'=59
+'!='=60
+'<'=61
+'<='=62
+'>'=63
+'>='=64
+'+'=65
+'-'=66
+'*'=67
+'/'=68
+'%'=69
+'{'=70
+'}'=71
+']'=74
+'metadata'=83
+'as'=92
+'on'=96
+'with'=97
+'info'=108
+'join'=122
+'USING'=123

+ 5 - 0
x-pack/plugin/esql/src/main/antlr/EsqlBaseParser.g4

@@ -56,6 +56,7 @@ processingCommand
     | {this.isDevVersion()}? inlinestatsCommand
     | {this.isDevVersion()}? lookupCommand
     | {this.isDevVersion()}? changePointCommand
+    | {this.isDevVersion()}? insistCommand
     ;
 
 whereCommand
@@ -344,3 +345,7 @@ joinPredicate
 changePointCommand
     : DEV_CHANGE_POINT value=qualifiedName (ON key=qualifiedName)? (AS targetType=qualifiedName COMMA targetPvalue=qualifiedName)?
     ;
+
+insistCommand
+    : DEV_INSIST qualifiedNamePatterns
+    ;

+ 166 - 162
x-pack/plugin/esql/src/main/antlr/EsqlBaseParser.tokens

@@ -17,121 +17,125 @@ WHERE=16
 JOIN_LOOKUP=17
 DEV_CHANGE_POINT=18
 DEV_INLINESTATS=19
-DEV_LOOKUP=20
-DEV_METRICS=21
-DEV_JOIN_FULL=22
-DEV_JOIN_LEFT=23
-DEV_JOIN_RIGHT=24
-UNKNOWN_CMD=25
-LINE_COMMENT=26
-MULTILINE_COMMENT=27
-WS=28
-PIPE=29
-QUOTED_STRING=30
-INTEGER_LITERAL=31
-DECIMAL_LITERAL=32
-BY=33
-AND=34
-ASC=35
-ASSIGN=36
-CAST_OP=37
-COLON=38
-COMMA=39
-DESC=40
-DOT=41
-FALSE=42
-FIRST=43
-IN=44
-IS=45
-LAST=46
-LIKE=47
-LP=48
-NOT=49
-NULL=50
-NULLS=51
-OR=52
-PARAM=53
-RLIKE=54
-RP=55
-TRUE=56
-EQ=57
-CIEQ=58
-NEQ=59
-LT=60
-LTE=61
-GT=62
-GTE=63
-PLUS=64
-MINUS=65
-ASTERISK=66
-SLASH=67
-PERCENT=68
-LEFT_BRACES=69
-RIGHT_BRACES=70
-NAMED_OR_POSITIONAL_PARAM=71
-OPENING_BRACKET=72
-CLOSING_BRACKET=73
-UNQUOTED_IDENTIFIER=74
-QUOTED_IDENTIFIER=75
-EXPR_LINE_COMMENT=76
-EXPR_MULTILINE_COMMENT=77
-EXPR_WS=78
-EXPLAIN_WS=79
-EXPLAIN_LINE_COMMENT=80
-EXPLAIN_MULTILINE_COMMENT=81
-METADATA=82
-UNQUOTED_SOURCE=83
-FROM_LINE_COMMENT=84
-FROM_MULTILINE_COMMENT=85
-FROM_WS=86
-ID_PATTERN=87
-PROJECT_LINE_COMMENT=88
-PROJECT_MULTILINE_COMMENT=89
-PROJECT_WS=90
-AS=91
-RENAME_LINE_COMMENT=92
-RENAME_MULTILINE_COMMENT=93
-RENAME_WS=94
-ON=95
-WITH=96
-ENRICH_POLICY_NAME=97
-ENRICH_LINE_COMMENT=98
-ENRICH_MULTILINE_COMMENT=99
-ENRICH_WS=100
-ENRICH_FIELD_LINE_COMMENT=101
-ENRICH_FIELD_MULTILINE_COMMENT=102
-ENRICH_FIELD_WS=103
-MVEXPAND_LINE_COMMENT=104
-MVEXPAND_MULTILINE_COMMENT=105
-MVEXPAND_WS=106
-INFO=107
-SHOW_LINE_COMMENT=108
-SHOW_MULTILINE_COMMENT=109
-SHOW_WS=110
-SETTING=111
-SETTING_LINE_COMMENT=112
-SETTTING_MULTILINE_COMMENT=113
-SETTING_WS=114
-LOOKUP_LINE_COMMENT=115
-LOOKUP_MULTILINE_COMMENT=116
-LOOKUP_WS=117
-LOOKUP_FIELD_LINE_COMMENT=118
-LOOKUP_FIELD_MULTILINE_COMMENT=119
-LOOKUP_FIELD_WS=120
-JOIN=121
-USING=122
-JOIN_LINE_COMMENT=123
-JOIN_MULTILINE_COMMENT=124
-JOIN_WS=125
-METRICS_LINE_COMMENT=126
-METRICS_MULTILINE_COMMENT=127
-METRICS_WS=128
-CLOSING_METRICS_LINE_COMMENT=129
-CLOSING_METRICS_MULTILINE_COMMENT=130
-CLOSING_METRICS_WS=131
-CHANGE_POINT_LINE_COMMENT=132
-CHANGE_POINT_MULTILINE_COMMENT=133
-CHANGE_POINT_WS=134
+DEV_INSIST=20
+DEV_LOOKUP=21
+DEV_METRICS=22
+DEV_JOIN_FULL=23
+DEV_JOIN_LEFT=24
+DEV_JOIN_RIGHT=25
+UNKNOWN_CMD=26
+LINE_COMMENT=27
+MULTILINE_COMMENT=28
+WS=29
+PIPE=30
+QUOTED_STRING=31
+INTEGER_LITERAL=32
+DECIMAL_LITERAL=33
+BY=34
+AND=35
+ASC=36
+ASSIGN=37
+CAST_OP=38
+COLON=39
+COMMA=40
+DESC=41
+DOT=42
+FALSE=43
+FIRST=44
+IN=45
+IS=46
+LAST=47
+LIKE=48
+LP=49
+NOT=50
+NULL=51
+NULLS=52
+OR=53
+PARAM=54
+RLIKE=55
+RP=56
+TRUE=57
+EQ=58
+CIEQ=59
+NEQ=60
+LT=61
+LTE=62
+GT=63
+GTE=64
+PLUS=65
+MINUS=66
+ASTERISK=67
+SLASH=68
+PERCENT=69
+LEFT_BRACES=70
+RIGHT_BRACES=71
+NAMED_OR_POSITIONAL_PARAM=72
+OPENING_BRACKET=73
+CLOSING_BRACKET=74
+UNQUOTED_IDENTIFIER=75
+QUOTED_IDENTIFIER=76
+EXPR_LINE_COMMENT=77
+EXPR_MULTILINE_COMMENT=78
+EXPR_WS=79
+EXPLAIN_WS=80
+EXPLAIN_LINE_COMMENT=81
+EXPLAIN_MULTILINE_COMMENT=82
+METADATA=83
+UNQUOTED_SOURCE=84
+FROM_LINE_COMMENT=85
+FROM_MULTILINE_COMMENT=86
+FROM_WS=87
+ID_PATTERN=88
+PROJECT_LINE_COMMENT=89
+PROJECT_MULTILINE_COMMENT=90
+PROJECT_WS=91
+AS=92
+RENAME_LINE_COMMENT=93
+RENAME_MULTILINE_COMMENT=94
+RENAME_WS=95
+ON=96
+WITH=97
+ENRICH_POLICY_NAME=98
+ENRICH_LINE_COMMENT=99
+ENRICH_MULTILINE_COMMENT=100
+ENRICH_WS=101
+ENRICH_FIELD_LINE_COMMENT=102
+ENRICH_FIELD_MULTILINE_COMMENT=103
+ENRICH_FIELD_WS=104
+MVEXPAND_LINE_COMMENT=105
+MVEXPAND_MULTILINE_COMMENT=106
+MVEXPAND_WS=107
+INFO=108
+SHOW_LINE_COMMENT=109
+SHOW_MULTILINE_COMMENT=110
+SHOW_WS=111
+SETTING=112
+SETTING_LINE_COMMENT=113
+SETTTING_MULTILINE_COMMENT=114
+SETTING_WS=115
+LOOKUP_LINE_COMMENT=116
+LOOKUP_MULTILINE_COMMENT=117
+LOOKUP_WS=118
+LOOKUP_FIELD_LINE_COMMENT=119
+LOOKUP_FIELD_MULTILINE_COMMENT=120
+LOOKUP_FIELD_WS=121
+JOIN=122
+USING=123
+JOIN_LINE_COMMENT=124
+JOIN_MULTILINE_COMMENT=125
+JOIN_WS=126
+METRICS_LINE_COMMENT=127
+METRICS_MULTILINE_COMMENT=128
+METRICS_WS=129
+CLOSING_METRICS_LINE_COMMENT=130
+CLOSING_METRICS_MULTILINE_COMMENT=131
+CLOSING_METRICS_WS=132
+CHANGE_POINT_LINE_COMMENT=133
+CHANGE_POINT_MULTILINE_COMMENT=134
+CHANGE_POINT_WS=135
+INSIST_WS=136
+INSIST_LINE_COMMENT=137
+INSIST_MULTILINE_COMMENT=138
 'dissect'=1
 'drop'=2
 'enrich'=3
@@ -149,50 +153,50 @@ CHANGE_POINT_WS=134
 'stats'=15
 'where'=16
 'lookup'=17
-'|'=29
-'by'=33
-'and'=34
-'asc'=35
-'='=36
-'::'=37
-':'=38
-','=39
-'desc'=40
-'.'=41
-'false'=42
-'first'=43
-'in'=44
-'is'=45
-'last'=46
-'like'=47
-'('=48
-'not'=49
-'null'=50
-'nulls'=51
-'or'=52
-'?'=53
-'rlike'=54
-')'=55
-'true'=56
-'=='=57
-'=~'=58
-'!='=59
-'<'=60
-'<='=61
-'>'=62
-'>='=63
-'+'=64
-'-'=65
-'*'=66
-'/'=67
-'%'=68
-'{'=69
-'}'=70
-']'=73
-'metadata'=82
-'as'=91
-'on'=95
-'with'=96
-'info'=107
-'join'=121
-'USING'=122
+'|'=30
+'by'=34
+'and'=35
+'asc'=36
+'='=37
+'::'=38
+':'=39
+','=40
+'desc'=41
+'.'=42
+'false'=43
+'first'=44
+'in'=45
+'is'=46
+'last'=47
+'like'=48
+'('=49
+'not'=50
+'null'=51
+'nulls'=52
+'or'=53
+'?'=54
+'rlike'=55
+')'=56
+'true'=57
+'=='=58
+'=~'=59
+'!='=60
+'<'=61
+'<='=62
+'>'=63
+'>='=64
+'+'=65
+'-'=66
+'*'=67
+'/'=68
+'%'=69
+'{'=70
+'}'=71
+']'=74
+'metadata'=83
+'as'=92
+'on'=96
+'with'=97
+'info'=108
+'join'=122
+'USING'=123

+ 10 - 0
x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/action/EsqlCapabilities.java

@@ -303,6 +303,11 @@ public class EsqlCapabilities {
          */
         UNION_TYPES,
 
+        /**
+         * Support unmapped using the INSIST keyword.
+         */
+        UNMAPPED_FIELDS(Build.current().isSnapshot()),
+
         /**
          * Support for function {@code ST_DISTANCE}. Done in #108764.
          */
@@ -622,6 +627,11 @@ public class EsqlCapabilities {
          */
         SORT_RETURNING_SOURCE_OK,
 
+        /**
+         * _source field mapping directives: https://www.elastic.co/guide/en/elasticsearch/reference/current/mapping-source-field.html
+         */
+        SOURCE_FIELD_MAPPING,
+
         /**
          * Allow filter per individual aggregation.
          */

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

@@ -9,13 +9,13 @@ package org.elasticsearch.xpack.esql.analysis;
 
 import org.elasticsearch.common.logging.HeaderWarning;
 import org.elasticsearch.compute.data.Block;
+import org.elasticsearch.core.Strings;
 import org.elasticsearch.index.IndexMode;
 import org.elasticsearch.logging.Logger;
 import org.elasticsearch.xpack.core.enrich.EnrichPolicy;
 import org.elasticsearch.xpack.esql.Column;
 import org.elasticsearch.xpack.esql.EsqlIllegalArgumentException;
 import org.elasticsearch.xpack.esql.VerificationException;
-import org.elasticsearch.xpack.esql.analysis.AnalyzerRules.BaseAnalyzerRule;
 import org.elasticsearch.xpack.esql.analysis.AnalyzerRules.ParameterizedAnalyzerRule;
 import org.elasticsearch.xpack.esql.common.Failure;
 import org.elasticsearch.xpack.esql.core.capabilities.Resolvables;
@@ -39,6 +39,7 @@ import org.elasticsearch.xpack.esql.core.type.DataType;
 import org.elasticsearch.xpack.esql.core.type.EsField;
 import org.elasticsearch.xpack.esql.core.type.InvalidMappedField;
 import org.elasticsearch.xpack.esql.core.type.MultiTypeEsField;
+import org.elasticsearch.xpack.esql.core.type.PotentiallyUnmappedKeywordEsField;
 import org.elasticsearch.xpack.esql.core.type.UnsupportedEsField;
 import org.elasticsearch.xpack.esql.core.util.CollectionUtils;
 import org.elasticsearch.xpack.esql.core.util.Holder;
@@ -70,6 +71,7 @@ import org.elasticsearch.xpack.esql.plan.logical.Drop;
 import org.elasticsearch.xpack.esql.plan.logical.Enrich;
 import org.elasticsearch.xpack.esql.plan.logical.EsRelation;
 import org.elasticsearch.xpack.esql.plan.logical.Eval;
+import org.elasticsearch.xpack.esql.plan.logical.Insist;
 import org.elasticsearch.xpack.esql.plan.logical.Keep;
 import org.elasticsearch.xpack.esql.plan.logical.Limit;
 import org.elasticsearch.xpack.esql.plan.logical.LogicalPlan;
@@ -430,9 +432,9 @@ public class Analyzer extends ParameterizedRuleExecutor<LogicalPlan, AnalyzerCon
         }
     }
 
-    public static class ResolveRefs extends BaseAnalyzerRule {
+    public static class ResolveRefs extends ParameterizedAnalyzerRule<LogicalPlan, AnalyzerContext> {
         @Override
-        protected LogicalPlan doRule(LogicalPlan plan) {
+        protected LogicalPlan rule(LogicalPlan plan, AnalyzerContext context) {
             if (plan.childrenResolved() == false) {
                 return plan;
             }
@@ -479,6 +481,10 @@ public class Analyzer extends ParameterizedRuleExecutor<LogicalPlan, AnalyzerCon
                 return resolveLookupJoin(j);
             }
 
+            if (plan instanceof Insist i) {
+                return resolveInsist(i, childrenOutput, context.indexResolution());
+            }
+
             return plan.transformExpressionsOnly(UnresolvedAttribute.class, ua -> maybeResolveAttribute(ua, childrenOutput));
         }
 
@@ -662,13 +668,13 @@ public class Analyzer extends ParameterizedRuleExecutor<LogicalPlan, AnalyzerCon
             List<Attribute> resolved = new ArrayList<>(cols.size());
             for (Attribute col : cols) {
                 if (col instanceof UnresolvedAttribute ua) {
-                    Attribute resolvedCol = maybeResolveAttribute(ua, output);
-                    if (resolvedCol instanceof UnresolvedAttribute ucol) {
+                    Attribute resolvedField = maybeResolveAttribute(ua, output);
+                    if (resolvedField instanceof UnresolvedAttribute ucol) {
                         String message = ua.unresolvedMessage();
                         String match = "column [" + ucol.name() + "]";
-                        resolvedCol = ucol.withUnresolvedMessage(message.replace(match, match + " in " + side + " side of join"));
+                        resolvedField = ucol.withUnresolvedMessage(message.replace(match, match + " in " + side + " side of join"));
                     }
-                    resolved.add(resolvedCol);
+                    resolved.add(resolvedField);
                 } else {
                     throw new IllegalStateException(
                         "Surprised to discover column [ " + col.name() + "] already resolved when resolving JOIN keys"
@@ -678,6 +684,49 @@ public class Analyzer extends ParameterizedRuleExecutor<LogicalPlan, AnalyzerCon
             return resolved;
         }
 
+        private LogicalPlan resolveInsist(Insist insist, List<Attribute> childrenOutput, IndexResolution indexResolution) {
+            List<Attribute> list = new ArrayList<>();
+            for (Attribute a : insist.insistedAttributes()) {
+                list.add(resolveInsistAttribute(a, childrenOutput, indexResolution));
+            }
+            return insist.withAttributes(list);
+        }
+
+        private Attribute resolveInsistAttribute(Attribute attribute, List<Attribute> childrenOutput, IndexResolution indexResolution) {
+            Attribute resolvedCol = maybeResolveAttribute((UnresolvedAttribute) attribute, childrenOutput);
+            // Field isn't mapped anywhere.
+            if (resolvedCol instanceof UnresolvedAttribute) {
+                return insistKeyword(attribute);
+            }
+
+            // Field is partially unmapped.
+            if (resolvedCol instanceof FieldAttribute fa && indexResolution.get().isPartiallyUnmappedField(fa.name())) {
+                return fa.dataType() == KEYWORD ? insistKeyword(fa) : invalidInsistAttribute(fa);
+            }
+
+            // Either the field is mapped everywhere and we can just use the resolved column, or the INSIST clause isn't on top of a FROM
+            // clause—for example, it might be on top of a ROW clause—so the verifier will catch it and fail.
+            return resolvedCol;
+        }
+
+        private static Attribute invalidInsistAttribute(FieldAttribute fa) {
+            var name = fa.name();
+            EsField field = fa.field() instanceof InvalidMappedField imf
+                ? new InvalidMappedField(name, InvalidMappedField.makeErrorsMessageIncludingInsistKeyword(imf.getTypesToIndices()))
+                : new InvalidMappedField(
+                    name,
+                    Strings.format(
+                        "mapped as [2] incompatible types: [keyword] enforced by INSIST command, and [%s] in index mappings",
+                        fa.dataType().typeName()
+                    )
+                );
+            return new FieldAttribute(fa.source(), name, field);
+        }
+
+        private static FieldAttribute insistKeyword(Attribute attribute) {
+            return new FieldAttribute(attribute.source(), attribute.name(), new PotentiallyUnmappedKeywordEsField(attribute.name()));
+        }
+
         private Attribute maybeResolveAttribute(UnresolvedAttribute ua, List<Attribute> childrenOutput) {
             return maybeResolveAttribute(ua, childrenOutput, log);
         }

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

@@ -29,6 +29,8 @@ import org.elasticsearch.xpack.esql.expression.predicate.operator.comparison.Equ
 import org.elasticsearch.xpack.esql.expression.predicate.operator.comparison.EsqlBinaryComparison;
 import org.elasticsearch.xpack.esql.expression.predicate.operator.comparison.NotEquals;
 import org.elasticsearch.xpack.esql.plan.logical.Aggregate;
+import org.elasticsearch.xpack.esql.plan.logical.EsRelation;
+import org.elasticsearch.xpack.esql.plan.logical.Insist;
 import org.elasticsearch.xpack.esql.plan.logical.LogicalPlan;
 import org.elasticsearch.xpack.esql.plan.logical.Lookup;
 import org.elasticsearch.xpack.esql.plan.logical.Project;
@@ -95,6 +97,7 @@ public class Verifier {
 
             checkOperationsOnUnsignedLong(p, failures);
             checkBinaryComparison(p, failures);
+            checkInsist(p, failures);
         });
 
         if (failures.hasFailures() == false) {
@@ -132,7 +135,7 @@ public class Verifier {
 
                 e.forEachUp(ae -> {
                     // Special handling for Project and unsupported/union types: disallow renaming them but pass them through otherwise.
-                    if (p instanceof Project) {
+                    if (p instanceof Project || p instanceof Insist) {
                         if (ae instanceof Alias as && as.child() instanceof UnsupportedAttribute ua) {
                             failures.add(fail(ae, ua.unresolvedMessage()));
                         }
@@ -231,6 +234,15 @@ public class Verifier {
         });
     }
 
+    private static void checkInsist(LogicalPlan p, Failures failures) {
+        if (p instanceof Insist i) {
+            LogicalPlan child = i.child();
+            if ((child instanceof EsRelation || child instanceof Insist) == false) {
+                failures.add(fail(i, "[insist] can only be used after [from] or [insist] commands, but was [{}]", child.sourceText()));
+            }
+        }
+    }
+
     private void licenseCheck(LogicalPlan plan, Failures failures) {
         Consumer<Node<?>> licenseCheck = n -> {
             if (n instanceof LicenseAware la && la.licenseCheck(licenseState) == false) {

+ 20 - 3
x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/index/EsIndex.java

@@ -19,18 +19,29 @@ import java.util.Set;
 
 import static java.util.stream.Collectors.toMap;
 
-public record EsIndex(String name, Map<String, EsField> mapping, Map<String, IndexMode> indexNameWithModes) implements Writeable {
+public record EsIndex(
+    String name,
+    Map<String, EsField> mapping,
+    Map<String, IndexMode> indexNameWithModes,
+    /** Fields mapped only in some (but *not* all) indices. Since this is only used by the analyzer, it is not serialized. */
+    Set<String> partiallyUnmappedFields
+) implements Writeable {
 
     public EsIndex {
         assert name != null;
         assert mapping != null;
+        assert partiallyUnmappedFields != null;
+    }
+
+    public EsIndex(String name, Map<String, EsField> mapping, Map<String, IndexMode> indexNameWithModes) {
+        this(name, mapping, indexNameWithModes, Set.of());
     }
 
     /**
      * Intended for tests. Returns an index with an empty index mode map.
      */
     public EsIndex(String name, Map<String, EsField> mapping) {
-        this(name, mapping, Map.of());
+        this(name, mapping, Map.of(), Set.of());
     }
 
     public static EsIndex readFrom(StreamInput in) throws IOException {
@@ -45,7 +56,8 @@ public record EsIndex(String name, Map<String, EsField> mapping, Map<String, Ind
             assert indices != null;
             indexNameWithModes = indices.stream().collect(toMap(e -> e, e -> IndexMode.STANDARD));
         }
-        return new EsIndex(name, mapping, indexNameWithModes);
+        // partially unmapped fields shouldn't pass the coordinator node anyway, since they are only used by the Analyzer.
+        return new EsIndex(name, mapping, indexNameWithModes, Set.of());
     }
 
     @Override
@@ -57,6 +69,11 @@ public record EsIndex(String name, Map<String, EsField> mapping, Map<String, Ind
         } else {
             out.writeGenericValue(indexNameWithModes.keySet());
         }
+        // partially unmapped fields shouldn't pass the coordinator node anyway, since they are only used by the Analyzer.
+    }
+
+    public boolean isPartiallyUnmappedField(String fieldName) {
+        return partiallyUnmappedFields.contains(fieldName);
     }
 
     public Set<String> concreteIndices() {

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

@@ -27,6 +27,7 @@ import org.elasticsearch.xpack.esql.optimizer.rules.logical.PropagateEquals;
 import org.elasticsearch.xpack.esql.optimizer.rules.logical.PropagateEvalFoldables;
 import org.elasticsearch.xpack.esql.optimizer.rules.logical.PropagateInlineEvals;
 import org.elasticsearch.xpack.esql.optimizer.rules.logical.PropagateNullable;
+import org.elasticsearch.xpack.esql.optimizer.rules.logical.PropgateUnmappedFields;
 import org.elasticsearch.xpack.esql.optimizer.rules.logical.PruneColumns;
 import org.elasticsearch.xpack.esql.optimizer.rules.logical.PruneEmptyPlans;
 import org.elasticsearch.xpack.esql.optimizer.rules.logical.PruneFilters;
@@ -193,6 +194,6 @@ public class LogicalPlanOptimizer extends ParameterizedRuleExecutor<LogicalPlan,
     }
 
     protected static Batch<LogicalPlan> cleanup() {
-        return new Batch<>("Clean Up", new ReplaceLimitAndSortAsTopN(), new ReplaceRowAsLocalRelation());
+        return new Batch<>("Clean Up", new ReplaceLimitAndSortAsTopN(), new ReplaceRowAsLocalRelation(), new PropgateUnmappedFields());
     }
 }

+ 43 - 0
x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/optimizer/rules/logical/PropgateUnmappedFields.java

@@ -0,0 +1,43 @@
+/*
+ * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
+ * or more contributor license agreements. Licensed under the Elastic License
+ * 2.0; you may not use this file except in compliance with the Elastic License
+ * 2.0.
+ */
+
+package org.elasticsearch.xpack.esql.optimizer.rules.logical;
+
+import org.elasticsearch.xpack.esql.core.expression.AttributeSet;
+import org.elasticsearch.xpack.esql.core.expression.FieldAttribute;
+import org.elasticsearch.xpack.esql.core.type.PotentiallyUnmappedKeywordEsField;
+import org.elasticsearch.xpack.esql.expression.NamedExpressions;
+import org.elasticsearch.xpack.esql.plan.logical.EsRelation;
+import org.elasticsearch.xpack.esql.plan.logical.LogicalPlan;
+import org.elasticsearch.xpack.esql.rule.Rule;
+
+import java.util.ArrayList;
+
+/**
+ * Merges unmapped fields into the output of the ES relation. This marking is necessary for the block loaders to force loading from _source
+ * if the field is unmapped.
+ */
+public class PropgateUnmappedFields extends Rule<LogicalPlan, LogicalPlan> {
+    @Override
+    public LogicalPlan apply(LogicalPlan logicalPlan) {
+        if (logicalPlan instanceof EsRelation) {
+            return logicalPlan;
+        }
+        var unmappedFields = new AttributeSet();
+        logicalPlan.forEachExpressionDown(FieldAttribute.class, fa -> {
+            if (fa.field() instanceof PotentiallyUnmappedKeywordEsField) {
+                unmappedFields.add(fa);
+            }
+        });
+        return unmappedFields.isEmpty()
+            ? logicalPlan
+            : logicalPlan.transformUp(
+                EsRelation.class,
+                er -> er.withAttributes(NamedExpressions.mergeOutputAttributes(new ArrayList<>(unmappedFields), er.output()))
+            );
+    }
+}

+ 8 - 2
x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/optimizer/rules/logical/local/ReplaceMissingFieldWithNull.java

@@ -15,6 +15,7 @@ import org.elasticsearch.xpack.esql.core.expression.FieldAttribute;
 import org.elasticsearch.xpack.esql.core.expression.Literal;
 import org.elasticsearch.xpack.esql.core.expression.NamedExpression;
 import org.elasticsearch.xpack.esql.core.type.DataType;
+import org.elasticsearch.xpack.esql.core.type.PotentiallyUnmappedKeywordEsField;
 import org.elasticsearch.xpack.esql.optimizer.LocalLogicalOptimizerContext;
 import org.elasticsearch.xpack.esql.plan.logical.Aggregate;
 import org.elasticsearch.xpack.esql.plan.logical.EsRelation;
@@ -70,7 +71,10 @@ public class ReplaceMissingFieldWithNull extends ParameterizedRule<LogicalPlan,
 
             for (NamedExpression projection : projections) {
                 // Do not use the attribute name, this can deviate from the field name for union types.
-                if (projection instanceof FieldAttribute f && stats.exists(f.fieldName()) == false && joinAttributes.contains(f) == false) {
+                if (projection instanceof FieldAttribute f
+                    && stats.exists(f.fieldName()) == false
+                    && joinAttributes.contains(f) == false
+                    && f.field() instanceof PotentiallyUnmappedKeywordEsField == false) {
                     // TODO: Should do a searchStats lookup for join attributes instead of just ignoring them here
                     // See TransportSearchShardsAction
                     DataType dt = f.dataType();
@@ -105,7 +109,9 @@ public class ReplaceMissingFieldWithNull extends ParameterizedRule<LogicalPlan,
                     // Do not use the attribute name, this can deviate from the field name for union types.
                     // Also skip fields from lookup indices because we do not have stats for these.
                     // TODO: We do have stats for lookup indices in case they are being used in the FROM clause; this can be refined.
-                    f -> stats.exists(f.fieldName()) || lookupFields.contains(f) ? f : Literal.of(f, null)
+                    f -> f.field() instanceof PotentiallyUnmappedKeywordEsField || (stats.exists(f.fieldName()) || lookupFields.contains(f))
+                        ? f
+                        : Literal.of(f, null)
                 );
             }
 

Fișier diff suprimat deoarece este prea mare
+ 15 - 0
x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/parser/EsqlBaseLexer.interp


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

@@ -27,37 +27,38 @@ public class EsqlBaseLexer extends LexerConfig {
   public static final int
     DISSECT=1, DROP=2, ENRICH=3, EVAL=4, EXPLAIN=5, FROM=6, GROK=7, KEEP=8, 
     LIMIT=9, MV_EXPAND=10, RENAME=11, ROW=12, SHOW=13, SORT=14, STATS=15, 
-    WHERE=16, JOIN_LOOKUP=17, DEV_CHANGE_POINT=18, DEV_INLINESTATS=19, DEV_LOOKUP=20, 
-    DEV_METRICS=21, DEV_JOIN_FULL=22, DEV_JOIN_LEFT=23, DEV_JOIN_RIGHT=24, 
-    UNKNOWN_CMD=25, LINE_COMMENT=26, MULTILINE_COMMENT=27, WS=28, PIPE=29, 
-    QUOTED_STRING=30, INTEGER_LITERAL=31, DECIMAL_LITERAL=32, BY=33, AND=34, 
-    ASC=35, ASSIGN=36, CAST_OP=37, COLON=38, COMMA=39, DESC=40, DOT=41, FALSE=42, 
-    FIRST=43, IN=44, IS=45, LAST=46, LIKE=47, LP=48, NOT=49, NULL=50, NULLS=51, 
-    OR=52, PARAM=53, RLIKE=54, RP=55, TRUE=56, EQ=57, CIEQ=58, NEQ=59, LT=60, 
-    LTE=61, GT=62, GTE=63, PLUS=64, MINUS=65, ASTERISK=66, SLASH=67, PERCENT=68, 
-    LEFT_BRACES=69, RIGHT_BRACES=70, NAMED_OR_POSITIONAL_PARAM=71, OPENING_BRACKET=72, 
-    CLOSING_BRACKET=73, UNQUOTED_IDENTIFIER=74, QUOTED_IDENTIFIER=75, EXPR_LINE_COMMENT=76, 
-    EXPR_MULTILINE_COMMENT=77, EXPR_WS=78, EXPLAIN_WS=79, EXPLAIN_LINE_COMMENT=80, 
-    EXPLAIN_MULTILINE_COMMENT=81, METADATA=82, UNQUOTED_SOURCE=83, FROM_LINE_COMMENT=84, 
-    FROM_MULTILINE_COMMENT=85, FROM_WS=86, ID_PATTERN=87, PROJECT_LINE_COMMENT=88, 
-    PROJECT_MULTILINE_COMMENT=89, PROJECT_WS=90, AS=91, RENAME_LINE_COMMENT=92, 
-    RENAME_MULTILINE_COMMENT=93, RENAME_WS=94, ON=95, WITH=96, ENRICH_POLICY_NAME=97, 
-    ENRICH_LINE_COMMENT=98, ENRICH_MULTILINE_COMMENT=99, ENRICH_WS=100, ENRICH_FIELD_LINE_COMMENT=101, 
-    ENRICH_FIELD_MULTILINE_COMMENT=102, ENRICH_FIELD_WS=103, MVEXPAND_LINE_COMMENT=104, 
-    MVEXPAND_MULTILINE_COMMENT=105, MVEXPAND_WS=106, INFO=107, SHOW_LINE_COMMENT=108, 
-    SHOW_MULTILINE_COMMENT=109, SHOW_WS=110, SETTING=111, SETTING_LINE_COMMENT=112, 
-    SETTTING_MULTILINE_COMMENT=113, SETTING_WS=114, LOOKUP_LINE_COMMENT=115, 
-    LOOKUP_MULTILINE_COMMENT=116, LOOKUP_WS=117, LOOKUP_FIELD_LINE_COMMENT=118, 
-    LOOKUP_FIELD_MULTILINE_COMMENT=119, LOOKUP_FIELD_WS=120, JOIN=121, USING=122, 
-    JOIN_LINE_COMMENT=123, JOIN_MULTILINE_COMMENT=124, JOIN_WS=125, METRICS_LINE_COMMENT=126, 
-    METRICS_MULTILINE_COMMENT=127, METRICS_WS=128, CLOSING_METRICS_LINE_COMMENT=129, 
-    CLOSING_METRICS_MULTILINE_COMMENT=130, CLOSING_METRICS_WS=131, CHANGE_POINT_LINE_COMMENT=132, 
-    CHANGE_POINT_MULTILINE_COMMENT=133, CHANGE_POINT_WS=134;
+    WHERE=16, JOIN_LOOKUP=17, DEV_CHANGE_POINT=18, DEV_INLINESTATS=19, DEV_INSIST=20, 
+    DEV_LOOKUP=21, DEV_METRICS=22, DEV_JOIN_FULL=23, DEV_JOIN_LEFT=24, DEV_JOIN_RIGHT=25, 
+    UNKNOWN_CMD=26, LINE_COMMENT=27, MULTILINE_COMMENT=28, WS=29, PIPE=30, 
+    QUOTED_STRING=31, INTEGER_LITERAL=32, DECIMAL_LITERAL=33, BY=34, AND=35, 
+    ASC=36, ASSIGN=37, CAST_OP=38, COLON=39, COMMA=40, DESC=41, DOT=42, FALSE=43, 
+    FIRST=44, IN=45, IS=46, LAST=47, LIKE=48, LP=49, NOT=50, NULL=51, NULLS=52, 
+    OR=53, PARAM=54, RLIKE=55, RP=56, TRUE=57, EQ=58, CIEQ=59, NEQ=60, LT=61, 
+    LTE=62, GT=63, GTE=64, PLUS=65, MINUS=66, ASTERISK=67, SLASH=68, PERCENT=69, 
+    LEFT_BRACES=70, RIGHT_BRACES=71, NAMED_OR_POSITIONAL_PARAM=72, OPENING_BRACKET=73, 
+    CLOSING_BRACKET=74, UNQUOTED_IDENTIFIER=75, QUOTED_IDENTIFIER=76, EXPR_LINE_COMMENT=77, 
+    EXPR_MULTILINE_COMMENT=78, EXPR_WS=79, EXPLAIN_WS=80, EXPLAIN_LINE_COMMENT=81, 
+    EXPLAIN_MULTILINE_COMMENT=82, METADATA=83, UNQUOTED_SOURCE=84, FROM_LINE_COMMENT=85, 
+    FROM_MULTILINE_COMMENT=86, FROM_WS=87, ID_PATTERN=88, PROJECT_LINE_COMMENT=89, 
+    PROJECT_MULTILINE_COMMENT=90, PROJECT_WS=91, AS=92, RENAME_LINE_COMMENT=93, 
+    RENAME_MULTILINE_COMMENT=94, RENAME_WS=95, ON=96, WITH=97, ENRICH_POLICY_NAME=98, 
+    ENRICH_LINE_COMMENT=99, ENRICH_MULTILINE_COMMENT=100, ENRICH_WS=101, ENRICH_FIELD_LINE_COMMENT=102, 
+    ENRICH_FIELD_MULTILINE_COMMENT=103, ENRICH_FIELD_WS=104, MVEXPAND_LINE_COMMENT=105, 
+    MVEXPAND_MULTILINE_COMMENT=106, MVEXPAND_WS=107, INFO=108, SHOW_LINE_COMMENT=109, 
+    SHOW_MULTILINE_COMMENT=110, SHOW_WS=111, SETTING=112, SETTING_LINE_COMMENT=113, 
+    SETTTING_MULTILINE_COMMENT=114, SETTING_WS=115, LOOKUP_LINE_COMMENT=116, 
+    LOOKUP_MULTILINE_COMMENT=117, LOOKUP_WS=118, LOOKUP_FIELD_LINE_COMMENT=119, 
+    LOOKUP_FIELD_MULTILINE_COMMENT=120, LOOKUP_FIELD_WS=121, JOIN=122, USING=123, 
+    JOIN_LINE_COMMENT=124, JOIN_MULTILINE_COMMENT=125, JOIN_WS=126, METRICS_LINE_COMMENT=127, 
+    METRICS_MULTILINE_COMMENT=128, METRICS_WS=129, CLOSING_METRICS_LINE_COMMENT=130, 
+    CLOSING_METRICS_MULTILINE_COMMENT=131, CLOSING_METRICS_WS=132, CHANGE_POINT_LINE_COMMENT=133, 
+    CHANGE_POINT_MULTILINE_COMMENT=134, CHANGE_POINT_WS=135, INSIST_WS=136, 
+    INSIST_LINE_COMMENT=137, INSIST_MULTILINE_COMMENT=138;
   public static final int
     EXPRESSION_MODE=1, EXPLAIN_MODE=2, FROM_MODE=3, PROJECT_MODE=4, RENAME_MODE=5, 
     ENRICH_MODE=6, ENRICH_FIELD_MODE=7, MVEXPAND_MODE=8, SHOW_MODE=9, SETTING_MODE=10, 
     LOOKUP_MODE=11, LOOKUP_FIELD_MODE=12, JOIN_MODE=13, METRICS_MODE=14, CLOSING_METRICS_MODE=15, 
-    CHANGE_POINT_MODE=16;
+    CHANGE_POINT_MODE=16, INSIST_MODE=17;
   public static String[] channelNames = {
     "DEFAULT_TOKEN_CHANNEL", "HIDDEN"
   };
@@ -66,22 +67,22 @@ public class EsqlBaseLexer extends LexerConfig {
     "DEFAULT_MODE", "EXPRESSION_MODE", "EXPLAIN_MODE", "FROM_MODE", "PROJECT_MODE", 
     "RENAME_MODE", "ENRICH_MODE", "ENRICH_FIELD_MODE", "MVEXPAND_MODE", "SHOW_MODE", 
     "SETTING_MODE", "LOOKUP_MODE", "LOOKUP_FIELD_MODE", "JOIN_MODE", "METRICS_MODE", 
-    "CLOSING_METRICS_MODE", "CHANGE_POINT_MODE"
+    "CLOSING_METRICS_MODE", "CHANGE_POINT_MODE", "INSIST_MODE"
   };
 
   private static String[] makeRuleNames() {
     return new String[] {
       "DISSECT", "DROP", "ENRICH", "EVAL", "EXPLAIN", "FROM", "GROK", "KEEP", 
       "LIMIT", "MV_EXPAND", "RENAME", "ROW", "SHOW", "SORT", "STATS", "WHERE", 
-      "JOIN_LOOKUP", "DEV_CHANGE_POINT", "DEV_INLINESTATS", "DEV_LOOKUP", "DEV_METRICS", 
-      "DEV_JOIN_FULL", "DEV_JOIN_LEFT", "DEV_JOIN_RIGHT", "UNKNOWN_CMD", "LINE_COMMENT", 
-      "MULTILINE_COMMENT", "WS", "PIPE", "DIGIT", "LETTER", "ESCAPE_SEQUENCE", 
-      "UNESCAPED_CHARS", "EXPONENT", "ASPERAND", "BACKQUOTE", "BACKQUOTE_BLOCK", 
-      "UNDERSCORE", "UNQUOTED_ID_BODY", "QUOTED_STRING", "INTEGER_LITERAL", 
-      "DECIMAL_LITERAL", "BY", "AND", "ASC", "ASSIGN", "CAST_OP", "COLON", 
-      "COMMA", "DESC", "DOT", "FALSE", "FIRST", "IN", "IS", "LAST", "LIKE", 
-      "LP", "NOT", "NULL", "NULLS", "OR", "PARAM", "RLIKE", "RP", "TRUE", "EQ", 
-      "CIEQ", "NEQ", "LT", "LTE", "GT", "GTE", "PLUS", "MINUS", "ASTERISK", 
+      "JOIN_LOOKUP", "DEV_CHANGE_POINT", "DEV_INLINESTATS", "DEV_INSIST", "DEV_LOOKUP", 
+      "DEV_METRICS", "DEV_JOIN_FULL", "DEV_JOIN_LEFT", "DEV_JOIN_RIGHT", "UNKNOWN_CMD", 
+      "LINE_COMMENT", "MULTILINE_COMMENT", "WS", "PIPE", "DIGIT", "LETTER", 
+      "ESCAPE_SEQUENCE", "UNESCAPED_CHARS", "EXPONENT", "ASPERAND", "BACKQUOTE", 
+      "BACKQUOTE_BLOCK", "UNDERSCORE", "UNQUOTED_ID_BODY", "QUOTED_STRING", 
+      "INTEGER_LITERAL", "DECIMAL_LITERAL", "BY", "AND", "ASC", "ASSIGN", "CAST_OP", 
+      "COLON", "COMMA", "DESC", "DOT", "FALSE", "FIRST", "IN", "IS", "LAST", 
+      "LIKE", "LP", "NOT", "NULL", "NULLS", "OR", "PARAM", "RLIKE", "RP", "TRUE", 
+      "EQ", "CIEQ", "NEQ", "LT", "LTE", "GT", "GTE", "PLUS", "MINUS", "ASTERISK", 
       "SLASH", "PERCENT", "LEFT_BRACES", "RIGHT_BRACES", "NESTED_WHERE", "NAMED_OR_POSITIONAL_PARAM", 
       "OPENING_BRACKET", "CLOSING_BRACKET", "UNQUOTED_IDENTIFIER", "QUOTED_ID", 
       "QUOTED_IDENTIFIER", "EXPR_LINE_COMMENT", "EXPR_MULTILINE_COMMENT", "EXPR_WS", 
@@ -120,7 +121,9 @@ public class EsqlBaseLexer extends LexerConfig {
       "CLOSING_METRICS_UNQUOTED_IDENTIFIER", "CLOSING_METRICS_BY", "CLOSING_METRICS_PIPE", 
       "CHANGE_POINT_PIPE", "CHANGE_POINT_ON", "CHANGE_POINT_AS", "CHANGE_POINT_DOT", 
       "CHANGE_POINT_COMMA", "CHANGE_POINT_QUOTED_IDENTIFIER", "CHANGE_POINT_UNQUOTED_IDENTIFIER", 
-      "CHANGE_POINT_LINE_COMMENT", "CHANGE_POINT_MULTILINE_COMMENT", "CHANGE_POINT_WS"
+      "CHANGE_POINT_LINE_COMMENT", "CHANGE_POINT_MULTILINE_COMMENT", "CHANGE_POINT_WS", 
+      "INSIST_PIPE", "INSIST_IDENTIFIER", "INSIST_WS", "INSIST_LINE_COMMENT", 
+      "INSIST_MULTILINE_COMMENT"
     };
   }
   public static final String[] ruleNames = makeRuleNames();
@@ -130,7 +133,7 @@ public class EsqlBaseLexer extends LexerConfig {
       null, "'dissect'", "'drop'", "'enrich'", "'eval'", "'explain'", "'from'", 
       "'grok'", "'keep'", "'limit'", "'mv_expand'", "'rename'", "'row'", "'show'", 
       "'sort'", "'stats'", "'where'", "'lookup'", null, null, null, null, null, 
-      null, null, null, null, null, null, "'|'", null, null, null, "'by'", 
+      null, null, null, null, null, null, null, "'|'", null, null, null, "'by'", 
       "'and'", "'asc'", "'='", "'::'", "':'", "','", "'desc'", "'.'", "'false'", 
       "'first'", "'in'", "'is'", "'last'", "'like'", "'('", "'not'", "'null'", 
       "'nulls'", "'or'", "'?'", "'rlike'", "')'", "'true'", "'=='", "'=~'", 
@@ -147,13 +150,13 @@ public class EsqlBaseLexer extends LexerConfig {
     return new String[] {
       null, "DISSECT", "DROP", "ENRICH", "EVAL", "EXPLAIN", "FROM", "GROK", 
       "KEEP", "LIMIT", "MV_EXPAND", "RENAME", "ROW", "SHOW", "SORT", "STATS", 
-      "WHERE", "JOIN_LOOKUP", "DEV_CHANGE_POINT", "DEV_INLINESTATS", "DEV_LOOKUP", 
-      "DEV_METRICS", "DEV_JOIN_FULL", "DEV_JOIN_LEFT", "DEV_JOIN_RIGHT", "UNKNOWN_CMD", 
-      "LINE_COMMENT", "MULTILINE_COMMENT", "WS", "PIPE", "QUOTED_STRING", "INTEGER_LITERAL", 
-      "DECIMAL_LITERAL", "BY", "AND", "ASC", "ASSIGN", "CAST_OP", "COLON", 
-      "COMMA", "DESC", "DOT", "FALSE", "FIRST", "IN", "IS", "LAST", "LIKE", 
-      "LP", "NOT", "NULL", "NULLS", "OR", "PARAM", "RLIKE", "RP", "TRUE", "EQ", 
-      "CIEQ", "NEQ", "LT", "LTE", "GT", "GTE", "PLUS", "MINUS", "ASTERISK", 
+      "WHERE", "JOIN_LOOKUP", "DEV_CHANGE_POINT", "DEV_INLINESTATS", "DEV_INSIST", 
+      "DEV_LOOKUP", "DEV_METRICS", "DEV_JOIN_FULL", "DEV_JOIN_LEFT", "DEV_JOIN_RIGHT", 
+      "UNKNOWN_CMD", "LINE_COMMENT", "MULTILINE_COMMENT", "WS", "PIPE", "QUOTED_STRING", 
+      "INTEGER_LITERAL", "DECIMAL_LITERAL", "BY", "AND", "ASC", "ASSIGN", "CAST_OP", 
+      "COLON", "COMMA", "DESC", "DOT", "FALSE", "FIRST", "IN", "IS", "LAST", 
+      "LIKE", "LP", "NOT", "NULL", "NULLS", "OR", "PARAM", "RLIKE", "RP", "TRUE", 
+      "EQ", "CIEQ", "NEQ", "LT", "LTE", "GT", "GTE", "PLUS", "MINUS", "ASTERISK", 
       "SLASH", "PERCENT", "LEFT_BRACES", "RIGHT_BRACES", "NAMED_OR_POSITIONAL_PARAM", 
       "OPENING_BRACKET", "CLOSING_BRACKET", "UNQUOTED_IDENTIFIER", "QUOTED_IDENTIFIER", 
       "EXPR_LINE_COMMENT", "EXPR_MULTILINE_COMMENT", "EXPR_WS", "EXPLAIN_WS", 
@@ -171,7 +174,8 @@ public class EsqlBaseLexer extends LexerConfig {
       "JOIN", "USING", "JOIN_LINE_COMMENT", "JOIN_MULTILINE_COMMENT", "JOIN_WS", 
       "METRICS_LINE_COMMENT", "METRICS_MULTILINE_COMMENT", "METRICS_WS", "CLOSING_METRICS_LINE_COMMENT", 
       "CLOSING_METRICS_MULTILINE_COMMENT", "CLOSING_METRICS_WS", "CHANGE_POINT_LINE_COMMENT", 
-      "CHANGE_POINT_MULTILINE_COMMENT", "CHANGE_POINT_WS"
+      "CHANGE_POINT_MULTILINE_COMMENT", "CHANGE_POINT_WS", "INSIST_WS", "INSIST_LINE_COMMENT", 
+      "INSIST_MULTILINE_COMMENT"
     };
   }
   private static final String[] _SYMBOLIC_NAMES = makeSymbolicNames();
@@ -241,14 +245,16 @@ public class EsqlBaseLexer extends LexerConfig {
     case 18:
       return DEV_INLINESTATS_sempred((RuleContext)_localctx, predIndex);
     case 19:
-      return DEV_LOOKUP_sempred((RuleContext)_localctx, predIndex);
+      return DEV_INSIST_sempred((RuleContext)_localctx, predIndex);
     case 20:
-      return DEV_METRICS_sempred((RuleContext)_localctx, predIndex);
+      return DEV_LOOKUP_sempred((RuleContext)_localctx, predIndex);
     case 21:
-      return DEV_JOIN_FULL_sempred((RuleContext)_localctx, predIndex);
+      return DEV_METRICS_sempred((RuleContext)_localctx, predIndex);
     case 22:
-      return DEV_JOIN_LEFT_sempred((RuleContext)_localctx, predIndex);
+      return DEV_JOIN_FULL_sempred((RuleContext)_localctx, predIndex);
     case 23:
+      return DEV_JOIN_LEFT_sempred((RuleContext)_localctx, predIndex);
+    case 24:
       return DEV_JOIN_RIGHT_sempred((RuleContext)_localctx, predIndex);
     }
     return true;
@@ -267,1143 +273,1180 @@ public class EsqlBaseLexer extends LexerConfig {
     }
     return true;
   }
-  private boolean DEV_LOOKUP_sempred(RuleContext _localctx, int predIndex) {
+  private boolean DEV_INSIST_sempred(RuleContext _localctx, int predIndex) {
     switch (predIndex) {
     case 2:
       return this.isDevVersion();
     }
     return true;
   }
-  private boolean DEV_METRICS_sempred(RuleContext _localctx, int predIndex) {
+  private boolean DEV_LOOKUP_sempred(RuleContext _localctx, int predIndex) {
     switch (predIndex) {
     case 3:
       return this.isDevVersion();
     }
     return true;
   }
-  private boolean DEV_JOIN_FULL_sempred(RuleContext _localctx, int predIndex) {
+  private boolean DEV_METRICS_sempred(RuleContext _localctx, int predIndex) {
     switch (predIndex) {
     case 4:
       return this.isDevVersion();
     }
     return true;
   }
-  private boolean DEV_JOIN_LEFT_sempred(RuleContext _localctx, int predIndex) {
+  private boolean DEV_JOIN_FULL_sempred(RuleContext _localctx, int predIndex) {
     switch (predIndex) {
     case 5:
       return this.isDevVersion();
     }
     return true;
   }
-  private boolean DEV_JOIN_RIGHT_sempred(RuleContext _localctx, int predIndex) {
+  private boolean DEV_JOIN_LEFT_sempred(RuleContext _localctx, int predIndex) {
     switch (predIndex) {
     case 6:
       return this.isDevVersion();
     }
     return true;
   }
+  private boolean DEV_JOIN_RIGHT_sempred(RuleContext _localctx, int predIndex) {
+    switch (predIndex) {
+    case 7:
+      return this.isDevVersion();
+    }
+    return true;
+  }
 
   public static final String _serializedATN =
-    "\u0004\u0000\u0086\u0699\u0006\uffff\uffff\u0006\uffff\uffff\u0006\uffff"+
+    "\u0004\u0000\u008a\u06c7\u0006\uffff\uffff\u0006\uffff\uffff\u0006\uffff"+
     "\uffff\u0006\uffff\uffff\u0006\uffff\uffff\u0006\uffff\uffff\u0006\uffff"+
     "\uffff\u0006\uffff\uffff\u0006\uffff\uffff\u0006\uffff\uffff\u0006\uffff"+
     "\uffff\u0006\uffff\uffff\u0006\uffff\uffff\u0006\uffff\uffff\u0006\uffff"+
-    "\uffff\u0006\uffff\uffff\u0006\uffff\uffff\u0002\u0000\u0007\u0000\u0002"+
-    "\u0001\u0007\u0001\u0002\u0002\u0007\u0002\u0002\u0003\u0007\u0003\u0002"+
-    "\u0004\u0007\u0004\u0002\u0005\u0007\u0005\u0002\u0006\u0007\u0006\u0002"+
-    "\u0007\u0007\u0007\u0002\b\u0007\b\u0002\t\u0007\t\u0002\n\u0007\n\u0002"+
-    "\u000b\u0007\u000b\u0002\f\u0007\f\u0002\r\u0007\r\u0002\u000e\u0007\u000e"+
-    "\u0002\u000f\u0007\u000f\u0002\u0010\u0007\u0010\u0002\u0011\u0007\u0011"+
-    "\u0002\u0012\u0007\u0012\u0002\u0013\u0007\u0013\u0002\u0014\u0007\u0014"+
-    "\u0002\u0015\u0007\u0015\u0002\u0016\u0007\u0016\u0002\u0017\u0007\u0017"+
-    "\u0002\u0018\u0007\u0018\u0002\u0019\u0007\u0019\u0002\u001a\u0007\u001a"+
-    "\u0002\u001b\u0007\u001b\u0002\u001c\u0007\u001c\u0002\u001d\u0007\u001d"+
-    "\u0002\u001e\u0007\u001e\u0002\u001f\u0007\u001f\u0002 \u0007 \u0002!"+
-    "\u0007!\u0002\"\u0007\"\u0002#\u0007#\u0002$\u0007$\u0002%\u0007%\u0002"+
-    "&\u0007&\u0002\'\u0007\'\u0002(\u0007(\u0002)\u0007)\u0002*\u0007*\u0002"+
-    "+\u0007+\u0002,\u0007,\u0002-\u0007-\u0002.\u0007.\u0002/\u0007/\u0002"+
-    "0\u00070\u00021\u00071\u00022\u00072\u00023\u00073\u00024\u00074\u0002"+
-    "5\u00075\u00026\u00076\u00027\u00077\u00028\u00078\u00029\u00079\u0002"+
-    ":\u0007:\u0002;\u0007;\u0002<\u0007<\u0002=\u0007=\u0002>\u0007>\u0002"+
-    "?\u0007?\u0002@\u0007@\u0002A\u0007A\u0002B\u0007B\u0002C\u0007C\u0002"+
-    "D\u0007D\u0002E\u0007E\u0002F\u0007F\u0002G\u0007G\u0002H\u0007H\u0002"+
-    "I\u0007I\u0002J\u0007J\u0002K\u0007K\u0002L\u0007L\u0002M\u0007M\u0002"+
-    "N\u0007N\u0002O\u0007O\u0002P\u0007P\u0002Q\u0007Q\u0002R\u0007R\u0002"+
-    "S\u0007S\u0002T\u0007T\u0002U\u0007U\u0002V\u0007V\u0002W\u0007W\u0002"+
-    "X\u0007X\u0002Y\u0007Y\u0002Z\u0007Z\u0002[\u0007[\u0002\\\u0007\\\u0002"+
-    "]\u0007]\u0002^\u0007^\u0002_\u0007_\u0002`\u0007`\u0002a\u0007a\u0002"+
-    "b\u0007b\u0002c\u0007c\u0002d\u0007d\u0002e\u0007e\u0002f\u0007f\u0002"+
-    "g\u0007g\u0002h\u0007h\u0002i\u0007i\u0002j\u0007j\u0002k\u0007k\u0002"+
-    "l\u0007l\u0002m\u0007m\u0002n\u0007n\u0002o\u0007o\u0002p\u0007p\u0002"+
-    "q\u0007q\u0002r\u0007r\u0002s\u0007s\u0002t\u0007t\u0002u\u0007u\u0002"+
-    "v\u0007v\u0002w\u0007w\u0002x\u0007x\u0002y\u0007y\u0002z\u0007z\u0002"+
-    "{\u0007{\u0002|\u0007|\u0002}\u0007}\u0002~\u0007~\u0002\u007f\u0007\u007f"+
-    "\u0002\u0080\u0007\u0080\u0002\u0081\u0007\u0081\u0002\u0082\u0007\u0082"+
-    "\u0002\u0083\u0007\u0083\u0002\u0084\u0007\u0084\u0002\u0085\u0007\u0085"+
-    "\u0002\u0086\u0007\u0086\u0002\u0087\u0007\u0087\u0002\u0088\u0007\u0088"+
-    "\u0002\u0089\u0007\u0089\u0002\u008a\u0007\u008a\u0002\u008b\u0007\u008b"+
-    "\u0002\u008c\u0007\u008c\u0002\u008d\u0007\u008d\u0002\u008e\u0007\u008e"+
-    "\u0002\u008f\u0007\u008f\u0002\u0090\u0007\u0090\u0002\u0091\u0007\u0091"+
-    "\u0002\u0092\u0007\u0092\u0002\u0093\u0007\u0093\u0002\u0094\u0007\u0094"+
-    "\u0002\u0095\u0007\u0095\u0002\u0096\u0007\u0096\u0002\u0097\u0007\u0097"+
-    "\u0002\u0098\u0007\u0098\u0002\u0099\u0007\u0099\u0002\u009a\u0007\u009a"+
-    "\u0002\u009b\u0007\u009b\u0002\u009c\u0007\u009c\u0002\u009d\u0007\u009d"+
-    "\u0002\u009e\u0007\u009e\u0002\u009f\u0007\u009f\u0002\u00a0\u0007\u00a0"+
-    "\u0002\u00a1\u0007\u00a1\u0002\u00a2\u0007\u00a2\u0002\u00a3\u0007\u00a3"+
-    "\u0002\u00a4\u0007\u00a4\u0002\u00a5\u0007\u00a5\u0002\u00a6\u0007\u00a6"+
-    "\u0002\u00a7\u0007\u00a7\u0002\u00a8\u0007\u00a8\u0002\u00a9\u0007\u00a9"+
-    "\u0002\u00aa\u0007\u00aa\u0002\u00ab\u0007\u00ab\u0002\u00ac\u0007\u00ac"+
-    "\u0002\u00ad\u0007\u00ad\u0002\u00ae\u0007\u00ae\u0002\u00af\u0007\u00af"+
-    "\u0002\u00b0\u0007\u00b0\u0002\u00b1\u0007\u00b1\u0002\u00b2\u0007\u00b2"+
-    "\u0002\u00b3\u0007\u00b3\u0002\u00b4\u0007\u00b4\u0002\u00b5\u0007\u00b5"+
-    "\u0002\u00b6\u0007\u00b6\u0002\u00b7\u0007\u00b7\u0002\u00b8\u0007\u00b8"+
-    "\u0002\u00b9\u0007\u00b9\u0002\u00ba\u0007\u00ba\u0002\u00bb\u0007\u00bb"+
-    "\u0002\u00bc\u0007\u00bc\u0002\u00bd\u0007\u00bd\u0002\u00be\u0007\u00be"+
-    "\u0002\u00bf\u0007\u00bf\u0002\u00c0\u0007\u00c0\u0002\u00c1\u0007\u00c1"+
-    "\u0002\u00c2\u0007\u00c2\u0002\u00c3\u0007\u00c3\u0002\u00c4\u0007\u00c4"+
-    "\u0002\u00c5\u0007\u00c5\u0002\u00c6\u0007\u00c6\u0002\u00c7\u0007\u00c7"+
-    "\u0002\u00c8\u0007\u00c8\u0002\u00c9\u0007\u00c9\u0002\u00ca\u0007\u00ca"+
-    "\u0002\u00cb\u0007\u00cb\u0002\u00cc\u0007\u00cc\u0002\u00cd\u0007\u00cd"+
-    "\u0002\u00ce\u0007\u00ce\u0002\u00cf\u0007\u00cf\u0002\u00d0\u0007\u00d0"+
-    "\u0002\u00d1\u0007\u00d1\u0002\u00d2\u0007\u00d2\u0002\u00d3\u0007\u00d3"+
-    "\u0002\u00d4\u0007\u00d4\u0002\u00d5\u0007\u00d5\u0002\u00d6\u0007\u00d6"+
-    "\u0002\u00d7\u0007\u00d7\u0002\u00d8\u0007\u00d8\u0002\u00d9\u0007\u00d9"+
-    "\u0002\u00da\u0007\u00da\u0002\u00db\u0007\u00db\u0002\u00dc\u0007\u00dc"+
-    "\u0002\u00dd\u0007\u00dd\u0002\u00de\u0007\u00de\u0002\u00df\u0007\u00df"+
-    "\u0002\u00e0\u0007\u00e0\u0002\u00e1\u0007\u00e1\u0002\u00e2\u0007\u00e2"+
-    "\u0002\u00e3\u0007\u00e3\u0001\u0000\u0001\u0000\u0001\u0000\u0001\u0000"+
-    "\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\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\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\b\u0001"+
-    "\t\u0001\t\u0001\t\u0001\t\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\n\u0001\n\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\r\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\u000e\u0001\u000f\u0001\u000f\u0001\u000f\u0001\u000f\u0001\u000f"+
-    "\u0001\u000f\u0001\u000f\u0001\u000f\u0001\u0010\u0001\u0010\u0001\u0010"+
+    "\uffff\u0006\uffff\uffff\u0006\uffff\uffff\u0006\uffff\uffff\u0002\u0000"+
+    "\u0007\u0000\u0002\u0001\u0007\u0001\u0002\u0002\u0007\u0002\u0002\u0003"+
+    "\u0007\u0003\u0002\u0004\u0007\u0004\u0002\u0005\u0007\u0005\u0002\u0006"+
+    "\u0007\u0006\u0002\u0007\u0007\u0007\u0002\b\u0007\b\u0002\t\u0007\t\u0002"+
+    "\n\u0007\n\u0002\u000b\u0007\u000b\u0002\f\u0007\f\u0002\r\u0007\r\u0002"+
+    "\u000e\u0007\u000e\u0002\u000f\u0007\u000f\u0002\u0010\u0007\u0010\u0002"+
+    "\u0011\u0007\u0011\u0002\u0012\u0007\u0012\u0002\u0013\u0007\u0013\u0002"+
+    "\u0014\u0007\u0014\u0002\u0015\u0007\u0015\u0002\u0016\u0007\u0016\u0002"+
+    "\u0017\u0007\u0017\u0002\u0018\u0007\u0018\u0002\u0019\u0007\u0019\u0002"+
+    "\u001a\u0007\u001a\u0002\u001b\u0007\u001b\u0002\u001c\u0007\u001c\u0002"+
+    "\u001d\u0007\u001d\u0002\u001e\u0007\u001e\u0002\u001f\u0007\u001f\u0002"+
+    " \u0007 \u0002!\u0007!\u0002\"\u0007\"\u0002#\u0007#\u0002$\u0007$\u0002"+
+    "%\u0007%\u0002&\u0007&\u0002\'\u0007\'\u0002(\u0007(\u0002)\u0007)\u0002"+
+    "*\u0007*\u0002+\u0007+\u0002,\u0007,\u0002-\u0007-\u0002.\u0007.\u0002"+
+    "/\u0007/\u00020\u00070\u00021\u00071\u00022\u00072\u00023\u00073\u0002"+
+    "4\u00074\u00025\u00075\u00026\u00076\u00027\u00077\u00028\u00078\u0002"+
+    "9\u00079\u0002:\u0007:\u0002;\u0007;\u0002<\u0007<\u0002=\u0007=\u0002"+
+    ">\u0007>\u0002?\u0007?\u0002@\u0007@\u0002A\u0007A\u0002B\u0007B\u0002"+
+    "C\u0007C\u0002D\u0007D\u0002E\u0007E\u0002F\u0007F\u0002G\u0007G\u0002"+
+    "H\u0007H\u0002I\u0007I\u0002J\u0007J\u0002K\u0007K\u0002L\u0007L\u0002"+
+    "M\u0007M\u0002N\u0007N\u0002O\u0007O\u0002P\u0007P\u0002Q\u0007Q\u0002"+
+    "R\u0007R\u0002S\u0007S\u0002T\u0007T\u0002U\u0007U\u0002V\u0007V\u0002"+
+    "W\u0007W\u0002X\u0007X\u0002Y\u0007Y\u0002Z\u0007Z\u0002[\u0007[\u0002"+
+    "\\\u0007\\\u0002]\u0007]\u0002^\u0007^\u0002_\u0007_\u0002`\u0007`\u0002"+
+    "a\u0007a\u0002b\u0007b\u0002c\u0007c\u0002d\u0007d\u0002e\u0007e\u0002"+
+    "f\u0007f\u0002g\u0007g\u0002h\u0007h\u0002i\u0007i\u0002j\u0007j\u0002"+
+    "k\u0007k\u0002l\u0007l\u0002m\u0007m\u0002n\u0007n\u0002o\u0007o\u0002"+
+    "p\u0007p\u0002q\u0007q\u0002r\u0007r\u0002s\u0007s\u0002t\u0007t\u0002"+
+    "u\u0007u\u0002v\u0007v\u0002w\u0007w\u0002x\u0007x\u0002y\u0007y\u0002"+
+    "z\u0007z\u0002{\u0007{\u0002|\u0007|\u0002}\u0007}\u0002~\u0007~\u0002"+
+    "\u007f\u0007\u007f\u0002\u0080\u0007\u0080\u0002\u0081\u0007\u0081\u0002"+
+    "\u0082\u0007\u0082\u0002\u0083\u0007\u0083\u0002\u0084\u0007\u0084\u0002"+
+    "\u0085\u0007\u0085\u0002\u0086\u0007\u0086\u0002\u0087\u0007\u0087\u0002"+
+    "\u0088\u0007\u0088\u0002\u0089\u0007\u0089\u0002\u008a\u0007\u008a\u0002"+
+    "\u008b\u0007\u008b\u0002\u008c\u0007\u008c\u0002\u008d\u0007\u008d\u0002"+
+    "\u008e\u0007\u008e\u0002\u008f\u0007\u008f\u0002\u0090\u0007\u0090\u0002"+
+    "\u0091\u0007\u0091\u0002\u0092\u0007\u0092\u0002\u0093\u0007\u0093\u0002"+
+    "\u0094\u0007\u0094\u0002\u0095\u0007\u0095\u0002\u0096\u0007\u0096\u0002"+
+    "\u0097\u0007\u0097\u0002\u0098\u0007\u0098\u0002\u0099\u0007\u0099\u0002"+
+    "\u009a\u0007\u009a\u0002\u009b\u0007\u009b\u0002\u009c\u0007\u009c\u0002"+
+    "\u009d\u0007\u009d\u0002\u009e\u0007\u009e\u0002\u009f\u0007\u009f\u0002"+
+    "\u00a0\u0007\u00a0\u0002\u00a1\u0007\u00a1\u0002\u00a2\u0007\u00a2\u0002"+
+    "\u00a3\u0007\u00a3\u0002\u00a4\u0007\u00a4\u0002\u00a5\u0007\u00a5\u0002"+
+    "\u00a6\u0007\u00a6\u0002\u00a7\u0007\u00a7\u0002\u00a8\u0007\u00a8\u0002"+
+    "\u00a9\u0007\u00a9\u0002\u00aa\u0007\u00aa\u0002\u00ab\u0007\u00ab\u0002"+
+    "\u00ac\u0007\u00ac\u0002\u00ad\u0007\u00ad\u0002\u00ae\u0007\u00ae\u0002"+
+    "\u00af\u0007\u00af\u0002\u00b0\u0007\u00b0\u0002\u00b1\u0007\u00b1\u0002"+
+    "\u00b2\u0007\u00b2\u0002\u00b3\u0007\u00b3\u0002\u00b4\u0007\u00b4\u0002"+
+    "\u00b5\u0007\u00b5\u0002\u00b6\u0007\u00b6\u0002\u00b7\u0007\u00b7\u0002"+
+    "\u00b8\u0007\u00b8\u0002\u00b9\u0007\u00b9\u0002\u00ba\u0007\u00ba\u0002"+
+    "\u00bb\u0007\u00bb\u0002\u00bc\u0007\u00bc\u0002\u00bd\u0007\u00bd\u0002"+
+    "\u00be\u0007\u00be\u0002\u00bf\u0007\u00bf\u0002\u00c0\u0007\u00c0\u0002"+
+    "\u00c1\u0007\u00c1\u0002\u00c2\u0007\u00c2\u0002\u00c3\u0007\u00c3\u0002"+
+    "\u00c4\u0007\u00c4\u0002\u00c5\u0007\u00c5\u0002\u00c6\u0007\u00c6\u0002"+
+    "\u00c7\u0007\u00c7\u0002\u00c8\u0007\u00c8\u0002\u00c9\u0007\u00c9\u0002"+
+    "\u00ca\u0007\u00ca\u0002\u00cb\u0007\u00cb\u0002\u00cc\u0007\u00cc\u0002"+
+    "\u00cd\u0007\u00cd\u0002\u00ce\u0007\u00ce\u0002\u00cf\u0007\u00cf\u0002"+
+    "\u00d0\u0007\u00d0\u0002\u00d1\u0007\u00d1\u0002\u00d2\u0007\u00d2\u0002"+
+    "\u00d3\u0007\u00d3\u0002\u00d4\u0007\u00d4\u0002\u00d5\u0007\u00d5\u0002"+
+    "\u00d6\u0007\u00d6\u0002\u00d7\u0007\u00d7\u0002\u00d8\u0007\u00d8\u0002"+
+    "\u00d9\u0007\u00d9\u0002\u00da\u0007\u00da\u0002\u00db\u0007\u00db\u0002"+
+    "\u00dc\u0007\u00dc\u0002\u00dd\u0007\u00dd\u0002\u00de\u0007\u00de\u0002"+
+    "\u00df\u0007\u00df\u0002\u00e0\u0007\u00e0\u0002\u00e1\u0007\u00e1\u0002"+
+    "\u00e2\u0007\u00e2\u0002\u00e3\u0007\u00e3\u0002\u00e4\u0007\u00e4\u0002"+
+    "\u00e5\u0007\u00e5\u0002\u00e6\u0007\u00e6\u0002\u00e7\u0007\u00e7\u0002"+
+    "\u00e8\u0007\u00e8\u0002\u00e9\u0007\u00e9\u0001\u0000\u0001\u0000\u0001"+
+    "\u0000\u0001\u0000\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\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\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\b\u0001\t\u0001\t\u0001\t\u0001\t\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\n\u0001\n\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\r\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\u000e\u0001\u000f\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\u0010\u0001\u0011\u0001\u0011\u0001\u0011\u0001\u0011\u0001\u0011"+
     "\u0001\u0011\u0001\u0011\u0001\u0011\u0001\u0011\u0001\u0011\u0001\u0011"+
-    "\u0001\u0011\u0001\u0011\u0001\u0011\u0001\u0011\u0001\u0011\u0001\u0011"+
-    "\u0001\u0011\u0001\u0011\u0001\u0011\u0001\u0011\u0001\u0012\u0001\u0012"+
+    "\u0001\u0011\u0001\u0011\u0001\u0011\u0001\u0011\u0001\u0011\u0001\u0012"+
     "\u0001\u0012\u0001\u0012\u0001\u0012\u0001\u0012\u0001\u0012\u0001\u0012"+
     "\u0001\u0012\u0001\u0012\u0001\u0012\u0001\u0012\u0001\u0012\u0001\u0012"+
-    "\u0001\u0012\u0001\u0013\u0001\u0013\u0001\u0013\u0001\u0013\u0001\u0013"+
+    "\u0001\u0012\u0001\u0012\u0001\u0013\u0001\u0013\u0001\u0013\u0001\u0013"+
     "\u0001\u0013\u0001\u0013\u0001\u0013\u0001\u0013\u0001\u0013\u0001\u0013"+
-    "\u0001\u0013\u0001\u0014\u0001\u0014\u0001\u0014\u0001\u0014\u0001\u0014"+
+    "\u0001\u0013\u0001\u0013\u0001\u0014\u0001\u0014\u0001\u0014\u0001\u0014"+
     "\u0001\u0014\u0001\u0014\u0001\u0014\u0001\u0014\u0001\u0014\u0001\u0014"+
+    "\u0001\u0014\u0001\u0014\u0001\u0015\u0001\u0015\u0001\u0015\u0001\u0015"+
     "\u0001\u0015\u0001\u0015\u0001\u0015\u0001\u0015\u0001\u0015\u0001\u0015"+
-    "\u0001\u0015\u0001\u0015\u0001\u0016\u0001\u0016\u0001\u0016\u0001\u0016"+
-    "\u0001\u0016\u0001\u0016\u0001\u0016\u0001\u0016\u0001\u0017\u0001\u0017"+
-    "\u0001\u0017\u0001\u0017\u0001\u0017\u0001\u0017\u0001\u0017\u0001\u0017"+
-    "\u0001\u0017\u0001\u0018\u0004\u0018\u02b4\b\u0018\u000b\u0018\f\u0018"+
-    "\u02b5\u0001\u0018\u0001\u0018\u0001\u0019\u0001\u0019\u0001\u0019\u0001"+
-    "\u0019\u0005\u0019\u02be\b\u0019\n\u0019\f\u0019\u02c1\t\u0019\u0001\u0019"+
-    "\u0003\u0019\u02c4\b\u0019\u0001\u0019\u0003\u0019\u02c7\b\u0019\u0001"+
-    "\u0019\u0001\u0019\u0001\u001a\u0001\u001a\u0001\u001a\u0001\u001a\u0001"+
-    "\u001a\u0005\u001a\u02d0\b\u001a\n\u001a\f\u001a\u02d3\t\u001a\u0001\u001a"+
-    "\u0001\u001a\u0001\u001a\u0001\u001a\u0001\u001a\u0001\u001b\u0004\u001b"+
-    "\u02db\b\u001b\u000b\u001b\f\u001b\u02dc\u0001\u001b\u0001\u001b\u0001"+
-    "\u001c\u0001\u001c\u0001\u001c\u0001\u001c\u0001\u001d\u0001\u001d\u0001"+
-    "\u001e\u0001\u001e\u0001\u001f\u0001\u001f\u0001\u001f\u0001 \u0001 \u0001"+
-    "!\u0001!\u0003!\u02f0\b!\u0001!\u0004!\u02f3\b!\u000b!\f!\u02f4\u0001"+
-    "\"\u0001\"\u0001#\u0001#\u0001$\u0001$\u0001$\u0003$\u02fe\b$\u0001%\u0001"+
-    "%\u0001&\u0001&\u0001&\u0003&\u0305\b&\u0001\'\u0001\'\u0001\'\u0005\'"+
-    "\u030a\b\'\n\'\f\'\u030d\t\'\u0001\'\u0001\'\u0001\'\u0001\'\u0001\'\u0001"+
-    "\'\u0005\'\u0315\b\'\n\'\f\'\u0318\t\'\u0001\'\u0001\'\u0001\'\u0001\'"+
-    "\u0001\'\u0003\'\u031f\b\'\u0001\'\u0003\'\u0322\b\'\u0003\'\u0324\b\'"+
-    "\u0001(\u0004(\u0327\b(\u000b(\f(\u0328\u0001)\u0004)\u032c\b)\u000b)"+
-    "\f)\u032d\u0001)\u0001)\u0005)\u0332\b)\n)\f)\u0335\t)\u0001)\u0001)\u0004"+
-    ")\u0339\b)\u000b)\f)\u033a\u0001)\u0004)\u033e\b)\u000b)\f)\u033f\u0001"+
-    ")\u0001)\u0005)\u0344\b)\n)\f)\u0347\t)\u0003)\u0349\b)\u0001)\u0001)"+
-    "\u0001)\u0001)\u0004)\u034f\b)\u000b)\f)\u0350\u0001)\u0001)\u0003)\u0355"+
-    "\b)\u0001*\u0001*\u0001*\u0001+\u0001+\u0001+\u0001+\u0001,\u0001,\u0001"+
-    ",\u0001,\u0001-\u0001-\u0001.\u0001.\u0001.\u0001/\u0001/\u00010\u0001"+
-    "0\u00011\u00011\u00011\u00011\u00011\u00012\u00012\u00013\u00013\u0001"+
-    "3\u00013\u00013\u00013\u00014\u00014\u00014\u00014\u00014\u00014\u0001"+
-    "5\u00015\u00015\u00016\u00016\u00016\u00017\u00017\u00017\u00017\u0001"+
-    "7\u00018\u00018\u00018\u00018\u00018\u00019\u00019\u0001:\u0001:\u0001"+
-    ":\u0001:\u0001;\u0001;\u0001;\u0001;\u0001;\u0001<\u0001<\u0001<\u0001"+
-    "<\u0001<\u0001<\u0001=\u0001=\u0001=\u0001>\u0001>\u0001?\u0001?\u0001"+
-    "?\u0001?\u0001?\u0001?\u0001@\u0001@\u0001A\u0001A\u0001A\u0001A\u0001"+
-    "A\u0001B\u0001B\u0001B\u0001C\u0001C\u0001C\u0001D\u0001D\u0001D\u0001"+
-    "E\u0001E\u0001F\u0001F\u0001F\u0001G\u0001G\u0001H\u0001H\u0001H\u0001"+
-    "I\u0001I\u0001J\u0001J\u0001K\u0001K\u0001L\u0001L\u0001M\u0001M\u0001"+
-    "N\u0001N\u0001O\u0001O\u0001P\u0001P\u0001P\u0001P\u0001Q\u0001Q\u0001"+
-    "Q\u0003Q\u03d9\bQ\u0001Q\u0005Q\u03dc\bQ\nQ\fQ\u03df\tQ\u0001Q\u0001Q"+
-    "\u0004Q\u03e3\bQ\u000bQ\fQ\u03e4\u0003Q\u03e7\bQ\u0001R\u0001R\u0001R"+
-    "\u0001R\u0001R\u0001S\u0001S\u0001S\u0001S\u0001S\u0001T\u0001T\u0005"+
-    "T\u03f5\bT\nT\fT\u03f8\tT\u0001T\u0001T\u0003T\u03fc\bT\u0001T\u0004T"+
-    "\u03ff\bT\u000bT\fT\u0400\u0003T\u0403\bT\u0001U\u0001U\u0004U\u0407\b"+
-    "U\u000bU\fU\u0408\u0001U\u0001U\u0001V\u0001V\u0001W\u0001W\u0001W\u0001"+
-    "W\u0001X\u0001X\u0001X\u0001X\u0001Y\u0001Y\u0001Y\u0001Y\u0001Z\u0001"+
-    "Z\u0001Z\u0001Z\u0001Z\u0001[\u0001[\u0001[\u0001[\u0001[\u0001\\\u0001"+
-    "\\\u0001\\\u0001\\\u0001]\u0001]\u0001]\u0001]\u0001^\u0001^\u0001^\u0001"+
-    "^\u0001_\u0001_\u0001_\u0001_\u0001_\u0001`\u0001`\u0001`\u0001`\u0001"+
-    "a\u0001a\u0001a\u0001a\u0001b\u0001b\u0001b\u0001b\u0001c\u0001c\u0001"+
-    "c\u0001c\u0001d\u0001d\u0001d\u0001d\u0001e\u0001e\u0001e\u0001e\u0001"+
-    "e\u0001e\u0001e\u0001e\u0001e\u0001f\u0001f\u0001f\u0003f\u0456\bf\u0001"+
-    "g\u0004g\u0459\bg\u000bg\fg\u045a\u0001h\u0001h\u0001h\u0001h\u0001i\u0001"+
-    "i\u0001i\u0001i\u0001j\u0001j\u0001j\u0001j\u0001k\u0001k\u0001k\u0001"+
-    "k\u0001l\u0001l\u0001l\u0001l\u0001m\u0001m\u0001m\u0001m\u0001m\u0001"+
-    "n\u0001n\u0001n\u0001n\u0001o\u0001o\u0001o\u0001o\u0001p\u0001p\u0001"+
-    "p\u0001p\u0001q\u0001q\u0001q\u0001q\u0001r\u0001r\u0001r\u0001r\u0003"+
-    "r\u048a\br\u0001s\u0001s\u0003s\u048e\bs\u0001s\u0005s\u0491\bs\ns\fs"+
-    "\u0494\ts\u0001s\u0001s\u0003s\u0498\bs\u0001s\u0004s\u049b\bs\u000bs"+
-    "\fs\u049c\u0003s\u049f\bs\u0001t\u0001t\u0004t\u04a3\bt\u000bt\ft\u04a4"+
-    "\u0001u\u0001u\u0001u\u0001u\u0001v\u0001v\u0001v\u0001v\u0001w\u0001"+
-    "w\u0001w\u0001w\u0001x\u0001x\u0001x\u0001x\u0001x\u0001y\u0001y\u0001"+
-    "y\u0001y\u0001z\u0001z\u0001z\u0001z\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\u0015\u0001\u0016\u0001\u0016\u0001\u0016\u0001\u0016\u0001\u0016"+
+    "\u0001\u0016\u0001\u0016\u0001\u0016\u0001\u0017\u0001\u0017\u0001\u0017"+
+    "\u0001\u0017\u0001\u0017\u0001\u0017\u0001\u0017\u0001\u0017\u0001\u0018"+
+    "\u0001\u0018\u0001\u0018\u0001\u0018\u0001\u0018\u0001\u0018\u0001\u0018"+
+    "\u0001\u0018\u0001\u0018\u0001\u0019\u0004\u0019\u02cd\b\u0019\u000b\u0019"+
+    "\f\u0019\u02ce\u0001\u0019\u0001\u0019\u0001\u001a\u0001\u001a\u0001\u001a"+
+    "\u0001\u001a\u0005\u001a\u02d7\b\u001a\n\u001a\f\u001a\u02da\t\u001a\u0001"+
+    "\u001a\u0003\u001a\u02dd\b\u001a\u0001\u001a\u0003\u001a\u02e0\b\u001a"+
+    "\u0001\u001a\u0001\u001a\u0001\u001b\u0001\u001b\u0001\u001b\u0001\u001b"+
+    "\u0001\u001b\u0005\u001b\u02e9\b\u001b\n\u001b\f\u001b\u02ec\t\u001b\u0001"+
+    "\u001b\u0001\u001b\u0001\u001b\u0001\u001b\u0001\u001b\u0001\u001c\u0004"+
+    "\u001c\u02f4\b\u001c\u000b\u001c\f\u001c\u02f5\u0001\u001c\u0001\u001c"+
+    "\u0001\u001d\u0001\u001d\u0001\u001d\u0001\u001d\u0001\u001e\u0001\u001e"+
+    "\u0001\u001f\u0001\u001f\u0001 \u0001 \u0001 \u0001!\u0001!\u0001\"\u0001"+
+    "\"\u0003\"\u0309\b\"\u0001\"\u0004\"\u030c\b\"\u000b\"\f\"\u030d\u0001"+
+    "#\u0001#\u0001$\u0001$\u0001%\u0001%\u0001%\u0003%\u0317\b%\u0001&\u0001"+
+    "&\u0001\'\u0001\'\u0001\'\u0003\'\u031e\b\'\u0001(\u0001(\u0001(\u0005"+
+    "(\u0323\b(\n(\f(\u0326\t(\u0001(\u0001(\u0001(\u0001(\u0001(\u0001(\u0005"+
+    "(\u032e\b(\n(\f(\u0331\t(\u0001(\u0001(\u0001(\u0001(\u0001(\u0003(\u0338"+
+    "\b(\u0001(\u0003(\u033b\b(\u0003(\u033d\b(\u0001)\u0004)\u0340\b)\u000b"+
+    ")\f)\u0341\u0001*\u0004*\u0345\b*\u000b*\f*\u0346\u0001*\u0001*\u0005"+
+    "*\u034b\b*\n*\f*\u034e\t*\u0001*\u0001*\u0004*\u0352\b*\u000b*\f*\u0353"+
+    "\u0001*\u0004*\u0357\b*\u000b*\f*\u0358\u0001*\u0001*\u0005*\u035d\b*"+
+    "\n*\f*\u0360\t*\u0003*\u0362\b*\u0001*\u0001*\u0001*\u0001*\u0004*\u0368"+
+    "\b*\u000b*\f*\u0369\u0001*\u0001*\u0003*\u036e\b*\u0001+\u0001+\u0001"+
+    "+\u0001,\u0001,\u0001,\u0001,\u0001-\u0001-\u0001-\u0001-\u0001.\u0001"+
+    ".\u0001/\u0001/\u0001/\u00010\u00010\u00011\u00011\u00012\u00012\u0001"+
+    "2\u00012\u00012\u00013\u00013\u00014\u00014\u00014\u00014\u00014\u0001"+
+    "4\u00015\u00015\u00015\u00015\u00015\u00015\u00016\u00016\u00016\u0001"+
+    "7\u00017\u00017\u00018\u00018\u00018\u00018\u00018\u00019\u00019\u0001"+
+    "9\u00019\u00019\u0001:\u0001:\u0001;\u0001;\u0001;\u0001;\u0001<\u0001"+
+    "<\u0001<\u0001<\u0001<\u0001=\u0001=\u0001=\u0001=\u0001=\u0001=\u0001"+
+    ">\u0001>\u0001>\u0001?\u0001?\u0001@\u0001@\u0001@\u0001@\u0001@\u0001"+
+    "@\u0001A\u0001A\u0001B\u0001B\u0001B\u0001B\u0001B\u0001C\u0001C\u0001"+
+    "C\u0001D\u0001D\u0001D\u0001E\u0001E\u0001E\u0001F\u0001F\u0001G\u0001"+
+    "G\u0001G\u0001H\u0001H\u0001I\u0001I\u0001I\u0001J\u0001J\u0001K\u0001"+
+    "K\u0001L\u0001L\u0001M\u0001M\u0001N\u0001N\u0001O\u0001O\u0001P\u0001"+
+    "P\u0001Q\u0001Q\u0001Q\u0001Q\u0001R\u0001R\u0001R\u0003R\u03f2\bR\u0001"+
+    "R\u0005R\u03f5\bR\nR\fR\u03f8\tR\u0001R\u0001R\u0004R\u03fc\bR\u000bR"+
+    "\fR\u03fd\u0003R\u0400\bR\u0001S\u0001S\u0001S\u0001S\u0001S\u0001T\u0001"+
+    "T\u0001T\u0001T\u0001T\u0001U\u0001U\u0005U\u040e\bU\nU\fU\u0411\tU\u0001"+
+    "U\u0001U\u0003U\u0415\bU\u0001U\u0004U\u0418\bU\u000bU\fU\u0419\u0003"+
+    "U\u041c\bU\u0001V\u0001V\u0004V\u0420\bV\u000bV\fV\u0421\u0001V\u0001"+
+    "V\u0001W\u0001W\u0001X\u0001X\u0001X\u0001X\u0001Y\u0001Y\u0001Y\u0001"+
+    "Y\u0001Z\u0001Z\u0001Z\u0001Z\u0001[\u0001[\u0001[\u0001[\u0001[\u0001"+
+    "\\\u0001\\\u0001\\\u0001\\\u0001\\\u0001]\u0001]\u0001]\u0001]\u0001^"+
+    "\u0001^\u0001^\u0001^\u0001_\u0001_\u0001_\u0001_\u0001`\u0001`\u0001"+
+    "`\u0001`\u0001`\u0001a\u0001a\u0001a\u0001a\u0001b\u0001b\u0001b\u0001"+
+    "b\u0001c\u0001c\u0001c\u0001c\u0001d\u0001d\u0001d\u0001d\u0001e\u0001"+
+    "e\u0001e\u0001e\u0001f\u0001f\u0001f\u0001f\u0001f\u0001f\u0001f\u0001"+
+    "f\u0001f\u0001g\u0001g\u0001g\u0003g\u046f\bg\u0001h\u0004h\u0472\bh\u000b"+
+    "h\fh\u0473\u0001i\u0001i\u0001i\u0001i\u0001j\u0001j\u0001j\u0001j\u0001"+
+    "k\u0001k\u0001k\u0001k\u0001l\u0001l\u0001l\u0001l\u0001m\u0001m\u0001"+
+    "m\u0001m\u0001n\u0001n\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\u0003s\u04a3\bs\u0001t\u0001"+
+    "t\u0003t\u04a7\bt\u0001t\u0005t\u04aa\bt\nt\ft\u04ad\tt\u0001t\u0001t"+
+    "\u0003t\u04b1\bt\u0001t\u0004t\u04b4\bt\u000bt\ft\u04b5\u0003t\u04b8\b"+
+    "t\u0001u\u0001u\u0004u\u04bc\bu\u000bu\fu\u04bd\u0001v\u0001v\u0001v\u0001"+
+    "v\u0001w\u0001w\u0001w\u0001w\u0001x\u0001x\u0001x\u0001x\u0001y\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\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\u0084\u0001\u0085\u0001\u0085\u0001\u0085\u0001\u0085"+
     "\u0001\u0085\u0001\u0086\u0001\u0086\u0001\u0086\u0001\u0086\u0001\u0086"+
-    "\u0001\u0086\u0001\u0086\u0001\u0087\u0001\u0087\u0001\u0088\u0004\u0088"+
-    "\u04f8\b\u0088\u000b\u0088\f\u0088\u04f9\u0001\u0088\u0001\u0088\u0003"+
-    "\u0088\u04fe\b\u0088\u0001\u0088\u0004\u0088\u0501\b\u0088\u000b\u0088"+
-    "\f\u0088\u0502\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\u008d\u0001\u008e"+
-    "\u0001\u008e\u0001\u008e\u0001\u008e\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\u0092"+
-    "\u0001\u0092\u0001\u0093\u0001\u0093\u0001\u0093\u0001\u0093\u0001\u0094"+
-    "\u0001\u0094\u0001\u0094\u0001\u0094\u0001\u0095\u0001\u0095\u0001\u0095"+
-    "\u0001\u0095\u0001\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\u009a\u0001\u009a\u0001\u009b\u0001\u009b"+
-    "\u0001\u009b\u0001\u009b\u0001\u009c\u0001\u009c\u0001\u009c\u0001\u009c"+
-    "\u0001\u009d\u0001\u009d\u0001\u009d\u0001\u009d\u0001\u009e\u0001\u009e"+
-    "\u0001\u009e\u0001\u009e\u0001\u009f\u0001\u009f\u0001\u009f\u0001\u009f"+
-    "\u0001\u00a0\u0001\u00a0\u0001\u00a0\u0001\u00a0\u0001\u00a1\u0001\u00a1"+
-    "\u0001\u00a1\u0001\u00a1\u0001\u00a2\u0001\u00a2\u0001\u00a2\u0001\u00a2"+
+    "\u0001\u0087\u0001\u0087\u0001\u0087\u0001\u0087\u0001\u0087\u0001\u0087"+
+    "\u0001\u0087\u0001\u0088\u0001\u0088\u0001\u0089\u0004\u0089\u0511\b\u0089"+
+    "\u000b\u0089\f\u0089\u0512\u0001\u0089\u0001\u0089\u0003\u0089\u0517\b"+
+    "\u0089\u0001\u0089\u0004\u0089\u051a\b\u0089\u000b\u0089\f\u0089\u051b"+
+    "\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\u008e\u0001\u008e\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\u0092\u0001\u0092\u0001\u0093\u0001\u0093\u0001\u0093\u0001\u0093"+
+    "\u0001\u0094\u0001\u0094\u0001\u0094\u0001\u0094\u0001\u0095\u0001\u0095"+
+    "\u0001\u0095\u0001\u0095\u0001\u0096\u0001\u0096\u0001\u0096\u0001\u0096"+
+    "\u0001\u0097\u0001\u0097\u0001\u0097\u0001\u0097\u0001\u0098\u0001\u0098"+
+    "\u0001\u0098\u0001\u0098\u0001\u0099\u0001\u0099\u0001\u0099\u0001\u0099"+
+    "\u0001\u009a\u0001\u009a\u0001\u009a\u0001\u009a\u0001\u009a\u0001\u009b"+
+    "\u0001\u009b\u0001\u009b\u0001\u009b\u0001\u009c\u0001\u009c\u0001\u009c"+
+    "\u0001\u009c\u0001\u009d\u0001\u009d\u0001\u009d\u0001\u009d\u0001\u009e"+
+    "\u0001\u009e\u0001\u009e\u0001\u009e\u0001\u009f\u0001\u009f\u0001\u009f"+
+    "\u0001\u009f\u0001\u00a0\u0001\u00a0\u0001\u00a0\u0001\u00a0\u0001\u00a1"+
+    "\u0001\u00a1\u0001\u00a1\u0001\u00a1\u0001\u00a2\u0001\u00a2\u0001\u00a2"+
     "\u0001\u00a2\u0001\u00a3\u0001\u00a3\u0001\u00a3\u0001\u00a3\u0001\u00a3"+
-    "\u0001\u00a4\u0001\u00a4\u0001\u00a4\u0001\u00a4\u0001\u00a5\u0001\u00a5"+
-    "\u0001\u00a5\u0001\u00a5\u0001\u00a6\u0001\u00a6\u0001\u00a6\u0001\u00a6"+
-    "\u0001\u00a7\u0001\u00a7\u0001\u00a7\u0001\u00a7\u0001\u00a7\u0001\u00a8"+
-    "\u0001\u00a8\u0001\u00a8\u0001\u00a8\u0001\u00a9\u0001\u00a9\u0001\u00a9"+
-    "\u0001\u00a9\u0001\u00a9\u0004\u00a9\u0590\b\u00a9\u000b\u00a9\f\u00a9"+
-    "\u0591\u0001\u00aa\u0001\u00aa\u0001\u00aa\u0001\u00aa\u0001\u00ab\u0001"+
-    "\u00ab\u0001\u00ab\u0001\u00ab\u0001\u00ac\u0001\u00ac\u0001\u00ac\u0001"+
-    "\u00ac\u0001\u00ad\u0001\u00ad\u0001\u00ad\u0001\u00ad\u0001\u00ad\u0001"+
-    "\u00ae\u0001\u00ae\u0001\u00ae\u0001\u00ae\u0001\u00af\u0001\u00af\u0001"+
-    "\u00af\u0001\u00af\u0001\u00b0\u0001\u00b0\u0001\u00b0\u0001\u00b0\u0001"+
-    "\u00b1\u0001\u00b1\u0001\u00b1\u0001\u00b1\u0001\u00b1\u0001\u00b2\u0001"+
-    "\u00b2\u0001\u00b2\u0001\u00b2\u0001\u00b3\u0001\u00b3\u0001\u00b3\u0001"+
-    "\u00b3\u0001\u00b4\u0001\u00b4\u0001\u00b4\u0001\u00b4\u0001\u00b5\u0001"+
-    "\u00b5\u0001\u00b5\u0001\u00b5\u0001\u00b6\u0001\u00b6\u0001\u00b6\u0001"+
-    "\u00b6\u0001\u00b7\u0001\u00b7\u0001\u00b7\u0001\u00b7\u0001\u00b7\u0001"+
-    "\u00b7\u0001\u00b8\u0001\u00b8\u0001\u00b8\u0001\u00b8\u0001\u00b9\u0001"+
-    "\u00b9\u0001\u00b9\u0001\u00b9\u0001\u00ba\u0001\u00ba\u0001\u00ba\u0001"+
-    "\u00ba\u0001\u00bb\u0001\u00bb\u0001\u00bb\u0001\u00bb\u0001\u00bc\u0001"+
-    "\u00bc\u0001\u00bc\u0001\u00bc\u0001\u00bd\u0001\u00bd\u0001\u00bd\u0001"+
-    "\u00bd\u0001\u00be\u0001\u00be\u0001\u00be\u0001\u00be\u0001\u00be\u0001"+
+    "\u0001\u00a4\u0001\u00a4\u0001\u00a4\u0001\u00a4\u0001\u00a4\u0001\u00a5"+
+    "\u0001\u00a5\u0001\u00a5\u0001\u00a5\u0001\u00a6\u0001\u00a6\u0001\u00a6"+
+    "\u0001\u00a6\u0001\u00a7\u0001\u00a7\u0001\u00a7\u0001\u00a7\u0001\u00a8"+
+    "\u0001\u00a8\u0001\u00a8\u0001\u00a8\u0001\u00a8\u0001\u00a9\u0001\u00a9"+
+    "\u0001\u00a9\u0001\u00a9\u0001\u00aa\u0001\u00aa\u0001\u00aa\u0001\u00aa"+
+    "\u0001\u00aa\u0004\u00aa\u05a9\b\u00aa\u000b\u00aa\f\u00aa\u05aa\u0001"+
+    "\u00ab\u0001\u00ab\u0001\u00ab\u0001\u00ab\u0001\u00ac\u0001\u00ac\u0001"+
+    "\u00ac\u0001\u00ac\u0001\u00ad\u0001\u00ad\u0001\u00ad\u0001\u00ad\u0001"+
+    "\u00ae\u0001\u00ae\u0001\u00ae\u0001\u00ae\u0001\u00ae\u0001\u00af\u0001"+
+    "\u00af\u0001\u00af\u0001\u00af\u0001\u00b0\u0001\u00b0\u0001\u00b0\u0001"+
+    "\u00b0\u0001\u00b1\u0001\u00b1\u0001\u00b1\u0001\u00b1\u0001\u00b2\u0001"+
+    "\u00b2\u0001\u00b2\u0001\u00b2\u0001\u00b2\u0001\u00b3\u0001\u00b3\u0001"+
+    "\u00b3\u0001\u00b3\u0001\u00b4\u0001\u00b4\u0001\u00b4\u0001\u00b4\u0001"+
+    "\u00b5\u0001\u00b5\u0001\u00b5\u0001\u00b5\u0001\u00b6\u0001\u00b6\u0001"+
+    "\u00b6\u0001\u00b6\u0001\u00b7\u0001\u00b7\u0001\u00b7\u0001\u00b7\u0001"+
+    "\u00b8\u0001\u00b8\u0001\u00b8\u0001\u00b8\u0001\u00b8\u0001\u00b8\u0001"+
+    "\u00b9\u0001\u00b9\u0001\u00b9\u0001\u00b9\u0001\u00ba\u0001\u00ba\u0001"+
+    "\u00ba\u0001\u00ba\u0001\u00bb\u0001\u00bb\u0001\u00bb\u0001\u00bb\u0001"+
+    "\u00bc\u0001\u00bc\u0001\u00bc\u0001\u00bc\u0001\u00bd\u0001\u00bd\u0001"+
+    "\u00bd\u0001\u00bd\u0001\u00be\u0001\u00be\u0001\u00be\u0001\u00be\u0001"+
     "\u00bf\u0001\u00bf\u0001\u00bf\u0001\u00bf\u0001\u00bf\u0001\u00c0\u0001"+
-    "\u00c0\u0001\u00c0\u0001\u00c0\u0001\u00c1\u0001\u00c1\u0001\u00c1\u0001"+
-    "\u00c1\u0001\u00c1\u0001\u00c1\u0001\u00c2\u0001\u00c2\u0001\u00c2\u0001"+
-    "\u00c2\u0001\u00c2\u0001\u00c2\u0001\u00c2\u0001\u00c2\u0001\u00c2\u0001"+
-    "\u00c3\u0001\u00c3\u0001\u00c3\u0001\u00c3\u0001\u00c4\u0001\u00c4\u0001"+
-    "\u00c4\u0001\u00c4\u0001\u00c5\u0001\u00c5\u0001\u00c5\u0001\u00c5\u0001"+
-    "\u00c6\u0001\u00c6\u0001\u00c6\u0001\u00c6\u0001\u00c7\u0001\u00c7\u0001"+
-    "\u00c7\u0001\u00c7\u0001\u00c8\u0001\u00c8\u0001\u00c8\u0001\u00c8\u0001"+
-    "\u00c9\u0001\u00c9\u0001\u00c9\u0001\u00c9\u0001\u00ca\u0001\u00ca\u0001"+
-    "\u00ca\u0001\u00ca\u0001\u00cb\u0001\u00cb\u0001\u00cb\u0001\u00cb\u0001"+
+    "\u00c0\u0001\u00c0\u0001\u00c0\u0001\u00c0\u0001\u00c1\u0001\u00c1\u0001"+
+    "\u00c1\u0001\u00c1\u0001\u00c2\u0001\u00c2\u0001\u00c2\u0001\u00c2\u0001"+
+    "\u00c2\u0001\u00c2\u0001\u00c3\u0001\u00c3\u0001\u00c3\u0001\u00c3\u0001"+
+    "\u00c3\u0001\u00c3\u0001\u00c3\u0001\u00c3\u0001\u00c3\u0001\u00c4\u0001"+
+    "\u00c4\u0001\u00c4\u0001\u00c4\u0001\u00c5\u0001\u00c5\u0001\u00c5\u0001"+
+    "\u00c5\u0001\u00c6\u0001\u00c6\u0001\u00c6\u0001\u00c6\u0001\u00c7\u0001"+
+    "\u00c7\u0001\u00c7\u0001\u00c7\u0001\u00c8\u0001\u00c8\u0001\u00c8\u0001"+
+    "\u00c8\u0001\u00c9\u0001\u00c9\u0001\u00c9\u0001\u00c9\u0001\u00ca\u0001"+
+    "\u00ca\u0001\u00ca\u0001\u00ca\u0001\u00cb\u0001\u00cb\u0001\u00cb\u0001"+
     "\u00cb\u0001\u00cc\u0001\u00cc\u0001\u00cc\u0001\u00cc\u0001\u00cc\u0001"+
-    "\u00cc\u0001\u00cd\u0001\u00cd\u0001\u00cd\u0001\u00cd\u0001\u00cd\u0001"+
-    "\u00cd\u0001\u00ce\u0001\u00ce\u0001\u00ce\u0001\u00ce\u0001\u00cf\u0001"+
-    "\u00cf\u0001\u00cf\u0001\u00cf\u0001\u00d0\u0001\u00d0\u0001\u00d0\u0001"+
-    "\u00d0\u0001\u00d1\u0001\u00d1\u0001\u00d1\u0001\u00d1\u0001\u00d1\u0001"+
-    "\u00d1\u0001\u00d2\u0001\u00d2\u0001\u00d2\u0001\u00d2\u0001\u00d2\u0001"+
-    "\u00d2\u0001\u00d3\u0001\u00d3\u0001\u00d3\u0001\u00d3\u0001\u00d4\u0001"+
-    "\u00d4\u0001\u00d4\u0001\u00d4\u0001\u00d5\u0001\u00d5\u0001\u00d5\u0001"+
-    "\u00d5\u0001\u00d6\u0001\u00d6\u0001\u00d6\u0001\u00d6\u0001\u00d6\u0001"+
-    "\u00d6\u0001\u00d7\u0001\u00d7\u0001\u00d7\u0001\u00d7\u0001\u00d7\u0001"+
-    "\u00d7\u0001\u00d8\u0001\u00d8\u0001\u00d8\u0001\u00d8\u0001\u00d8\u0001"+
-    "\u00d8\u0001\u00d9\u0001\u00d9\u0001\u00d9\u0001\u00d9\u0001\u00d9\u0001"+
+    "\u00cd\u0001\u00cd\u0001\u00cd\u0001\u00cd\u0001\u00cd\u0001\u00cd\u0001"+
+    "\u00ce\u0001\u00ce\u0001\u00ce\u0001\u00ce\u0001\u00ce\u0001\u00ce\u0001"+
+    "\u00cf\u0001\u00cf\u0001\u00cf\u0001\u00cf\u0001\u00d0\u0001\u00d0\u0001"+
+    "\u00d0\u0001\u00d0\u0001\u00d1\u0001\u00d1\u0001\u00d1\u0001\u00d1\u0001"+
+    "\u00d2\u0001\u00d2\u0001\u00d2\u0001\u00d2\u0001\u00d2\u0001\u00d2\u0001"+
+    "\u00d3\u0001\u00d3\u0001\u00d3\u0001\u00d3\u0001\u00d3\u0001\u00d3\u0001"+
+    "\u00d4\u0001\u00d4\u0001\u00d4\u0001\u00d4\u0001\u00d5\u0001\u00d5\u0001"+
+    "\u00d5\u0001\u00d5\u0001\u00d6\u0001\u00d6\u0001\u00d6\u0001\u00d6\u0001"+
+    "\u00d7\u0001\u00d7\u0001\u00d7\u0001\u00d7\u0001\u00d7\u0001\u00d7\u0001"+
+    "\u00d8\u0001\u00d8\u0001\u00d8\u0001\u00d8\u0001\u00d8\u0001\u00d8\u0001"+
+    "\u00d9\u0001\u00d9\u0001\u00d9\u0001\u00d9\u0001\u00d9\u0001\u00d9\u0001"+
     "\u00da\u0001\u00da\u0001\u00da\u0001\u00da\u0001\u00da\u0001\u00db\u0001"+
-    "\u00db\u0001\u00db\u0001\u00db\u0001\u00dc\u0001\u00dc\u0001\u00dc\u0001"+
-    "\u00dc\u0001\u00dd\u0001\u00dd\u0001\u00dd\u0001\u00dd\u0001\u00de\u0001"+
-    "\u00de\u0001\u00de\u0001\u00de\u0001\u00df\u0001\u00df\u0001\u00df\u0001"+
-    "\u00df\u0001\u00e0\u0001\u00e0\u0001\u00e0\u0001\u00e0\u0001\u00e1\u0001"+
-    "\u00e1\u0001\u00e1\u0001\u00e1\u0001\u00e2\u0001\u00e2\u0001\u00e2\u0001"+
-    "\u00e2\u0001\u00e3\u0001\u00e3\u0001\u00e3\u0001\u00e3\u0002\u02d1\u0316"+
-    "\u0000\u00e4\u0011\u0001\u0013\u0002\u0015\u0003\u0017\u0004\u0019\u0005"+
-    "\u001b\u0006\u001d\u0007\u001f\b!\t#\n%\u000b\'\f)\r+\u000e-\u000f/\u0010"+
-    "1\u00113\u00125\u00137\u00149\u0015;\u0016=\u0017?\u0018A\u0019C\u001a"+
-    "E\u001bG\u001cI\u001dK\u0000M\u0000O\u0000Q\u0000S\u0000U\u0000W\u0000"+
-    "Y\u0000[\u0000]\u0000_\u001ea\u001fc e!g\"i#k$m%o&q\'s(u)w*y+{,}-\u007f"+
-    ".\u0081/\u00830\u00851\u00872\u00893\u008b4\u008d5\u008f6\u00917\u0093"+
-    "8\u00959\u0097:\u0099;\u009b<\u009d=\u009f>\u00a1?\u00a3@\u00a5A\u00a7"+
-    "B\u00a9C\u00abD\u00adE\u00afF\u00b1\u0000\u00b3G\u00b5H\u00b7I\u00b9J"+
-    "\u00bb\u0000\u00bdK\u00bfL\u00c1M\u00c3N\u00c5\u0000\u00c7\u0000\u00c9"+
-    "O\u00cbP\u00cdQ\u00cf\u0000\u00d1\u0000\u00d3\u0000\u00d5\u0000\u00d7"+
-    "\u0000\u00d9\u0000\u00dbR\u00dd\u0000\u00dfS\u00e1\u0000\u00e3\u0000\u00e5"+
-    "T\u00e7U\u00e9V\u00eb\u0000\u00ed\u0000\u00ef\u0000\u00f1\u0000\u00f3"+
-    "\u0000\u00f5\u0000\u00f7\u0000\u00f9W\u00fbX\u00fdY\u00ffZ\u0101\u0000"+
-    "\u0103\u0000\u0105\u0000\u0107\u0000\u0109\u0000\u010b\u0000\u010d[\u010f"+
-    "\u0000\u0111\\\u0113]\u0115^\u0117\u0000\u0119\u0000\u011b_\u011d`\u011f"+
-    "\u0000\u0121a\u0123\u0000\u0125b\u0127c\u0129d\u012b\u0000\u012d\u0000"+
-    "\u012f\u0000\u0131\u0000\u0133\u0000\u0135\u0000\u0137\u0000\u0139\u0000"+
-    "\u013b\u0000\u013de\u013ff\u0141g\u0143\u0000\u0145\u0000\u0147\u0000"+
-    "\u0149\u0000\u014b\u0000\u014d\u0000\u014fh\u0151i\u0153j\u0155\u0000"+
-    "\u0157k\u0159l\u015bm\u015dn\u015f\u0000\u0161\u0000\u0163o\u0165p\u0167"+
-    "q\u0169r\u016b\u0000\u016d\u0000\u016f\u0000\u0171\u0000\u0173\u0000\u0175"+
-    "\u0000\u0177\u0000\u0179s\u017bt\u017du\u017f\u0000\u0181\u0000\u0183"+
-    "\u0000\u0185\u0000\u0187v\u0189w\u018bx\u018d\u0000\u018fy\u0191\u0000"+
-    "\u0193\u0000\u0195z\u0197\u0000\u0199\u0000\u019b\u0000\u019d\u0000\u019f"+
-    "\u0000\u01a1{\u01a3|\u01a5}\u01a7\u0000\u01a9\u0000\u01ab\u0000\u01ad"+
-    "~\u01af\u007f\u01b1\u0080\u01b3\u0000\u01b5\u0000\u01b7\u0081\u01b9\u0082"+
-    "\u01bb\u0083\u01bd\u0000\u01bf\u0000\u01c1\u0000\u01c3\u0000\u01c5\u0000"+
-    "\u01c7\u0000\u01c9\u0000\u01cb\u0000\u01cd\u0000\u01cf\u0000\u01d1\u0000"+
-    "\u01d3\u0084\u01d5\u0085\u01d7\u0086\u0011\u0000\u0001\u0002\u0003\u0004"+
-    "\u0005\u0006\u0007\b\t\n\u000b\f\r\u000e\u000f\u0010$\u0002\u0000DDdd"+
-    "\u0002\u0000IIii\u0002\u0000SSss\u0002\u0000EEee\u0002\u0000CCcc\u0002"+
-    "\u0000TTtt\u0002\u0000RRrr\u0002\u0000OOoo\u0002\u0000PPpp\u0002\u0000"+
-    "NNnn\u0002\u0000HHhh\u0002\u0000VVvv\u0002\u0000AAaa\u0002\u0000LLll\u0002"+
-    "\u0000XXxx\u0002\u0000FFff\u0002\u0000MMmm\u0002\u0000GGgg\u0002\u0000"+
-    "KKkk\u0002\u0000WWww\u0002\u0000UUuu\u0006\u0000\t\n\r\r  //[[]]\u0002"+
-    "\u0000\n\n\r\r\u0003\u0000\t\n\r\r  \u0001\u000009\u0002\u0000AZaz\b\u0000"+
-    "\"\"NNRRTT\\\\nnrrtt\u0004\u0000\n\n\r\r\"\"\\\\\u0002\u0000++--\u0001"+
-    "\u0000``\u0002\u0000BBbb\u0002\u0000YYyy\u000b\u0000\t\n\r\r  \"\",,/"+
-    "/::==[[]]||\u0002\u0000**//\u000b\u0000\t\n\r\r  \"#,,//::<<>?\\\\||\u0002"+
-    "\u0000JJjj\u06b3\u0000\u0011\u0001\u0000\u0000\u0000\u0000\u0013\u0001"+
-    "\u0000\u0000\u0000\u0000\u0015\u0001\u0000\u0000\u0000\u0000\u0017\u0001"+
-    "\u0000\u0000\u0000\u0000\u0019\u0001\u0000\u0000\u0000\u0000\u001b\u0001"+
-    "\u0000\u0000\u0000\u0000\u001d\u0001\u0000\u0000\u0000\u0000\u001f\u0001"+
-    "\u0000\u0000\u0000\u0000!\u0001\u0000\u0000\u0000\u0000#\u0001\u0000\u0000"+
-    "\u0000\u0000%\u0001\u0000\u0000\u0000\u0000\'\u0001\u0000\u0000\u0000"+
-    "\u0000)\u0001\u0000\u0000\u0000\u0000+\u0001\u0000\u0000\u0000\u0000-"+
-    "\u0001\u0000\u0000\u0000\u0000/\u0001\u0000\u0000\u0000\u00001\u0001\u0000"+
-    "\u0000\u0000\u00003\u0001\u0000\u0000\u0000\u00005\u0001\u0000\u0000\u0000"+
-    "\u00007\u0001\u0000\u0000\u0000\u00009\u0001\u0000\u0000\u0000\u0000;"+
-    "\u0001\u0000\u0000\u0000\u0000=\u0001\u0000\u0000\u0000\u0000?\u0001\u0000"+
-    "\u0000\u0000\u0000A\u0001\u0000\u0000\u0000\u0000C\u0001\u0000\u0000\u0000"+
-    "\u0000E\u0001\u0000\u0000\u0000\u0000G\u0001\u0000\u0000\u0000\u0001I"+
-    "\u0001\u0000\u0000\u0000\u0001_\u0001\u0000\u0000\u0000\u0001a\u0001\u0000"+
-    "\u0000\u0000\u0001c\u0001\u0000\u0000\u0000\u0001e\u0001\u0000\u0000\u0000"+
-    "\u0001g\u0001\u0000\u0000\u0000\u0001i\u0001\u0000\u0000\u0000\u0001k"+
-    "\u0001\u0000\u0000\u0000\u0001m\u0001\u0000\u0000\u0000\u0001o\u0001\u0000"+
-    "\u0000\u0000\u0001q\u0001\u0000\u0000\u0000\u0001s\u0001\u0000\u0000\u0000"+
-    "\u0001u\u0001\u0000\u0000\u0000\u0001w\u0001\u0000\u0000\u0000\u0001y"+
-    "\u0001\u0000\u0000\u0000\u0001{\u0001\u0000\u0000\u0000\u0001}\u0001\u0000"+
-    "\u0000\u0000\u0001\u007f\u0001\u0000\u0000\u0000\u0001\u0081\u0001\u0000"+
-    "\u0000\u0000\u0001\u0083\u0001\u0000\u0000\u0000\u0001\u0085\u0001\u0000"+
-    "\u0000\u0000\u0001\u0087\u0001\u0000\u0000\u0000\u0001\u0089\u0001\u0000"+
-    "\u0000\u0000\u0001\u008b\u0001\u0000\u0000\u0000\u0001\u008d\u0001\u0000"+
-    "\u0000\u0000\u0001\u008f\u0001\u0000\u0000\u0000\u0001\u0091\u0001\u0000"+
-    "\u0000\u0000\u0001\u0093\u0001\u0000\u0000\u0000\u0001\u0095\u0001\u0000"+
-    "\u0000\u0000\u0001\u0097\u0001\u0000\u0000\u0000\u0001\u0099\u0001\u0000"+
-    "\u0000\u0000\u0001\u009b\u0001\u0000\u0000\u0000\u0001\u009d\u0001\u0000"+
-    "\u0000\u0000\u0001\u009f\u0001\u0000\u0000\u0000\u0001\u00a1\u0001\u0000"+
-    "\u0000\u0000\u0001\u00a3\u0001\u0000\u0000\u0000\u0001\u00a5\u0001\u0000"+
-    "\u0000\u0000\u0001\u00a7\u0001\u0000\u0000\u0000\u0001\u00a9\u0001\u0000"+
-    "\u0000\u0000\u0001\u00ab\u0001\u0000\u0000\u0000\u0001\u00ad\u0001\u0000"+
-    "\u0000\u0000\u0001\u00af\u0001\u0000\u0000\u0000\u0001\u00b1\u0001\u0000"+
-    "\u0000\u0000\u0001\u00b3\u0001\u0000\u0000\u0000\u0001\u00b5\u0001\u0000"+
-    "\u0000\u0000\u0001\u00b7\u0001\u0000\u0000\u0000\u0001\u00b9\u0001\u0000"+
-    "\u0000\u0000\u0001\u00bd\u0001\u0000\u0000\u0000\u0001\u00bf\u0001\u0000"+
-    "\u0000\u0000\u0001\u00c1\u0001\u0000\u0000\u0000\u0001\u00c3\u0001\u0000"+
-    "\u0000\u0000\u0002\u00c5\u0001\u0000\u0000\u0000\u0002\u00c7\u0001\u0000"+
-    "\u0000\u0000\u0002\u00c9\u0001\u0000\u0000\u0000\u0002\u00cb\u0001\u0000"+
-    "\u0000\u0000\u0002\u00cd\u0001\u0000\u0000\u0000\u0003\u00cf\u0001\u0000"+
-    "\u0000\u0000\u0003\u00d1\u0001\u0000\u0000\u0000\u0003\u00d3\u0001\u0000"+
-    "\u0000\u0000\u0003\u00d5\u0001\u0000\u0000\u0000\u0003\u00d7\u0001\u0000"+
-    "\u0000\u0000\u0003\u00d9\u0001\u0000\u0000\u0000\u0003\u00db\u0001\u0000"+
-    "\u0000\u0000\u0003\u00df\u0001\u0000\u0000\u0000\u0003\u00e1\u0001\u0000"+
-    "\u0000\u0000\u0003\u00e3\u0001\u0000\u0000\u0000\u0003\u00e5\u0001\u0000"+
-    "\u0000\u0000\u0003\u00e7\u0001\u0000\u0000\u0000\u0003\u00e9\u0001\u0000"+
-    "\u0000\u0000\u0004\u00eb\u0001\u0000\u0000\u0000\u0004\u00ed\u0001\u0000"+
-    "\u0000\u0000\u0004\u00ef\u0001\u0000\u0000\u0000\u0004\u00f1\u0001\u0000"+
-    "\u0000\u0000\u0004\u00f3\u0001\u0000\u0000\u0000\u0004\u00f9\u0001\u0000"+
-    "\u0000\u0000\u0004\u00fb\u0001\u0000\u0000\u0000\u0004\u00fd\u0001\u0000"+
-    "\u0000\u0000\u0004\u00ff\u0001\u0000\u0000\u0000\u0005\u0101\u0001\u0000"+
-    "\u0000\u0000\u0005\u0103\u0001\u0000\u0000\u0000\u0005\u0105\u0001\u0000"+
-    "\u0000\u0000\u0005\u0107\u0001\u0000\u0000\u0000\u0005\u0109\u0001\u0000"+
-    "\u0000\u0000\u0005\u010b\u0001\u0000\u0000\u0000\u0005\u010d\u0001\u0000"+
-    "\u0000\u0000\u0005\u010f\u0001\u0000\u0000\u0000\u0005\u0111\u0001\u0000"+
-    "\u0000\u0000\u0005\u0113\u0001\u0000\u0000\u0000\u0005\u0115\u0001\u0000"+
-    "\u0000\u0000\u0006\u0117\u0001\u0000\u0000\u0000\u0006\u0119\u0001\u0000"+
-    "\u0000\u0000\u0006\u011b\u0001\u0000\u0000\u0000\u0006\u011d\u0001\u0000"+
-    "\u0000\u0000\u0006\u0121\u0001\u0000\u0000\u0000\u0006\u0123\u0001\u0000"+
-    "\u0000\u0000\u0006\u0125\u0001\u0000\u0000\u0000\u0006\u0127\u0001\u0000"+
-    "\u0000\u0000\u0006\u0129\u0001\u0000\u0000\u0000\u0007\u012b\u0001\u0000"+
-    "\u0000\u0000\u0007\u012d\u0001\u0000\u0000\u0000\u0007\u012f\u0001\u0000"+
-    "\u0000\u0000\u0007\u0131\u0001\u0000\u0000\u0000\u0007\u0133\u0001\u0000"+
-    "\u0000\u0000\u0007\u0135\u0001\u0000\u0000\u0000\u0007\u0137\u0001\u0000"+
-    "\u0000\u0000\u0007\u0139\u0001\u0000\u0000\u0000\u0007\u013b\u0001\u0000"+
-    "\u0000\u0000\u0007\u013d\u0001\u0000\u0000\u0000\u0007\u013f\u0001\u0000"+
-    "\u0000\u0000\u0007\u0141\u0001\u0000\u0000\u0000\b\u0143\u0001\u0000\u0000"+
-    "\u0000\b\u0145\u0001\u0000\u0000\u0000\b\u0147\u0001\u0000\u0000\u0000"+
-    "\b\u0149\u0001\u0000\u0000\u0000\b\u014b\u0001\u0000\u0000\u0000\b\u014d"+
-    "\u0001\u0000\u0000\u0000\b\u014f\u0001\u0000\u0000\u0000\b\u0151\u0001"+
-    "\u0000\u0000\u0000\b\u0153\u0001\u0000\u0000\u0000\t\u0155\u0001\u0000"+
-    "\u0000\u0000\t\u0157\u0001\u0000\u0000\u0000\t\u0159\u0001\u0000\u0000"+
-    "\u0000\t\u015b\u0001\u0000\u0000\u0000\t\u015d\u0001\u0000\u0000\u0000"+
-    "\n\u015f\u0001\u0000\u0000\u0000\n\u0161\u0001\u0000\u0000\u0000\n\u0163"+
-    "\u0001\u0000\u0000\u0000\n\u0165\u0001\u0000\u0000\u0000\n\u0167\u0001"+
-    "\u0000\u0000\u0000\n\u0169\u0001\u0000\u0000\u0000\u000b\u016b\u0001\u0000"+
-    "\u0000\u0000\u000b\u016d\u0001\u0000\u0000\u0000\u000b\u016f\u0001\u0000"+
-    "\u0000\u0000\u000b\u0171\u0001\u0000\u0000\u0000\u000b\u0173\u0001\u0000"+
-    "\u0000\u0000\u000b\u0175\u0001\u0000\u0000\u0000\u000b\u0177\u0001\u0000"+
-    "\u0000\u0000\u000b\u0179\u0001\u0000\u0000\u0000\u000b\u017b\u0001\u0000"+
-    "\u0000\u0000\u000b\u017d\u0001\u0000\u0000\u0000\f\u017f\u0001\u0000\u0000"+
-    "\u0000\f\u0181\u0001\u0000\u0000\u0000\f\u0183\u0001\u0000\u0000\u0000"+
-    "\f\u0185\u0001\u0000\u0000\u0000\f\u0187\u0001\u0000\u0000\u0000\f\u0189"+
-    "\u0001\u0000\u0000\u0000\f\u018b\u0001\u0000\u0000\u0000\r\u018d\u0001"+
-    "\u0000\u0000\u0000\r\u018f\u0001\u0000\u0000\u0000\r\u0191\u0001\u0000"+
-    "\u0000\u0000\r\u0193\u0001\u0000\u0000\u0000\r\u0195\u0001\u0000\u0000"+
-    "\u0000\r\u0197\u0001\u0000\u0000\u0000\r\u0199\u0001\u0000\u0000\u0000"+
-    "\r\u019b\u0001\u0000\u0000\u0000\r\u019d\u0001\u0000\u0000\u0000\r\u019f"+
-    "\u0001\u0000\u0000\u0000\r\u01a1\u0001\u0000\u0000\u0000\r\u01a3\u0001"+
-    "\u0000\u0000\u0000\r\u01a5\u0001\u0000\u0000\u0000\u000e\u01a7\u0001\u0000"+
-    "\u0000\u0000\u000e\u01a9\u0001\u0000\u0000\u0000\u000e\u01ab\u0001\u0000"+
-    "\u0000\u0000\u000e\u01ad\u0001\u0000\u0000\u0000\u000e\u01af\u0001\u0000"+
-    "\u0000\u0000\u000e\u01b1\u0001\u0000\u0000\u0000\u000f\u01b3\u0001\u0000"+
-    "\u0000\u0000\u000f\u01b5\u0001\u0000\u0000\u0000\u000f\u01b7\u0001\u0000"+
-    "\u0000\u0000\u000f\u01b9\u0001\u0000\u0000\u0000\u000f\u01bb\u0001\u0000"+
-    "\u0000\u0000\u000f\u01bd\u0001\u0000\u0000\u0000\u000f\u01bf\u0001\u0000"+
-    "\u0000\u0000\u000f\u01c1\u0001\u0000\u0000\u0000\u000f\u01c3\u0001\u0000"+
-    "\u0000\u0000\u0010\u01c5\u0001\u0000\u0000\u0000\u0010\u01c7\u0001\u0000"+
-    "\u0000\u0000\u0010\u01c9\u0001\u0000\u0000\u0000\u0010\u01cb\u0001\u0000"+
-    "\u0000\u0000\u0010\u01cd\u0001\u0000\u0000\u0000\u0010\u01cf\u0001\u0000"+
-    "\u0000\u0000\u0010\u01d1\u0001\u0000\u0000\u0000\u0010\u01d3\u0001\u0000"+
-    "\u0000\u0000\u0010\u01d5\u0001\u0000\u0000\u0000\u0010\u01d7\u0001\u0000"+
-    "\u0000\u0000\u0011\u01d9\u0001\u0000\u0000\u0000\u0013\u01e3\u0001\u0000"+
-    "\u0000\u0000\u0015\u01ea\u0001\u0000\u0000\u0000\u0017\u01f3\u0001\u0000"+
-    "\u0000\u0000\u0019\u01fa\u0001\u0000\u0000\u0000\u001b\u0204\u0001\u0000"+
-    "\u0000\u0000\u001d\u020b\u0001\u0000\u0000\u0000\u001f\u0212\u0001\u0000"+
-    "\u0000\u0000!\u0219\u0001\u0000\u0000\u0000#\u0221\u0001\u0000\u0000\u0000"+
-    "%\u022d\u0001\u0000\u0000\u0000\'\u0236\u0001\u0000\u0000\u0000)\u023c"+
-    "\u0001\u0000\u0000\u0000+\u0243\u0001\u0000\u0000\u0000-\u024a\u0001\u0000"+
-    "\u0000\u0000/\u0252\u0001\u0000\u0000\u00001\u025a\u0001\u0000\u0000\u0000"+
-    "3\u0263\u0001\u0000\u0000\u00005\u0273\u0001\u0000\u0000\u00007\u0282"+
-    "\u0001\u0000\u0000\u00009\u028e\u0001\u0000\u0000\u0000;\u0299\u0001\u0000"+
-    "\u0000\u0000=\u02a1\u0001\u0000\u0000\u0000?\u02a9\u0001\u0000\u0000\u0000"+
-    "A\u02b3\u0001\u0000\u0000\u0000C\u02b9\u0001\u0000\u0000\u0000E\u02ca"+
-    "\u0001\u0000\u0000\u0000G\u02da\u0001\u0000\u0000\u0000I\u02e0\u0001\u0000"+
-    "\u0000\u0000K\u02e4\u0001\u0000\u0000\u0000M\u02e6\u0001\u0000\u0000\u0000"+
-    "O\u02e8\u0001\u0000\u0000\u0000Q\u02eb\u0001\u0000\u0000\u0000S\u02ed"+
-    "\u0001\u0000\u0000\u0000U\u02f6\u0001\u0000\u0000\u0000W\u02f8\u0001\u0000"+
-    "\u0000\u0000Y\u02fd\u0001\u0000\u0000\u0000[\u02ff\u0001\u0000\u0000\u0000"+
-    "]\u0304\u0001\u0000\u0000\u0000_\u0323\u0001\u0000\u0000\u0000a\u0326"+
-    "\u0001\u0000\u0000\u0000c\u0354\u0001\u0000\u0000\u0000e\u0356\u0001\u0000"+
-    "\u0000\u0000g\u0359\u0001\u0000\u0000\u0000i\u035d\u0001\u0000\u0000\u0000"+
-    "k\u0361\u0001\u0000\u0000\u0000m\u0363\u0001\u0000\u0000\u0000o\u0366"+
-    "\u0001\u0000\u0000\u0000q\u0368\u0001\u0000\u0000\u0000s\u036a\u0001\u0000"+
-    "\u0000\u0000u\u036f\u0001\u0000\u0000\u0000w\u0371\u0001\u0000\u0000\u0000"+
-    "y\u0377\u0001\u0000\u0000\u0000{\u037d\u0001\u0000\u0000\u0000}\u0380"+
-    "\u0001\u0000\u0000\u0000\u007f\u0383\u0001\u0000\u0000\u0000\u0081\u0388"+
-    "\u0001\u0000\u0000\u0000\u0083\u038d\u0001\u0000\u0000\u0000\u0085\u038f"+
-    "\u0001\u0000\u0000\u0000\u0087\u0393\u0001\u0000\u0000\u0000\u0089\u0398"+
-    "\u0001\u0000\u0000\u0000\u008b\u039e\u0001\u0000\u0000\u0000\u008d\u03a1"+
-    "\u0001\u0000\u0000\u0000\u008f\u03a3\u0001\u0000\u0000\u0000\u0091\u03a9"+
-    "\u0001\u0000\u0000\u0000\u0093\u03ab\u0001\u0000\u0000\u0000\u0095\u03b0"+
-    "\u0001\u0000\u0000\u0000\u0097\u03b3\u0001\u0000\u0000\u0000\u0099\u03b6"+
-    "\u0001\u0000\u0000\u0000\u009b\u03b9\u0001\u0000\u0000\u0000\u009d\u03bb"+
-    "\u0001\u0000\u0000\u0000\u009f\u03be\u0001\u0000\u0000\u0000\u00a1\u03c0"+
-    "\u0001\u0000\u0000\u0000\u00a3\u03c3\u0001\u0000\u0000\u0000\u00a5\u03c5"+
-    "\u0001\u0000\u0000\u0000\u00a7\u03c7\u0001\u0000\u0000\u0000\u00a9\u03c9"+
-    "\u0001\u0000\u0000\u0000\u00ab\u03cb\u0001\u0000\u0000\u0000\u00ad\u03cd"+
-    "\u0001\u0000\u0000\u0000\u00af\u03cf\u0001\u0000\u0000\u0000\u00b1\u03d1"+
-    "\u0001\u0000\u0000\u0000\u00b3\u03e6\u0001\u0000\u0000\u0000\u00b5\u03e8"+
-    "\u0001\u0000\u0000\u0000\u00b7\u03ed\u0001\u0000\u0000\u0000\u00b9\u0402"+
-    "\u0001\u0000\u0000\u0000\u00bb\u0404\u0001\u0000\u0000\u0000\u00bd\u040c"+
-    "\u0001\u0000\u0000\u0000\u00bf\u040e\u0001\u0000\u0000\u0000\u00c1\u0412"+
-    "\u0001\u0000\u0000\u0000\u00c3\u0416\u0001\u0000\u0000\u0000\u00c5\u041a"+
-    "\u0001\u0000\u0000\u0000\u00c7\u041f\u0001\u0000\u0000\u0000\u00c9\u0424"+
-    "\u0001\u0000\u0000\u0000\u00cb\u0428\u0001\u0000\u0000\u0000\u00cd\u042c"+
-    "\u0001\u0000\u0000\u0000\u00cf\u0430\u0001\u0000\u0000\u0000\u00d1\u0435"+
-    "\u0001\u0000\u0000\u0000\u00d3\u0439\u0001\u0000\u0000\u0000\u00d5\u043d"+
-    "\u0001\u0000\u0000\u0000\u00d7\u0441\u0001\u0000\u0000\u0000\u00d9\u0445"+
-    "\u0001\u0000\u0000\u0000\u00db\u0449\u0001\u0000\u0000\u0000\u00dd\u0455"+
-    "\u0001\u0000\u0000\u0000\u00df\u0458\u0001\u0000\u0000\u0000\u00e1\u045c"+
-    "\u0001\u0000\u0000\u0000\u00e3\u0460\u0001\u0000\u0000\u0000\u00e5\u0464"+
-    "\u0001\u0000\u0000\u0000\u00e7\u0468\u0001\u0000\u0000\u0000\u00e9\u046c"+
-    "\u0001\u0000\u0000\u0000\u00eb\u0470\u0001\u0000\u0000\u0000\u00ed\u0475"+
-    "\u0001\u0000\u0000\u0000\u00ef\u0479\u0001\u0000\u0000\u0000\u00f1\u047d"+
-    "\u0001\u0000\u0000\u0000\u00f3\u0481\u0001\u0000\u0000\u0000\u00f5\u0489"+
-    "\u0001\u0000\u0000\u0000\u00f7\u049e\u0001\u0000\u0000\u0000\u00f9\u04a2"+
-    "\u0001\u0000\u0000\u0000\u00fb\u04a6\u0001\u0000\u0000\u0000\u00fd\u04aa"+
-    "\u0001\u0000\u0000\u0000\u00ff\u04ae\u0001\u0000\u0000\u0000\u0101\u04b2"+
-    "\u0001\u0000\u0000\u0000\u0103\u04b7\u0001\u0000\u0000\u0000\u0105\u04bb"+
-    "\u0001\u0000\u0000\u0000\u0107\u04bf\u0001\u0000\u0000\u0000\u0109\u04c3"+
-    "\u0001\u0000\u0000\u0000\u010b\u04c7\u0001\u0000\u0000\u0000\u010d\u04cb"+
-    "\u0001\u0000\u0000\u0000\u010f\u04ce\u0001\u0000\u0000\u0000\u0111\u04d2"+
-    "\u0001\u0000\u0000\u0000\u0113\u04d6\u0001\u0000\u0000\u0000\u0115\u04da"+
-    "\u0001\u0000\u0000\u0000\u0117\u04de\u0001\u0000\u0000\u0000\u0119\u04e3"+
-    "\u0001\u0000\u0000\u0000\u011b\u04e8\u0001\u0000\u0000\u0000\u011d\u04ed"+
-    "\u0001\u0000\u0000\u0000\u011f\u04f4\u0001\u0000\u0000\u0000\u0121\u04fd"+
-    "\u0001\u0000\u0000\u0000\u0123\u0504\u0001\u0000\u0000\u0000\u0125\u0508"+
-    "\u0001\u0000\u0000\u0000\u0127\u050c\u0001\u0000\u0000\u0000\u0129\u0510"+
-    "\u0001\u0000\u0000\u0000\u012b\u0514\u0001\u0000\u0000\u0000\u012d\u051a"+
-    "\u0001\u0000\u0000\u0000\u012f\u051e\u0001\u0000\u0000\u0000\u0131\u0522"+
-    "\u0001\u0000\u0000\u0000\u0133\u0526\u0001\u0000\u0000\u0000\u0135\u052a"+
-    "\u0001\u0000\u0000\u0000\u0137\u052e\u0001\u0000\u0000\u0000\u0139\u0532"+
-    "\u0001\u0000\u0000\u0000\u013b\u0536\u0001\u0000\u0000\u0000\u013d\u053a"+
-    "\u0001\u0000\u0000\u0000\u013f\u053e\u0001\u0000\u0000\u0000\u0141\u0542"+
-    "\u0001\u0000\u0000\u0000\u0143\u0546\u0001\u0000\u0000\u0000\u0145\u054b"+
-    "\u0001\u0000\u0000\u0000\u0147\u054f\u0001\u0000\u0000\u0000\u0149\u0553"+
-    "\u0001\u0000\u0000\u0000\u014b\u0557\u0001\u0000\u0000\u0000\u014d\u055b"+
-    "\u0001\u0000\u0000\u0000\u014f\u055f\u0001\u0000\u0000\u0000\u0151\u0563"+
-    "\u0001\u0000\u0000\u0000\u0153\u0567\u0001\u0000\u0000\u0000\u0155\u056b"+
-    "\u0001\u0000\u0000\u0000\u0157\u0570\u0001\u0000\u0000\u0000\u0159\u0575"+
-    "\u0001\u0000\u0000\u0000\u015b\u0579\u0001\u0000\u0000\u0000\u015d\u057d"+
-    "\u0001\u0000\u0000\u0000\u015f\u0581\u0001\u0000\u0000\u0000\u0161\u0586"+
-    "\u0001\u0000\u0000\u0000\u0163\u058f\u0001\u0000\u0000\u0000\u0165\u0593"+
-    "\u0001\u0000\u0000\u0000\u0167\u0597\u0001\u0000\u0000\u0000\u0169\u059b"+
-    "\u0001\u0000\u0000\u0000\u016b\u059f\u0001\u0000\u0000\u0000\u016d\u05a4"+
-    "\u0001\u0000\u0000\u0000\u016f\u05a8\u0001\u0000\u0000\u0000\u0171\u05ac"+
-    "\u0001\u0000\u0000\u0000\u0173\u05b0\u0001\u0000\u0000\u0000\u0175\u05b5"+
-    "\u0001\u0000\u0000\u0000\u0177\u05b9\u0001\u0000\u0000\u0000\u0179\u05bd"+
-    "\u0001\u0000\u0000\u0000\u017b\u05c1\u0001\u0000\u0000\u0000\u017d\u05c5"+
-    "\u0001\u0000\u0000\u0000\u017f\u05c9\u0001\u0000\u0000\u0000\u0181\u05cf"+
-    "\u0001\u0000\u0000\u0000\u0183\u05d3\u0001\u0000\u0000\u0000\u0185\u05d7"+
-    "\u0001\u0000\u0000\u0000\u0187\u05db\u0001\u0000\u0000\u0000\u0189\u05df"+
-    "\u0001\u0000\u0000\u0000\u018b\u05e3\u0001\u0000\u0000\u0000\u018d\u05e7"+
-    "\u0001\u0000\u0000\u0000\u018f\u05ec\u0001\u0000\u0000\u0000\u0191\u05f1"+
-    "\u0001\u0000\u0000\u0000\u0193\u05f5\u0001\u0000\u0000\u0000\u0195\u05fb"+
-    "\u0001\u0000\u0000\u0000\u0197\u0604\u0001\u0000\u0000\u0000\u0199\u0608"+
-    "\u0001\u0000\u0000\u0000\u019b\u060c\u0001\u0000\u0000\u0000\u019d\u0610"+
-    "\u0001\u0000\u0000\u0000\u019f\u0614\u0001\u0000\u0000\u0000\u01a1\u0618"+
-    "\u0001\u0000\u0000\u0000\u01a3\u061c\u0001\u0000\u0000\u0000\u01a5\u0620"+
-    "\u0001\u0000\u0000\u0000\u01a7\u0624\u0001\u0000\u0000\u0000\u01a9\u0629"+
-    "\u0001\u0000\u0000\u0000\u01ab\u062f\u0001\u0000\u0000\u0000\u01ad\u0635"+
-    "\u0001\u0000\u0000\u0000\u01af\u0639\u0001\u0000\u0000\u0000\u01b1\u063d"+
-    "\u0001\u0000\u0000\u0000\u01b3\u0641\u0001\u0000\u0000\u0000\u01b5\u0647"+
-    "\u0001\u0000\u0000\u0000\u01b7\u064d\u0001\u0000\u0000\u0000\u01b9\u0651"+
-    "\u0001\u0000\u0000\u0000\u01bb\u0655\u0001\u0000\u0000\u0000\u01bd\u0659"+
-    "\u0001\u0000\u0000\u0000\u01bf\u065f\u0001\u0000\u0000\u0000\u01c1\u0665"+
-    "\u0001\u0000\u0000\u0000\u01c3\u066b\u0001\u0000\u0000\u0000\u01c5\u0670"+
-    "\u0001\u0000\u0000\u0000\u01c7\u0675\u0001\u0000\u0000\u0000\u01c9\u0679"+
-    "\u0001\u0000\u0000\u0000\u01cb\u067d\u0001\u0000\u0000\u0000\u01cd\u0681"+
-    "\u0001\u0000\u0000\u0000\u01cf\u0685\u0001\u0000\u0000\u0000\u01d1\u0689"+
-    "\u0001\u0000\u0000\u0000\u01d3\u068d\u0001\u0000\u0000\u0000\u01d5\u0691"+
-    "\u0001\u0000\u0000\u0000\u01d7\u0695\u0001\u0000\u0000\u0000\u01d9\u01da"+
-    "\u0007\u0000\u0000\u0000\u01da\u01db\u0007\u0001\u0000\u0000\u01db\u01dc"+
-    "\u0007\u0002\u0000\u0000\u01dc\u01dd\u0007\u0002\u0000\u0000\u01dd\u01de"+
-    "\u0007\u0003\u0000\u0000\u01de\u01df\u0007\u0004\u0000\u0000\u01df\u01e0"+
-    "\u0007\u0005\u0000\u0000\u01e0\u01e1\u0001\u0000\u0000\u0000\u01e1\u01e2"+
-    "\u0006\u0000\u0000\u0000\u01e2\u0012\u0001\u0000\u0000\u0000\u01e3\u01e4"+
-    "\u0007\u0000\u0000\u0000\u01e4\u01e5\u0007\u0006\u0000\u0000\u01e5\u01e6"+
-    "\u0007\u0007\u0000\u0000\u01e6\u01e7\u0007\b\u0000\u0000\u01e7\u01e8\u0001"+
-    "\u0000\u0000\u0000\u01e8\u01e9\u0006\u0001\u0001\u0000\u01e9\u0014\u0001"+
-    "\u0000\u0000\u0000\u01ea\u01eb\u0007\u0003\u0000\u0000\u01eb\u01ec\u0007"+
-    "\t\u0000\u0000\u01ec\u01ed\u0007\u0006\u0000\u0000\u01ed\u01ee\u0007\u0001"+
-    "\u0000\u0000\u01ee\u01ef\u0007\u0004\u0000\u0000\u01ef\u01f0\u0007\n\u0000"+
-    "\u0000\u01f0\u01f1\u0001\u0000\u0000\u0000\u01f1\u01f2\u0006\u0002\u0002"+
-    "\u0000\u01f2\u0016\u0001\u0000\u0000\u0000\u01f3\u01f4\u0007\u0003\u0000"+
-    "\u0000\u01f4\u01f5\u0007\u000b\u0000\u0000\u01f5\u01f6\u0007\f\u0000\u0000"+
-    "\u01f6\u01f7\u0007\r\u0000\u0000\u01f7\u01f8\u0001\u0000\u0000\u0000\u01f8"+
-    "\u01f9\u0006\u0003\u0000\u0000\u01f9\u0018\u0001\u0000\u0000\u0000\u01fa"+
-    "\u01fb\u0007\u0003\u0000\u0000\u01fb\u01fc\u0007\u000e\u0000\u0000\u01fc"+
-    "\u01fd\u0007\b\u0000\u0000\u01fd\u01fe\u0007\r\u0000\u0000\u01fe\u01ff"+
-    "\u0007\f\u0000\u0000\u01ff\u0200\u0007\u0001\u0000\u0000\u0200\u0201\u0007"+
-    "\t\u0000\u0000\u0201\u0202\u0001\u0000\u0000\u0000\u0202\u0203\u0006\u0004"+
-    "\u0003\u0000\u0203\u001a\u0001\u0000\u0000\u0000\u0204\u0205\u0007\u000f"+
-    "\u0000\u0000\u0205\u0206\u0007\u0006\u0000\u0000\u0206\u0207\u0007\u0007"+
-    "\u0000\u0000\u0207\u0208\u0007\u0010\u0000\u0000\u0208\u0209\u0001\u0000"+
-    "\u0000\u0000\u0209\u020a\u0006\u0005\u0004\u0000\u020a\u001c\u0001\u0000"+
-    "\u0000\u0000\u020b\u020c\u0007\u0011\u0000\u0000\u020c\u020d\u0007\u0006"+
-    "\u0000\u0000\u020d\u020e\u0007\u0007\u0000\u0000\u020e\u020f\u0007\u0012"+
-    "\u0000\u0000\u020f\u0210\u0001\u0000\u0000\u0000\u0210\u0211\u0006\u0006"+
-    "\u0000\u0000\u0211\u001e\u0001\u0000\u0000\u0000\u0212\u0213\u0007\u0012"+
-    "\u0000\u0000\u0213\u0214\u0007\u0003\u0000\u0000\u0214\u0215\u0007\u0003"+
-    "\u0000\u0000\u0215\u0216\u0007\b\u0000\u0000\u0216\u0217\u0001\u0000\u0000"+
-    "\u0000\u0217\u0218\u0006\u0007\u0001\u0000\u0218 \u0001\u0000\u0000\u0000"+
-    "\u0219\u021a\u0007\r\u0000\u0000\u021a\u021b\u0007\u0001\u0000\u0000\u021b"+
-    "\u021c\u0007\u0010\u0000\u0000\u021c\u021d\u0007\u0001\u0000\u0000\u021d"+
-    "\u021e\u0007\u0005\u0000\u0000\u021e\u021f\u0001\u0000\u0000\u0000\u021f"+
-    "\u0220\u0006\b\u0000\u0000\u0220\"\u0001\u0000\u0000\u0000\u0221\u0222"+
-    "\u0007\u0010\u0000\u0000\u0222\u0223\u0007\u000b\u0000\u0000\u0223\u0224"+
-    "\u0005_\u0000\u0000\u0224\u0225\u0007\u0003\u0000\u0000\u0225\u0226\u0007"+
-    "\u000e\u0000\u0000\u0226\u0227\u0007\b\u0000\u0000\u0227\u0228\u0007\f"+
-    "\u0000\u0000\u0228\u0229\u0007\t\u0000\u0000\u0229\u022a\u0007\u0000\u0000"+
-    "\u0000\u022a\u022b\u0001\u0000\u0000\u0000\u022b\u022c\u0006\t\u0005\u0000"+
-    "\u022c$\u0001\u0000\u0000\u0000\u022d\u022e\u0007\u0006\u0000\u0000\u022e"+
-    "\u022f\u0007\u0003\u0000\u0000\u022f\u0230\u0007\t\u0000\u0000\u0230\u0231"+
-    "\u0007\f\u0000\u0000\u0231\u0232\u0007\u0010\u0000\u0000\u0232\u0233\u0007"+
-    "\u0003\u0000\u0000\u0233\u0234\u0001\u0000\u0000\u0000\u0234\u0235\u0006"+
-    "\n\u0006\u0000\u0235&\u0001\u0000\u0000\u0000\u0236\u0237\u0007\u0006"+
-    "\u0000\u0000\u0237\u0238\u0007\u0007\u0000\u0000\u0238\u0239\u0007\u0013"+
-    "\u0000\u0000\u0239\u023a\u0001\u0000\u0000\u0000\u023a\u023b\u0006\u000b"+
-    "\u0000\u0000\u023b(\u0001\u0000\u0000\u0000\u023c\u023d\u0007\u0002\u0000"+
-    "\u0000\u023d\u023e\u0007\n\u0000\u0000\u023e\u023f\u0007\u0007\u0000\u0000"+
-    "\u023f\u0240\u0007\u0013\u0000\u0000\u0240\u0241\u0001\u0000\u0000\u0000"+
-    "\u0241\u0242\u0006\f\u0007\u0000\u0242*\u0001\u0000\u0000\u0000\u0243"+
-    "\u0244\u0007\u0002\u0000\u0000\u0244\u0245\u0007\u0007\u0000\u0000\u0245"+
-    "\u0246\u0007\u0006\u0000\u0000\u0246\u0247\u0007\u0005\u0000\u0000\u0247"+
-    "\u0248\u0001\u0000\u0000\u0000\u0248\u0249\u0006\r\u0000\u0000\u0249,"+
-    "\u0001\u0000\u0000\u0000\u024a\u024b\u0007\u0002\u0000\u0000\u024b\u024c"+
-    "\u0007\u0005\u0000\u0000\u024c\u024d\u0007\f\u0000\u0000\u024d\u024e\u0007"+
-    "\u0005\u0000\u0000\u024e\u024f\u0007\u0002\u0000\u0000\u024f\u0250\u0001"+
-    "\u0000\u0000\u0000\u0250\u0251\u0006\u000e\u0000\u0000\u0251.\u0001\u0000"+
-    "\u0000\u0000\u0252\u0253\u0007\u0013\u0000\u0000\u0253\u0254\u0007\n\u0000"+
-    "\u0000\u0254\u0255\u0007\u0003\u0000\u0000\u0255\u0256\u0007\u0006\u0000"+
-    "\u0000\u0256\u0257\u0007\u0003\u0000\u0000\u0257\u0258\u0001\u0000\u0000"+
-    "\u0000\u0258\u0259\u0006\u000f\u0000\u0000\u02590\u0001\u0000\u0000\u0000"+
-    "\u025a\u025b\u0007\r\u0000\u0000\u025b\u025c\u0007\u0007\u0000\u0000\u025c"+
-    "\u025d\u0007\u0007\u0000\u0000\u025d\u025e\u0007\u0012\u0000\u0000\u025e"+
-    "\u025f\u0007\u0014\u0000\u0000\u025f\u0260\u0007\b\u0000\u0000\u0260\u0261"+
-    "\u0001\u0000\u0000\u0000\u0261\u0262\u0006\u0010\b\u0000\u02622\u0001"+
-    "\u0000\u0000\u0000\u0263\u0264\u0004\u0011\u0000\u0000\u0264\u0265\u0007"+
-    "\u0004\u0000\u0000\u0265\u0266\u0007\n\u0000\u0000\u0266\u0267\u0007\f"+
-    "\u0000\u0000\u0267\u0268\u0007\t\u0000\u0000\u0268\u0269\u0007\u0011\u0000"+
-    "\u0000\u0269\u026a\u0007\u0003\u0000\u0000\u026a\u026b\u0005_\u0000\u0000"+
-    "\u026b\u026c\u0007\b\u0000\u0000\u026c\u026d\u0007\u0007\u0000\u0000\u026d"+
-    "\u026e\u0007\u0001\u0000\u0000\u026e\u026f\u0007\t\u0000\u0000\u026f\u0270"+
-    "\u0007\u0005\u0000\u0000\u0270\u0271\u0001\u0000\u0000\u0000\u0271\u0272"+
-    "\u0006\u0011\t\u0000\u02724\u0001\u0000\u0000\u0000\u0273\u0274\u0004"+
-    "\u0012\u0001\u0000\u0274\u0275\u0007\u0001\u0000\u0000\u0275\u0276\u0007"+
-    "\t\u0000\u0000\u0276\u0277\u0007\r\u0000\u0000\u0277\u0278\u0007\u0001"+
-    "\u0000\u0000\u0278\u0279\u0007\t\u0000\u0000\u0279\u027a\u0007\u0003\u0000"+
-    "\u0000\u027a\u027b\u0007\u0002\u0000\u0000\u027b\u027c\u0007\u0005\u0000"+
-    "\u0000\u027c\u027d\u0007\f\u0000\u0000\u027d\u027e\u0007\u0005\u0000\u0000"+
-    "\u027e\u027f\u0007\u0002\u0000\u0000\u027f\u0280\u0001\u0000\u0000\u0000"+
-    "\u0280\u0281\u0006\u0012\u0000\u0000\u02816\u0001\u0000\u0000\u0000\u0282"+
-    "\u0283\u0004\u0013\u0002\u0000\u0283\u0284\u0007\r\u0000\u0000\u0284\u0285"+
-    "\u0007\u0007\u0000\u0000\u0285\u0286\u0007\u0007\u0000\u0000\u0286\u0287"+
-    "\u0007\u0012\u0000\u0000\u0287\u0288\u0007\u0014\u0000\u0000\u0288\u0289"+
-    "\u0007\b\u0000\u0000\u0289\u028a\u0005_\u0000\u0000\u028a\u028b\u0005"+
-    "\u8001\uf414\u0000\u0000\u028b\u028c\u0001\u0000\u0000\u0000\u028c\u028d"+
-    "\u0006\u0013\n\u0000\u028d8\u0001\u0000\u0000\u0000\u028e\u028f\u0004"+
-    "\u0014\u0003\u0000\u028f\u0290\u0007\u0010\u0000\u0000\u0290\u0291\u0007"+
-    "\u0003\u0000\u0000\u0291\u0292\u0007\u0005\u0000\u0000\u0292\u0293\u0007"+
-    "\u0006\u0000\u0000\u0293\u0294\u0007\u0001\u0000\u0000\u0294\u0295\u0007"+
-    "\u0004\u0000\u0000\u0295\u0296\u0007\u0002\u0000\u0000\u0296\u0297\u0001"+
-    "\u0000\u0000\u0000\u0297\u0298\u0006\u0014\u000b\u0000\u0298:\u0001\u0000"+
-    "\u0000\u0000\u0299\u029a\u0004\u0015\u0004\u0000\u029a\u029b\u0007\u000f"+
-    "\u0000\u0000\u029b\u029c\u0007\u0014\u0000\u0000\u029c\u029d\u0007\r\u0000"+
-    "\u0000\u029d\u029e\u0007\r\u0000\u0000\u029e\u029f\u0001\u0000\u0000\u0000"+
-    "\u029f\u02a0\u0006\u0015\b\u0000\u02a0<\u0001\u0000\u0000\u0000\u02a1"+
-    "\u02a2\u0004\u0016\u0005\u0000\u02a2\u02a3\u0007\r\u0000\u0000\u02a3\u02a4"+
-    "\u0007\u0003\u0000\u0000\u02a4\u02a5\u0007\u000f\u0000\u0000\u02a5\u02a6"+
-    "\u0007\u0005\u0000\u0000\u02a6\u02a7\u0001\u0000\u0000\u0000\u02a7\u02a8"+
-    "\u0006\u0016\b\u0000\u02a8>\u0001\u0000\u0000\u0000\u02a9\u02aa\u0004"+
-    "\u0017\u0006\u0000\u02aa\u02ab\u0007\u0006\u0000\u0000\u02ab\u02ac\u0007"+
-    "\u0001\u0000\u0000\u02ac\u02ad\u0007\u0011\u0000\u0000\u02ad\u02ae\u0007"+
-    "\n\u0000\u0000\u02ae\u02af\u0007\u0005\u0000\u0000\u02af\u02b0\u0001\u0000"+
-    "\u0000\u0000\u02b0\u02b1\u0006\u0017\b\u0000\u02b1@\u0001\u0000\u0000"+
-    "\u0000\u02b2\u02b4\b\u0015\u0000\u0000\u02b3\u02b2\u0001\u0000\u0000\u0000"+
-    "\u02b4\u02b5\u0001\u0000\u0000\u0000\u02b5\u02b3\u0001\u0000\u0000\u0000"+
-    "\u02b5\u02b6\u0001\u0000\u0000\u0000\u02b6\u02b7\u0001\u0000\u0000\u0000"+
-    "\u02b7\u02b8\u0006\u0018\u0000\u0000\u02b8B\u0001\u0000\u0000\u0000\u02b9"+
-    "\u02ba\u0005/\u0000\u0000\u02ba\u02bb\u0005/\u0000\u0000\u02bb\u02bf\u0001"+
-    "\u0000\u0000\u0000\u02bc\u02be\b\u0016\u0000\u0000\u02bd\u02bc\u0001\u0000"+
-    "\u0000\u0000\u02be\u02c1\u0001\u0000\u0000\u0000\u02bf\u02bd\u0001\u0000"+
-    "\u0000\u0000\u02bf\u02c0\u0001\u0000\u0000\u0000\u02c0\u02c3\u0001\u0000"+
-    "\u0000\u0000\u02c1\u02bf\u0001\u0000\u0000\u0000\u02c2\u02c4\u0005\r\u0000"+
-    "\u0000\u02c3\u02c2\u0001\u0000\u0000\u0000\u02c3\u02c4\u0001\u0000\u0000"+
-    "\u0000\u02c4\u02c6\u0001\u0000\u0000\u0000\u02c5\u02c7\u0005\n\u0000\u0000"+
-    "\u02c6\u02c5\u0001\u0000\u0000\u0000\u02c6\u02c7\u0001\u0000\u0000\u0000"+
-    "\u02c7\u02c8\u0001\u0000\u0000\u0000\u02c8\u02c9\u0006\u0019\f\u0000\u02c9"+
-    "D\u0001\u0000\u0000\u0000\u02ca\u02cb\u0005/\u0000\u0000\u02cb\u02cc\u0005"+
-    "*\u0000\u0000\u02cc\u02d1\u0001\u0000\u0000\u0000\u02cd\u02d0\u0003E\u001a"+
-    "\u0000\u02ce\u02d0\t\u0000\u0000\u0000\u02cf\u02cd\u0001\u0000\u0000\u0000"+
-    "\u02cf\u02ce\u0001\u0000\u0000\u0000\u02d0\u02d3\u0001\u0000\u0000\u0000"+
-    "\u02d1\u02d2\u0001\u0000\u0000\u0000\u02d1\u02cf\u0001\u0000\u0000\u0000"+
-    "\u02d2\u02d4\u0001\u0000\u0000\u0000\u02d3\u02d1\u0001\u0000\u0000\u0000"+
-    "\u02d4\u02d5\u0005*\u0000\u0000\u02d5\u02d6\u0005/\u0000\u0000\u02d6\u02d7"+
-    "\u0001\u0000\u0000\u0000\u02d7\u02d8\u0006\u001a\f\u0000\u02d8F\u0001"+
-    "\u0000\u0000\u0000\u02d9\u02db\u0007\u0017\u0000\u0000\u02da\u02d9\u0001"+
-    "\u0000\u0000\u0000\u02db\u02dc\u0001\u0000\u0000\u0000\u02dc\u02da\u0001"+
-    "\u0000\u0000\u0000\u02dc\u02dd\u0001\u0000\u0000\u0000\u02dd\u02de\u0001"+
-    "\u0000\u0000\u0000\u02de\u02df\u0006\u001b\f\u0000\u02dfH\u0001\u0000"+
-    "\u0000\u0000\u02e0\u02e1\u0005|\u0000\u0000\u02e1\u02e2\u0001\u0000\u0000"+
-    "\u0000\u02e2\u02e3\u0006\u001c\r\u0000\u02e3J\u0001\u0000\u0000\u0000"+
-    "\u02e4\u02e5\u0007\u0018\u0000\u0000\u02e5L\u0001\u0000\u0000\u0000\u02e6"+
-    "\u02e7\u0007\u0019\u0000\u0000\u02e7N\u0001\u0000\u0000\u0000\u02e8\u02e9"+
-    "\u0005\\\u0000\u0000\u02e9\u02ea\u0007\u001a\u0000\u0000\u02eaP\u0001"+
-    "\u0000\u0000\u0000\u02eb\u02ec\b\u001b\u0000\u0000\u02ecR\u0001\u0000"+
-    "\u0000\u0000\u02ed\u02ef\u0007\u0003\u0000\u0000\u02ee\u02f0\u0007\u001c"+
-    "\u0000\u0000\u02ef\u02ee\u0001\u0000\u0000\u0000\u02ef\u02f0\u0001\u0000"+
-    "\u0000\u0000\u02f0\u02f2\u0001\u0000\u0000\u0000\u02f1\u02f3\u0003K\u001d"+
-    "\u0000\u02f2\u02f1\u0001\u0000\u0000\u0000\u02f3\u02f4\u0001\u0000\u0000"+
-    "\u0000\u02f4\u02f2\u0001\u0000\u0000\u0000\u02f4\u02f5\u0001\u0000\u0000"+
-    "\u0000\u02f5T\u0001\u0000\u0000\u0000\u02f6\u02f7\u0005@\u0000\u0000\u02f7"+
-    "V\u0001\u0000\u0000\u0000\u02f8\u02f9\u0005`\u0000\u0000\u02f9X\u0001"+
-    "\u0000\u0000\u0000\u02fa\u02fe\b\u001d\u0000\u0000\u02fb\u02fc\u0005`"+
-    "\u0000\u0000\u02fc\u02fe\u0005`\u0000\u0000\u02fd\u02fa\u0001\u0000\u0000"+
-    "\u0000\u02fd\u02fb\u0001\u0000\u0000\u0000\u02feZ\u0001\u0000\u0000\u0000"+
-    "\u02ff\u0300\u0005_\u0000\u0000\u0300\\\u0001\u0000\u0000\u0000\u0301"+
-    "\u0305\u0003M\u001e\u0000\u0302\u0305\u0003K\u001d\u0000\u0303\u0305\u0003"+
-    "[%\u0000\u0304\u0301\u0001\u0000\u0000\u0000\u0304\u0302\u0001\u0000\u0000"+
-    "\u0000\u0304\u0303\u0001\u0000\u0000\u0000\u0305^\u0001\u0000\u0000\u0000"+
-    "\u0306\u030b\u0005\"\u0000\u0000\u0307\u030a\u0003O\u001f\u0000\u0308"+
-    "\u030a\u0003Q \u0000\u0309\u0307\u0001\u0000\u0000\u0000\u0309\u0308\u0001"+
-    "\u0000\u0000\u0000\u030a\u030d\u0001\u0000\u0000\u0000\u030b\u0309\u0001"+
-    "\u0000\u0000\u0000\u030b\u030c\u0001\u0000\u0000\u0000\u030c\u030e\u0001"+
-    "\u0000\u0000\u0000\u030d\u030b\u0001\u0000\u0000\u0000\u030e\u0324\u0005"+
-    "\"\u0000\u0000\u030f\u0310\u0005\"\u0000\u0000\u0310\u0311\u0005\"\u0000"+
-    "\u0000\u0311\u0312\u0005\"\u0000\u0000\u0312\u0316\u0001\u0000\u0000\u0000"+
-    "\u0313\u0315\b\u0016\u0000\u0000\u0314\u0313\u0001\u0000\u0000\u0000\u0315"+
-    "\u0318\u0001\u0000\u0000\u0000\u0316\u0317\u0001\u0000\u0000\u0000\u0316"+
-    "\u0314\u0001\u0000\u0000\u0000\u0317\u0319\u0001\u0000\u0000\u0000\u0318"+
-    "\u0316\u0001\u0000\u0000\u0000\u0319\u031a\u0005\"\u0000\u0000\u031a\u031b"+
-    "\u0005\"\u0000\u0000\u031b\u031c\u0005\"\u0000\u0000\u031c\u031e\u0001"+
-    "\u0000\u0000\u0000\u031d\u031f\u0005\"\u0000\u0000\u031e\u031d\u0001\u0000"+
-    "\u0000\u0000\u031e\u031f\u0001\u0000\u0000\u0000\u031f\u0321\u0001\u0000"+
-    "\u0000\u0000\u0320\u0322\u0005\"\u0000\u0000\u0321\u0320\u0001\u0000\u0000"+
-    "\u0000\u0321\u0322\u0001\u0000\u0000\u0000\u0322\u0324\u0001\u0000\u0000"+
-    "\u0000\u0323\u0306\u0001\u0000\u0000\u0000\u0323\u030f\u0001\u0000\u0000"+
-    "\u0000\u0324`\u0001\u0000\u0000\u0000\u0325\u0327\u0003K\u001d\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"+
-    "b\u0001\u0000\u0000\u0000\u032a\u032c\u0003K\u001d\u0000\u032b\u032a\u0001"+
-    "\u0000\u0000\u0000\u032c\u032d\u0001\u0000\u0000\u0000\u032d\u032b\u0001"+
-    "\u0000\u0000\u0000\u032d\u032e\u0001\u0000\u0000\u0000\u032e\u032f\u0001"+
-    "\u0000\u0000\u0000\u032f\u0333\u0003u2\u0000\u0330\u0332\u0003K\u001d"+
-    "\u0000\u0331\u0330\u0001\u0000\u0000\u0000\u0332\u0335\u0001\u0000\u0000"+
-    "\u0000\u0333\u0331\u0001\u0000\u0000\u0000\u0333\u0334\u0001\u0000\u0000"+
-    "\u0000\u0334\u0355\u0001\u0000\u0000\u0000\u0335\u0333\u0001\u0000\u0000"+
-    "\u0000\u0336\u0338\u0003u2\u0000\u0337\u0339\u0003K\u001d\u0000\u0338"+
-    "\u0337\u0001\u0000\u0000\u0000\u0339\u033a\u0001\u0000\u0000\u0000\u033a"+
-    "\u0338\u0001\u0000\u0000\u0000\u033a\u033b\u0001\u0000\u0000\u0000\u033b"+
-    "\u0355\u0001\u0000\u0000\u0000\u033c\u033e\u0003K\u001d\u0000\u033d\u033c"+
-    "\u0001\u0000\u0000\u0000\u033e\u033f\u0001\u0000\u0000\u0000\u033f\u033d"+
-    "\u0001\u0000\u0000\u0000\u033f\u0340\u0001\u0000\u0000\u0000\u0340\u0348"+
-    "\u0001\u0000\u0000\u0000\u0341\u0345\u0003u2\u0000\u0342\u0344\u0003K"+
-    "\u001d\u0000\u0343\u0342\u0001\u0000\u0000\u0000\u0344\u0347\u0001\u0000"+
-    "\u0000\u0000\u0345\u0343\u0001\u0000\u0000\u0000\u0345\u0346\u0001\u0000"+
-    "\u0000\u0000\u0346\u0349\u0001\u0000\u0000\u0000\u0347\u0345\u0001\u0000"+
-    "\u0000\u0000\u0348\u0341\u0001\u0000\u0000\u0000\u0348\u0349\u0001\u0000"+
-    "\u0000\u0000\u0349\u034a\u0001\u0000\u0000\u0000\u034a\u034b\u0003S!\u0000"+
-    "\u034b\u0355\u0001\u0000\u0000\u0000\u034c\u034e\u0003u2\u0000\u034d\u034f"+
-    "\u0003K\u001d\u0000\u034e\u034d\u0001\u0000\u0000\u0000\u034f\u0350\u0001"+
-    "\u0000\u0000\u0000\u0350\u034e\u0001\u0000\u0000\u0000\u0350\u0351\u0001"+
-    "\u0000\u0000\u0000\u0351\u0352\u0001\u0000\u0000\u0000\u0352\u0353\u0003"+
-    "S!\u0000\u0353\u0355\u0001\u0000\u0000\u0000\u0354\u032b\u0001\u0000\u0000"+
-    "\u0000\u0354\u0336\u0001\u0000\u0000\u0000\u0354\u033d\u0001\u0000\u0000"+
-    "\u0000\u0354\u034c\u0001\u0000\u0000\u0000\u0355d\u0001\u0000\u0000\u0000"+
-    "\u0356\u0357\u0007\u001e\u0000\u0000\u0357\u0358\u0007\u001f\u0000\u0000"+
-    "\u0358f\u0001\u0000\u0000\u0000\u0359\u035a\u0007\f\u0000\u0000\u035a"+
-    "\u035b\u0007\t\u0000\u0000\u035b\u035c\u0007\u0000\u0000\u0000\u035ch"+
-    "\u0001\u0000\u0000\u0000\u035d\u035e\u0007\f\u0000\u0000\u035e\u035f\u0007"+
-    "\u0002\u0000\u0000\u035f\u0360\u0007\u0004\u0000\u0000\u0360j\u0001\u0000"+
-    "\u0000\u0000\u0361\u0362\u0005=\u0000\u0000\u0362l\u0001\u0000\u0000\u0000"+
-    "\u0363\u0364\u0005:\u0000\u0000\u0364\u0365\u0005:\u0000\u0000\u0365n"+
-    "\u0001\u0000\u0000\u0000\u0366\u0367\u0005:\u0000\u0000\u0367p\u0001\u0000"+
-    "\u0000\u0000\u0368\u0369\u0005,\u0000\u0000\u0369r\u0001\u0000\u0000\u0000"+
-    "\u036a\u036b\u0007\u0000\u0000\u0000\u036b\u036c\u0007\u0003\u0000\u0000"+
-    "\u036c\u036d\u0007\u0002\u0000\u0000\u036d\u036e\u0007\u0004\u0000\u0000"+
-    "\u036et\u0001\u0000\u0000\u0000\u036f\u0370\u0005.\u0000\u0000\u0370v"+
-    "\u0001\u0000\u0000\u0000\u0371\u0372\u0007\u000f\u0000\u0000\u0372\u0373"+
-    "\u0007\f\u0000\u0000\u0373\u0374\u0007\r\u0000\u0000\u0374\u0375\u0007"+
-    "\u0002\u0000\u0000\u0375\u0376\u0007\u0003\u0000\u0000\u0376x\u0001\u0000"+
-    "\u0000\u0000\u0377\u0378\u0007\u000f\u0000\u0000\u0378\u0379\u0007\u0001"+
-    "\u0000\u0000\u0379\u037a\u0007\u0006\u0000\u0000\u037a\u037b\u0007\u0002"+
-    "\u0000\u0000\u037b\u037c\u0007\u0005\u0000\u0000\u037cz\u0001\u0000\u0000"+
-    "\u0000\u037d\u037e\u0007\u0001\u0000\u0000\u037e\u037f\u0007\t\u0000\u0000"+
-    "\u037f|\u0001\u0000\u0000\u0000\u0380\u0381\u0007\u0001\u0000\u0000\u0381"+
-    "\u0382\u0007\u0002\u0000\u0000\u0382~\u0001\u0000\u0000\u0000\u0383\u0384"+
-    "\u0007\r\u0000\u0000\u0384\u0385\u0007\f\u0000\u0000\u0385\u0386\u0007"+
-    "\u0002\u0000\u0000\u0386\u0387\u0007\u0005\u0000\u0000\u0387\u0080\u0001"+
-    "\u0000\u0000\u0000\u0388\u0389\u0007\r\u0000\u0000\u0389\u038a\u0007\u0001"+
-    "\u0000\u0000\u038a\u038b\u0007\u0012\u0000\u0000\u038b\u038c\u0007\u0003"+
-    "\u0000\u0000\u038c\u0082\u0001\u0000\u0000\u0000\u038d\u038e\u0005(\u0000"+
-    "\u0000\u038e\u0084\u0001\u0000\u0000\u0000\u038f\u0390\u0007\t\u0000\u0000"+
-    "\u0390\u0391\u0007\u0007\u0000\u0000\u0391\u0392\u0007\u0005\u0000\u0000"+
-    "\u0392\u0086\u0001\u0000\u0000\u0000\u0393\u0394\u0007\t\u0000\u0000\u0394"+
-    "\u0395\u0007\u0014\u0000\u0000\u0395\u0396\u0007\r\u0000\u0000\u0396\u0397"+
-    "\u0007\r\u0000\u0000\u0397\u0088\u0001\u0000\u0000\u0000\u0398\u0399\u0007"+
-    "\t\u0000\u0000\u0399\u039a\u0007\u0014\u0000\u0000\u039a\u039b\u0007\r"+
-    "\u0000\u0000\u039b\u039c\u0007\r\u0000\u0000\u039c\u039d\u0007\u0002\u0000"+
-    "\u0000\u039d\u008a\u0001\u0000\u0000\u0000\u039e\u039f\u0007\u0007\u0000"+
-    "\u0000\u039f\u03a0\u0007\u0006\u0000\u0000\u03a0\u008c\u0001\u0000\u0000"+
-    "\u0000\u03a1\u03a2\u0005?\u0000\u0000\u03a2\u008e\u0001\u0000\u0000\u0000"+
-    "\u03a3\u03a4\u0007\u0006\u0000\u0000\u03a4\u03a5\u0007\r\u0000\u0000\u03a5"+
-    "\u03a6\u0007\u0001\u0000\u0000\u03a6\u03a7\u0007\u0012\u0000\u0000\u03a7"+
-    "\u03a8\u0007\u0003\u0000\u0000\u03a8\u0090\u0001\u0000\u0000\u0000\u03a9"+
-    "\u03aa\u0005)\u0000\u0000\u03aa\u0092\u0001\u0000\u0000\u0000\u03ab\u03ac"+
-    "\u0007\u0005\u0000\u0000\u03ac\u03ad\u0007\u0006\u0000\u0000\u03ad\u03ae"+
-    "\u0007\u0014\u0000\u0000\u03ae\u03af\u0007\u0003\u0000\u0000\u03af\u0094"+
-    "\u0001\u0000\u0000\u0000\u03b0\u03b1\u0005=\u0000\u0000\u03b1\u03b2\u0005"+
-    "=\u0000\u0000\u03b2\u0096\u0001\u0000\u0000\u0000\u03b3\u03b4\u0005=\u0000"+
-    "\u0000\u03b4\u03b5\u0005~\u0000\u0000\u03b5\u0098\u0001\u0000\u0000\u0000"+
-    "\u03b6\u03b7\u0005!\u0000\u0000\u03b7\u03b8\u0005=\u0000\u0000\u03b8\u009a"+
-    "\u0001\u0000\u0000\u0000\u03b9\u03ba\u0005<\u0000\u0000\u03ba\u009c\u0001"+
-    "\u0000\u0000\u0000\u03bb\u03bc\u0005<\u0000\u0000\u03bc\u03bd\u0005=\u0000"+
-    "\u0000\u03bd\u009e\u0001\u0000\u0000\u0000\u03be\u03bf\u0005>\u0000\u0000"+
-    "\u03bf\u00a0\u0001\u0000\u0000\u0000\u03c0\u03c1\u0005>\u0000\u0000\u03c1"+
-    "\u03c2\u0005=\u0000\u0000\u03c2\u00a2\u0001\u0000\u0000\u0000\u03c3\u03c4"+
-    "\u0005+\u0000\u0000\u03c4\u00a4\u0001\u0000\u0000\u0000\u03c5\u03c6\u0005"+
-    "-\u0000\u0000\u03c6\u00a6\u0001\u0000\u0000\u0000\u03c7\u03c8\u0005*\u0000"+
-    "\u0000\u03c8\u00a8\u0001\u0000\u0000\u0000\u03c9\u03ca\u0005/\u0000\u0000"+
-    "\u03ca\u00aa\u0001\u0000\u0000\u0000\u03cb\u03cc\u0005%\u0000\u0000\u03cc"+
-    "\u00ac\u0001\u0000\u0000\u0000\u03cd\u03ce\u0005{\u0000\u0000\u03ce\u00ae"+
-    "\u0001\u0000\u0000\u0000\u03cf\u03d0\u0005}\u0000\u0000\u03d0\u00b0\u0001"+
-    "\u0000\u0000\u0000\u03d1\u03d2\u0003/\u000f\u0000\u03d2\u03d3\u0001\u0000"+
-    "\u0000\u0000\u03d3\u03d4\u0006P\u000e\u0000\u03d4\u00b2\u0001\u0000\u0000"+
-    "\u0000\u03d5\u03d8\u0003\u008d>\u0000\u03d6\u03d9\u0003M\u001e\u0000\u03d7"+
-    "\u03d9\u0003[%\u0000\u03d8\u03d6\u0001\u0000\u0000\u0000\u03d8\u03d7\u0001"+
-    "\u0000\u0000\u0000\u03d9\u03dd\u0001\u0000\u0000\u0000\u03da\u03dc\u0003"+
-    "]&\u0000\u03db\u03da\u0001\u0000\u0000\u0000\u03dc\u03df\u0001\u0000\u0000"+
-    "\u0000\u03dd\u03db\u0001\u0000\u0000\u0000\u03dd\u03de\u0001\u0000\u0000"+
-    "\u0000\u03de\u03e7\u0001\u0000\u0000\u0000\u03df\u03dd\u0001\u0000\u0000"+
-    "\u0000\u03e0\u03e2\u0003\u008d>\u0000\u03e1\u03e3\u0003K\u001d\u0000\u03e2"+
-    "\u03e1\u0001\u0000\u0000\u0000\u03e3\u03e4\u0001\u0000\u0000\u0000\u03e4"+
-    "\u03e2\u0001\u0000\u0000\u0000\u03e4\u03e5\u0001\u0000\u0000\u0000\u03e5"+
-    "\u03e7\u0001\u0000\u0000\u0000\u03e6\u03d5\u0001\u0000\u0000\u0000\u03e6"+
-    "\u03e0\u0001\u0000\u0000\u0000\u03e7\u00b4\u0001\u0000\u0000\u0000\u03e8"+
-    "\u03e9\u0005[\u0000\u0000\u03e9\u03ea\u0001\u0000\u0000\u0000\u03ea\u03eb"+
-    "\u0006R\u0000\u0000\u03eb\u03ec\u0006R\u0000\u0000\u03ec\u00b6\u0001\u0000"+
-    "\u0000\u0000\u03ed\u03ee\u0005]\u0000\u0000\u03ee\u03ef\u0001\u0000\u0000"+
-    "\u0000\u03ef\u03f0\u0006S\r\u0000\u03f0\u03f1\u0006S\r\u0000\u03f1\u00b8"+
-    "\u0001\u0000\u0000\u0000\u03f2\u03f6\u0003M\u001e\u0000\u03f3\u03f5\u0003"+
-    "]&\u0000\u03f4\u03f3\u0001\u0000\u0000\u0000\u03f5\u03f8\u0001\u0000\u0000"+
-    "\u0000\u03f6\u03f4\u0001\u0000\u0000\u0000\u03f6\u03f7\u0001\u0000\u0000"+
-    "\u0000\u03f7\u0403\u0001\u0000\u0000\u0000\u03f8\u03f6\u0001\u0000\u0000"+
-    "\u0000\u03f9\u03fc\u0003[%\u0000\u03fa\u03fc\u0003U\"\u0000\u03fb\u03f9"+
-    "\u0001\u0000\u0000\u0000\u03fb\u03fa\u0001\u0000\u0000\u0000\u03fc\u03fe"+
-    "\u0001\u0000\u0000\u0000\u03fd\u03ff\u0003]&\u0000\u03fe\u03fd\u0001\u0000"+
-    "\u0000\u0000\u03ff\u0400\u0001\u0000\u0000\u0000\u0400\u03fe\u0001\u0000"+
-    "\u0000\u0000\u0400\u0401\u0001\u0000\u0000\u0000\u0401\u0403\u0001\u0000"+
-    "\u0000\u0000\u0402\u03f2\u0001\u0000\u0000\u0000\u0402\u03fb\u0001\u0000"+
-    "\u0000\u0000\u0403\u00ba\u0001\u0000\u0000\u0000\u0404\u0406\u0003W#\u0000"+
-    "\u0405\u0407\u0003Y$\u0000\u0406\u0405\u0001\u0000\u0000\u0000\u0407\u0408"+
-    "\u0001\u0000\u0000\u0000\u0408\u0406\u0001\u0000\u0000\u0000\u0408\u0409"+
-    "\u0001\u0000\u0000\u0000\u0409\u040a\u0001\u0000\u0000\u0000\u040a\u040b"+
-    "\u0003W#\u0000\u040b\u00bc\u0001\u0000\u0000\u0000\u040c\u040d\u0003\u00bb"+
-    "U\u0000\u040d\u00be\u0001\u0000\u0000\u0000\u040e\u040f\u0003C\u0019\u0000"+
-    "\u040f\u0410\u0001\u0000\u0000\u0000\u0410\u0411\u0006W\f\u0000\u0411"+
-    "\u00c0\u0001\u0000\u0000\u0000\u0412\u0413\u0003E\u001a\u0000\u0413\u0414"+
-    "\u0001\u0000\u0000\u0000\u0414\u0415\u0006X\f\u0000\u0415\u00c2\u0001"+
-    "\u0000\u0000\u0000\u0416\u0417\u0003G\u001b\u0000\u0417\u0418\u0001\u0000"+
-    "\u0000\u0000\u0418\u0419\u0006Y\f\u0000\u0419\u00c4\u0001\u0000\u0000"+
-    "\u0000\u041a\u041b\u0003\u00b5R\u0000\u041b\u041c\u0001\u0000\u0000\u0000"+
-    "\u041c\u041d\u0006Z\u000f\u0000\u041d\u041e\u0006Z\u0010\u0000\u041e\u00c6"+
-    "\u0001\u0000\u0000\u0000\u041f\u0420\u0003I\u001c\u0000\u0420\u0421\u0001"+
-    "\u0000\u0000\u0000\u0421\u0422\u0006[\u0011\u0000\u0422\u0423\u0006[\r"+
-    "\u0000\u0423\u00c8\u0001\u0000\u0000\u0000\u0424\u0425\u0003G\u001b\u0000"+
-    "\u0425\u0426\u0001\u0000\u0000\u0000\u0426\u0427\u0006\\\f\u0000\u0427"+
-    "\u00ca\u0001\u0000\u0000\u0000\u0428\u0429\u0003C\u0019\u0000\u0429\u042a"+
-    "\u0001\u0000\u0000\u0000\u042a\u042b\u0006]\f\u0000\u042b\u00cc\u0001"+
-    "\u0000\u0000\u0000\u042c\u042d\u0003E\u001a\u0000\u042d\u042e\u0001\u0000"+
-    "\u0000\u0000\u042e\u042f\u0006^\f\u0000\u042f\u00ce\u0001\u0000\u0000"+
-    "\u0000\u0430\u0431\u0003I\u001c\u0000\u0431\u0432\u0001\u0000\u0000\u0000"+
-    "\u0432\u0433\u0006_\u0011\u0000\u0433\u0434\u0006_\r\u0000\u0434\u00d0"+
-    "\u0001\u0000\u0000\u0000\u0435\u0436\u0003\u00b5R\u0000\u0436\u0437\u0001"+
-    "\u0000\u0000\u0000\u0437\u0438\u0006`\u000f\u0000\u0438\u00d2\u0001\u0000"+
-    "\u0000\u0000\u0439\u043a\u0003\u00b7S\u0000\u043a\u043b\u0001\u0000\u0000"+
-    "\u0000\u043b\u043c\u0006a\u0012\u0000\u043c\u00d4\u0001\u0000\u0000\u0000"+
-    "\u043d\u043e\u0003o/\u0000\u043e\u043f\u0001\u0000\u0000\u0000\u043f\u0440"+
-    "\u0006b\u0013\u0000\u0440\u00d6\u0001\u0000\u0000\u0000\u0441\u0442\u0003"+
-    "q0\u0000\u0442\u0443\u0001\u0000\u0000\u0000\u0443\u0444\u0006c\u0014"+
-    "\u0000\u0444\u00d8\u0001\u0000\u0000\u0000\u0445\u0446\u0003k-\u0000\u0446"+
-    "\u0447\u0001\u0000\u0000\u0000\u0447\u0448\u0006d\u0015\u0000\u0448\u00da"+
-    "\u0001\u0000\u0000\u0000\u0449\u044a\u0007\u0010\u0000\u0000\u044a\u044b"+
-    "\u0007\u0003\u0000\u0000\u044b\u044c\u0007\u0005\u0000\u0000\u044c\u044d"+
-    "\u0007\f\u0000\u0000\u044d\u044e\u0007\u0000\u0000\u0000\u044e\u044f\u0007"+
-    "\f\u0000\u0000\u044f\u0450\u0007\u0005\u0000\u0000\u0450\u0451\u0007\f"+
-    "\u0000\u0000\u0451\u00dc\u0001\u0000\u0000\u0000\u0452\u0456\b \u0000"+
-    "\u0000\u0453\u0454\u0005/\u0000\u0000\u0454\u0456\b!\u0000\u0000\u0455"+
-    "\u0452\u0001\u0000\u0000\u0000\u0455\u0453\u0001\u0000\u0000\u0000\u0456"+
-    "\u00de\u0001\u0000\u0000\u0000\u0457\u0459\u0003\u00ddf\u0000\u0458\u0457"+
-    "\u0001\u0000\u0000\u0000\u0459\u045a\u0001\u0000\u0000\u0000\u045a\u0458"+
-    "\u0001\u0000\u0000\u0000\u045a\u045b\u0001\u0000\u0000\u0000\u045b\u00e0"+
-    "\u0001\u0000\u0000\u0000\u045c\u045d\u0003\u00dfg\u0000\u045d\u045e\u0001"+
-    "\u0000\u0000\u0000\u045e\u045f\u0006h\u0016\u0000\u045f\u00e2\u0001\u0000"+
-    "\u0000\u0000\u0460\u0461\u0003_\'\u0000\u0461\u0462\u0001\u0000\u0000"+
-    "\u0000\u0462\u0463\u0006i\u0017\u0000\u0463\u00e4\u0001\u0000\u0000\u0000"+
-    "\u0464\u0465\u0003C\u0019\u0000\u0465\u0466\u0001\u0000\u0000\u0000\u0466"+
-    "\u0467\u0006j\f\u0000\u0467\u00e6\u0001\u0000\u0000\u0000\u0468\u0469"+
-    "\u0003E\u001a\u0000\u0469\u046a\u0001\u0000\u0000\u0000\u046a\u046b\u0006"+
-    "k\f\u0000\u046b\u00e8\u0001\u0000\u0000\u0000\u046c\u046d\u0003G\u001b"+
-    "\u0000\u046d\u046e\u0001\u0000\u0000\u0000\u046e\u046f\u0006l\f\u0000"+
-    "\u046f\u00ea\u0001\u0000\u0000\u0000\u0470\u0471\u0003I\u001c\u0000\u0471"+
-    "\u0472\u0001\u0000\u0000\u0000\u0472\u0473\u0006m\u0011\u0000\u0473\u0474"+
-    "\u0006m\r\u0000\u0474\u00ec\u0001\u0000\u0000\u0000\u0475\u0476\u0003"+
-    "u2\u0000\u0476\u0477\u0001\u0000\u0000\u0000\u0477\u0478\u0006n\u0018"+
-    "\u0000\u0478\u00ee\u0001\u0000\u0000\u0000\u0479\u047a\u0003q0\u0000\u047a"+
-    "\u047b\u0001\u0000\u0000\u0000\u047b\u047c\u0006o\u0014\u0000\u047c\u00f0"+
-    "\u0001\u0000\u0000\u0000\u047d\u047e\u0003\u008d>\u0000\u047e\u047f\u0001"+
-    "\u0000\u0000\u0000\u047f\u0480\u0006p\u0019\u0000\u0480\u00f2\u0001\u0000"+
-    "\u0000\u0000\u0481\u0482\u0003\u00b3Q\u0000\u0482\u0483\u0001\u0000\u0000"+
-    "\u0000\u0483\u0484\u0006q\u001a\u0000\u0484\u00f4\u0001\u0000\u0000\u0000"+
-    "\u0485\u048a\u0003M\u001e\u0000\u0486\u048a\u0003K\u001d\u0000\u0487\u048a"+
-    "\u0003[%\u0000\u0488\u048a\u0003\u00a7K\u0000\u0489\u0485\u0001\u0000"+
-    "\u0000\u0000\u0489\u0486\u0001\u0000\u0000\u0000\u0489\u0487\u0001\u0000"+
-    "\u0000\u0000\u0489\u0488\u0001\u0000\u0000\u0000\u048a\u00f6\u0001\u0000"+
-    "\u0000\u0000\u048b\u048e\u0003M\u001e\u0000\u048c\u048e\u0003\u00a7K\u0000"+
-    "\u048d\u048b\u0001\u0000\u0000\u0000\u048d\u048c\u0001\u0000\u0000\u0000"+
-    "\u048e\u0492\u0001\u0000\u0000\u0000\u048f\u0491\u0003\u00f5r\u0000\u0490"+
-    "\u048f\u0001\u0000\u0000\u0000\u0491\u0494\u0001\u0000\u0000\u0000\u0492"+
-    "\u0490\u0001\u0000\u0000\u0000\u0492\u0493\u0001\u0000\u0000\u0000\u0493"+
-    "\u049f\u0001\u0000\u0000\u0000\u0494\u0492\u0001\u0000\u0000\u0000\u0495"+
-    "\u0498\u0003[%\u0000\u0496\u0498\u0003U\"\u0000\u0497\u0495\u0001\u0000"+
-    "\u0000\u0000\u0497\u0496\u0001\u0000\u0000\u0000\u0498\u049a\u0001\u0000"+
-    "\u0000\u0000\u0499\u049b\u0003\u00f5r\u0000\u049a\u0499\u0001\u0000\u0000"+
-    "\u0000\u049b\u049c\u0001\u0000\u0000\u0000\u049c\u049a\u0001\u0000\u0000"+
-    "\u0000\u049c\u049d\u0001\u0000\u0000\u0000\u049d\u049f\u0001\u0000\u0000"+
-    "\u0000\u049e\u048d\u0001\u0000\u0000\u0000\u049e\u0497\u0001\u0000\u0000"+
-    "\u0000\u049f\u00f8\u0001\u0000\u0000\u0000\u04a0\u04a3\u0003\u00f7s\u0000"+
-    "\u04a1\u04a3\u0003\u00bbU\u0000\u04a2\u04a0\u0001\u0000\u0000\u0000\u04a2"+
-    "\u04a1\u0001\u0000\u0000\u0000\u04a3\u04a4\u0001\u0000\u0000\u0000\u04a4"+
-    "\u04a2\u0001\u0000\u0000\u0000\u04a4\u04a5\u0001\u0000\u0000\u0000\u04a5"+
-    "\u00fa\u0001\u0000\u0000\u0000\u04a6\u04a7\u0003C\u0019\u0000\u04a7\u04a8"+
-    "\u0001\u0000\u0000\u0000\u04a8\u04a9\u0006u\f\u0000\u04a9\u00fc\u0001"+
-    "\u0000\u0000\u0000\u04aa\u04ab\u0003E\u001a\u0000\u04ab\u04ac\u0001\u0000"+
-    "\u0000\u0000\u04ac\u04ad\u0006v\f\u0000\u04ad\u00fe\u0001\u0000\u0000"+
-    "\u0000\u04ae\u04af\u0003G\u001b\u0000\u04af\u04b0\u0001\u0000\u0000\u0000"+
-    "\u04b0\u04b1\u0006w\f\u0000\u04b1\u0100\u0001\u0000\u0000\u0000\u04b2"+
-    "\u04b3\u0003I\u001c\u0000\u04b3\u04b4\u0001\u0000\u0000\u0000\u04b4\u04b5"+
-    "\u0006x\u0011\u0000\u04b5\u04b6\u0006x\r\u0000\u04b6\u0102\u0001\u0000"+
-    "\u0000\u0000\u04b7\u04b8\u0003k-\u0000\u04b8\u04b9\u0001\u0000\u0000\u0000"+
-    "\u04b9\u04ba\u0006y\u0015\u0000\u04ba\u0104\u0001\u0000\u0000\u0000\u04bb"+
-    "\u04bc\u0003q0\u0000\u04bc\u04bd\u0001\u0000\u0000\u0000\u04bd\u04be\u0006"+
-    "z\u0014\u0000\u04be\u0106\u0001\u0000\u0000\u0000\u04bf\u04c0\u0003u2"+
-    "\u0000\u04c0\u04c1\u0001\u0000\u0000\u0000\u04c1\u04c2\u0006{\u0018\u0000"+
-    "\u04c2\u0108\u0001\u0000\u0000\u0000\u04c3\u04c4\u0003\u008d>\u0000\u04c4"+
-    "\u04c5\u0001\u0000\u0000\u0000\u04c5\u04c6\u0006|\u0019\u0000\u04c6\u010a"+
-    "\u0001\u0000\u0000\u0000\u04c7\u04c8\u0003\u00b3Q\u0000\u04c8\u04c9\u0001"+
-    "\u0000\u0000\u0000\u04c9\u04ca\u0006}\u001a\u0000\u04ca\u010c\u0001\u0000"+
-    "\u0000\u0000\u04cb\u04cc\u0007\f\u0000\u0000\u04cc\u04cd\u0007\u0002\u0000"+
-    "\u0000\u04cd\u010e\u0001\u0000\u0000\u0000\u04ce\u04cf\u0003\u00f9t\u0000"+
-    "\u04cf\u04d0\u0001\u0000\u0000\u0000\u04d0\u04d1\u0006\u007f\u001b\u0000"+
-    "\u04d1\u0110\u0001\u0000\u0000\u0000\u04d2\u04d3\u0003C\u0019\u0000\u04d3"+
-    "\u04d4\u0001\u0000\u0000\u0000\u04d4\u04d5\u0006\u0080\f\u0000\u04d5\u0112"+
-    "\u0001\u0000\u0000\u0000\u04d6\u04d7\u0003E\u001a\u0000\u04d7\u04d8\u0001"+
-    "\u0000\u0000\u0000\u04d8\u04d9\u0006\u0081\f\u0000\u04d9\u0114\u0001\u0000"+
-    "\u0000\u0000\u04da\u04db\u0003G\u001b\u0000\u04db\u04dc\u0001\u0000\u0000"+
-    "\u0000\u04dc\u04dd\u0006\u0082\f\u0000\u04dd\u0116\u0001\u0000\u0000\u0000"+
-    "\u04de\u04df\u0003I\u001c\u0000\u04df\u04e0\u0001\u0000\u0000\u0000\u04e0"+
-    "\u04e1\u0006\u0083\u0011\u0000\u04e1\u04e2\u0006\u0083\r\u0000\u04e2\u0118"+
-    "\u0001\u0000\u0000\u0000\u04e3\u04e4\u0003\u00b5R\u0000\u04e4\u04e5\u0001"+
-    "\u0000\u0000\u0000\u04e5\u04e6\u0006\u0084\u000f\u0000\u04e6\u04e7\u0006"+
-    "\u0084\u001c\u0000\u04e7\u011a\u0001\u0000\u0000\u0000\u04e8\u04e9\u0007"+
-    "\u0007\u0000\u0000\u04e9\u04ea\u0007\t\u0000\u0000\u04ea\u04eb\u0001\u0000"+
-    "\u0000\u0000\u04eb\u04ec\u0006\u0085\u001d\u0000\u04ec\u011c\u0001\u0000"+
-    "\u0000\u0000\u04ed\u04ee\u0007\u0013\u0000\u0000\u04ee\u04ef\u0007\u0001"+
-    "\u0000\u0000\u04ef\u04f0\u0007\u0005\u0000\u0000\u04f0\u04f1\u0007\n\u0000"+
-    "\u0000\u04f1\u04f2\u0001\u0000\u0000\u0000\u04f2\u04f3\u0006\u0086\u001d"+
-    "\u0000\u04f3\u011e\u0001\u0000\u0000\u0000\u04f4\u04f5\b\"\u0000\u0000"+
-    "\u04f5\u0120\u0001\u0000\u0000\u0000\u04f6\u04f8\u0003\u011f\u0087\u0000"+
-    "\u04f7\u04f6\u0001\u0000\u0000\u0000\u04f8\u04f9\u0001\u0000\u0000\u0000"+
-    "\u04f9\u04f7\u0001\u0000\u0000\u0000\u04f9\u04fa\u0001\u0000\u0000\u0000"+
-    "\u04fa\u04fb\u0001\u0000\u0000\u0000\u04fb\u04fc\u0003o/\u0000\u04fc\u04fe"+
-    "\u0001\u0000\u0000\u0000\u04fd\u04f7\u0001\u0000\u0000\u0000\u04fd\u04fe"+
-    "\u0001\u0000\u0000\u0000\u04fe\u0500\u0001\u0000\u0000\u0000\u04ff\u0501"+
-    "\u0003\u011f\u0087\u0000\u0500\u04ff\u0001\u0000\u0000\u0000\u0501\u0502"+
-    "\u0001\u0000\u0000\u0000\u0502\u0500\u0001\u0000\u0000\u0000\u0502\u0503"+
-    "\u0001\u0000\u0000\u0000\u0503\u0122\u0001\u0000\u0000\u0000\u0504\u0505"+
-    "\u0003\u0121\u0088\u0000\u0505\u0506\u0001\u0000\u0000\u0000\u0506\u0507"+
-    "\u0006\u0089\u001e\u0000\u0507\u0124\u0001\u0000\u0000\u0000\u0508\u0509"+
-    "\u0003C\u0019\u0000\u0509\u050a\u0001\u0000\u0000\u0000\u050a\u050b\u0006"+
-    "\u008a\f\u0000\u050b\u0126\u0001\u0000\u0000\u0000\u050c\u050d\u0003E"+
-    "\u001a\u0000\u050d\u050e\u0001\u0000\u0000\u0000\u050e\u050f\u0006\u008b"+
-    "\f\u0000\u050f\u0128\u0001\u0000\u0000\u0000\u0510\u0511\u0003G\u001b"+
-    "\u0000\u0511\u0512\u0001\u0000\u0000\u0000\u0512\u0513\u0006\u008c\f\u0000"+
-    "\u0513\u012a\u0001\u0000\u0000\u0000\u0514\u0515\u0003I\u001c\u0000\u0515"+
-    "\u0516\u0001\u0000\u0000\u0000\u0516\u0517\u0006\u008d\u0011\u0000\u0517"+
-    "\u0518\u0006\u008d\r\u0000\u0518\u0519\u0006\u008d\r\u0000\u0519\u012c"+
-    "\u0001\u0000\u0000\u0000\u051a\u051b\u0003k-\u0000\u051b\u051c\u0001\u0000"+
-    "\u0000\u0000\u051c\u051d\u0006\u008e\u0015\u0000\u051d\u012e\u0001\u0000"+
-    "\u0000\u0000\u051e\u051f\u0003q0\u0000\u051f\u0520\u0001\u0000\u0000\u0000"+
-    "\u0520\u0521\u0006\u008f\u0014\u0000\u0521\u0130\u0001\u0000\u0000\u0000"+
-    "\u0522\u0523\u0003u2\u0000\u0523\u0524\u0001\u0000\u0000\u0000\u0524\u0525"+
-    "\u0006\u0090\u0018\u0000\u0525\u0132\u0001\u0000\u0000\u0000\u0526\u0527"+
-    "\u0003\u011d\u0086\u0000\u0527\u0528\u0001\u0000\u0000\u0000\u0528\u0529"+
-    "\u0006\u0091\u001f\u0000\u0529\u0134\u0001\u0000\u0000\u0000\u052a\u052b"+
-    "\u0003\u00f9t\u0000\u052b\u052c\u0001\u0000\u0000\u0000\u052c\u052d\u0006"+
-    "\u0092\u001b\u0000\u052d\u0136\u0001\u0000\u0000\u0000\u052e\u052f\u0003"+
-    "\u00bdV\u0000\u052f\u0530\u0001\u0000\u0000\u0000\u0530\u0531\u0006\u0093"+
-    " \u0000\u0531\u0138\u0001\u0000\u0000\u0000\u0532\u0533\u0003\u008d>\u0000"+
-    "\u0533\u0534\u0001\u0000\u0000\u0000\u0534\u0535\u0006\u0094\u0019\u0000"+
-    "\u0535\u013a\u0001\u0000\u0000\u0000\u0536\u0537\u0003\u00b3Q\u0000\u0537"+
-    "\u0538\u0001\u0000\u0000\u0000\u0538\u0539\u0006\u0095\u001a\u0000\u0539"+
-    "\u013c\u0001\u0000\u0000\u0000\u053a\u053b\u0003C\u0019\u0000\u053b\u053c"+
-    "\u0001\u0000\u0000\u0000\u053c\u053d\u0006\u0096\f\u0000\u053d\u013e\u0001"+
-    "\u0000\u0000\u0000\u053e\u053f\u0003E\u001a\u0000\u053f\u0540\u0001\u0000"+
-    "\u0000\u0000\u0540\u0541\u0006\u0097\f\u0000\u0541\u0140\u0001\u0000\u0000"+
-    "\u0000\u0542\u0543\u0003G\u001b\u0000\u0543\u0544\u0001\u0000\u0000\u0000"+
-    "\u0544\u0545\u0006\u0098\f\u0000\u0545\u0142\u0001\u0000\u0000\u0000\u0546"+
-    "\u0547\u0003I\u001c\u0000\u0547\u0548\u0001\u0000\u0000\u0000\u0548\u0549"+
-    "\u0006\u0099\u0011\u0000\u0549\u054a\u0006\u0099\r\u0000\u054a\u0144\u0001"+
-    "\u0000\u0000\u0000\u054b\u054c\u0003u2\u0000\u054c\u054d\u0001\u0000\u0000"+
-    "\u0000\u054d\u054e\u0006\u009a\u0018\u0000\u054e\u0146\u0001\u0000\u0000"+
-    "\u0000\u054f\u0550\u0003\u008d>\u0000\u0550\u0551\u0001\u0000\u0000\u0000"+
-    "\u0551\u0552\u0006\u009b\u0019\u0000\u0552\u0148\u0001\u0000\u0000\u0000"+
-    "\u0553\u0554\u0003\u00b3Q\u0000\u0554\u0555\u0001\u0000\u0000\u0000\u0555"+
-    "\u0556\u0006\u009c\u001a\u0000\u0556\u014a\u0001\u0000\u0000\u0000\u0557"+
-    "\u0558\u0003\u00bdV\u0000\u0558\u0559\u0001\u0000\u0000\u0000\u0559\u055a"+
-    "\u0006\u009d \u0000\u055a\u014c\u0001\u0000\u0000\u0000\u055b\u055c\u0003"+
-    "\u00b9T\u0000\u055c\u055d\u0001\u0000\u0000\u0000\u055d\u055e\u0006\u009e"+
-    "!\u0000\u055e\u014e\u0001\u0000\u0000\u0000\u055f\u0560\u0003C\u0019\u0000"+
-    "\u0560\u0561\u0001\u0000\u0000\u0000\u0561\u0562\u0006\u009f\f\u0000\u0562"+
-    "\u0150\u0001\u0000\u0000\u0000\u0563\u0564\u0003E\u001a\u0000\u0564\u0565"+
-    "\u0001\u0000\u0000\u0000\u0565\u0566\u0006\u00a0\f\u0000\u0566\u0152\u0001"+
-    "\u0000\u0000\u0000\u0567\u0568\u0003G\u001b\u0000\u0568\u0569\u0001\u0000"+
-    "\u0000\u0000\u0569\u056a\u0006\u00a1\f\u0000\u056a\u0154\u0001\u0000\u0000"+
-    "\u0000\u056b\u056c\u0003I\u001c\u0000\u056c\u056d\u0001\u0000\u0000\u0000"+
-    "\u056d\u056e\u0006\u00a2\u0011\u0000\u056e\u056f\u0006\u00a2\r\u0000\u056f"+
-    "\u0156\u0001\u0000\u0000\u0000\u0570\u0571\u0007\u0001\u0000\u0000\u0571"+
-    "\u0572\u0007\t\u0000\u0000\u0572\u0573\u0007\u000f\u0000\u0000\u0573\u0574"+
-    "\u0007\u0007\u0000\u0000\u0574\u0158\u0001\u0000\u0000\u0000\u0575\u0576"+
-    "\u0003C\u0019\u0000\u0576\u0577\u0001\u0000\u0000\u0000\u0577\u0578\u0006"+
-    "\u00a4\f\u0000\u0578\u015a\u0001\u0000\u0000\u0000\u0579\u057a\u0003E"+
-    "\u001a\u0000\u057a\u057b\u0001\u0000\u0000\u0000\u057b\u057c\u0006\u00a5"+
-    "\f\u0000\u057c\u015c\u0001\u0000\u0000\u0000\u057d\u057e\u0003G\u001b"+
-    "\u0000\u057e\u057f\u0001\u0000\u0000\u0000\u057f\u0580\u0006\u00a6\f\u0000"+
-    "\u0580\u015e\u0001\u0000\u0000\u0000\u0581\u0582\u0003\u00b7S\u0000\u0582"+
-    "\u0583\u0001\u0000\u0000\u0000\u0583\u0584\u0006\u00a7\u0012\u0000\u0584"+
-    "\u0585\u0006\u00a7\r\u0000\u0585\u0160\u0001\u0000\u0000\u0000\u0586\u0587"+
-    "\u0003o/\u0000\u0587\u0588\u0001\u0000\u0000\u0000\u0588\u0589\u0006\u00a8"+
-    "\u0013\u0000\u0589\u0162\u0001\u0000\u0000\u0000\u058a\u0590\u0003U\""+
-    "\u0000\u058b\u0590\u0003K\u001d\u0000\u058c\u0590\u0003u2\u0000\u058d"+
-    "\u0590\u0003M\u001e\u0000\u058e\u0590\u0003[%\u0000\u058f\u058a\u0001"+
-    "\u0000\u0000\u0000\u058f\u058b\u0001\u0000\u0000\u0000\u058f\u058c\u0001"+
-    "\u0000\u0000\u0000\u058f\u058d\u0001\u0000\u0000\u0000\u058f\u058e\u0001"+
-    "\u0000\u0000\u0000\u0590\u0591\u0001\u0000\u0000\u0000\u0591\u058f\u0001"+
-    "\u0000\u0000\u0000\u0591\u0592\u0001\u0000\u0000\u0000\u0592\u0164\u0001"+
-    "\u0000\u0000\u0000\u0593\u0594\u0003C\u0019\u0000\u0594\u0595\u0001\u0000"+
-    "\u0000\u0000\u0595\u0596\u0006\u00aa\f\u0000\u0596\u0166\u0001\u0000\u0000"+
-    "\u0000\u0597\u0598\u0003E\u001a\u0000\u0598\u0599\u0001\u0000\u0000\u0000"+
-    "\u0599\u059a\u0006\u00ab\f\u0000\u059a\u0168\u0001\u0000\u0000\u0000\u059b"+
-    "\u059c\u0003G\u001b\u0000\u059c\u059d\u0001\u0000\u0000\u0000\u059d\u059e"+
-    "\u0006\u00ac\f\u0000\u059e\u016a\u0001\u0000\u0000\u0000\u059f\u05a0\u0003"+
-    "I\u001c\u0000\u05a0\u05a1\u0001\u0000\u0000\u0000\u05a1\u05a2\u0006\u00ad"+
-    "\u0011\u0000\u05a2\u05a3\u0006\u00ad\r\u0000\u05a3\u016c\u0001\u0000\u0000"+
-    "\u0000\u05a4\u05a5\u0003o/\u0000\u05a5\u05a6\u0001\u0000\u0000\u0000\u05a6"+
-    "\u05a7\u0006\u00ae\u0013\u0000\u05a7\u016e\u0001\u0000\u0000\u0000\u05a8"+
-    "\u05a9\u0003q0\u0000\u05a9\u05aa\u0001\u0000\u0000\u0000\u05aa\u05ab\u0006"+
-    "\u00af\u0014\u0000\u05ab\u0170\u0001\u0000\u0000\u0000\u05ac\u05ad\u0003"+
-    "u2\u0000\u05ad\u05ae\u0001\u0000\u0000\u0000\u05ae\u05af\u0006\u00b0\u0018"+
-    "\u0000\u05af\u0172\u0001\u0000\u0000\u0000\u05b0\u05b1\u0003\u011b\u0085"+
-    "\u0000\u05b1\u05b2\u0001\u0000\u0000\u0000\u05b2\u05b3\u0006\u00b1\"\u0000"+
-    "\u05b3\u05b4\u0006\u00b1#\u0000\u05b4\u0174\u0001\u0000\u0000\u0000\u05b5"+
-    "\u05b6\u0003\u00dfg\u0000\u05b6\u05b7\u0001\u0000\u0000\u0000\u05b7\u05b8"+
-    "\u0006\u00b2\u0016\u0000\u05b8\u0176\u0001\u0000\u0000\u0000\u05b9\u05ba"+
-    "\u0003_\'\u0000\u05ba\u05bb\u0001\u0000\u0000\u0000\u05bb\u05bc\u0006"+
-    "\u00b3\u0017\u0000\u05bc\u0178\u0001\u0000\u0000\u0000\u05bd\u05be\u0003"+
-    "C\u0019\u0000\u05be\u05bf\u0001\u0000\u0000\u0000\u05bf\u05c0\u0006\u00b4"+
-    "\f\u0000\u05c0\u017a\u0001\u0000\u0000\u0000\u05c1\u05c2\u0003E\u001a"+
-    "\u0000\u05c2\u05c3\u0001\u0000\u0000\u0000\u05c3\u05c4\u0006\u00b5\f\u0000"+
-    "\u05c4\u017c\u0001\u0000\u0000\u0000\u05c5\u05c6\u0003G\u001b\u0000\u05c6"+
-    "\u05c7\u0001\u0000\u0000\u0000\u05c7\u05c8\u0006\u00b6\f\u0000\u05c8\u017e"+
-    "\u0001\u0000\u0000\u0000\u05c9\u05ca\u0003I\u001c\u0000\u05ca\u05cb\u0001"+
-    "\u0000\u0000\u0000\u05cb\u05cc\u0006\u00b7\u0011\u0000\u05cc\u05cd\u0006"+
-    "\u00b7\r\u0000\u05cd\u05ce\u0006\u00b7\r\u0000\u05ce\u0180\u0001\u0000"+
-    "\u0000\u0000\u05cf\u05d0\u0003q0\u0000\u05d0\u05d1\u0001\u0000\u0000\u0000"+
-    "\u05d1\u05d2\u0006\u00b8\u0014\u0000\u05d2\u0182\u0001\u0000\u0000\u0000"+
-    "\u05d3\u05d4\u0003u2\u0000\u05d4\u05d5\u0001\u0000\u0000\u0000\u05d5\u05d6"+
-    "\u0006\u00b9\u0018\u0000\u05d6\u0184\u0001\u0000\u0000\u0000\u05d7\u05d8"+
-    "\u0003\u00f9t\u0000\u05d8\u05d9\u0001\u0000\u0000\u0000\u05d9\u05da\u0006"+
-    "\u00ba\u001b\u0000\u05da\u0186\u0001\u0000\u0000\u0000\u05db\u05dc\u0003"+
-    "C\u0019\u0000\u05dc\u05dd\u0001\u0000\u0000\u0000\u05dd\u05de\u0006\u00bb"+
-    "\f\u0000\u05de\u0188\u0001\u0000\u0000\u0000\u05df\u05e0\u0003E\u001a"+
-    "\u0000\u05e0\u05e1\u0001\u0000\u0000\u0000\u05e1\u05e2\u0006\u00bc\f\u0000"+
-    "\u05e2\u018a\u0001\u0000\u0000\u0000\u05e3\u05e4\u0003G\u001b\u0000\u05e4"+
-    "\u05e5\u0001\u0000\u0000\u0000\u05e5\u05e6\u0006\u00bd\f\u0000\u05e6\u018c"+
-    "\u0001\u0000\u0000\u0000\u05e7\u05e8\u0003I\u001c\u0000\u05e8\u05e9\u0001"+
-    "\u0000\u0000\u0000\u05e9\u05ea\u0006\u00be\u0011\u0000\u05ea\u05eb\u0006"+
-    "\u00be\r\u0000\u05eb\u018e\u0001\u0000\u0000\u0000\u05ec\u05ed\u0007#"+
-    "\u0000\u0000\u05ed\u05ee\u0007\u0007\u0000\u0000\u05ee\u05ef\u0007\u0001"+
-    "\u0000\u0000\u05ef\u05f0\u0007\t\u0000\u0000\u05f0\u0190\u0001\u0000\u0000"+
-    "\u0000\u05f1\u05f2\u0003\u010d~\u0000\u05f2\u05f3\u0001\u0000\u0000\u0000"+
-    "\u05f3\u05f4\u0006\u00c0$\u0000\u05f4\u0192\u0001\u0000\u0000\u0000\u05f5"+
-    "\u05f6\u0003\u011b\u0085\u0000\u05f6\u05f7\u0001\u0000\u0000\u0000\u05f7"+
-    "\u05f8\u0006\u00c1\"\u0000\u05f8\u05f9\u0006\u00c1\r\u0000\u05f9\u05fa"+
-    "\u0006\u00c1\u0000\u0000\u05fa\u0194\u0001\u0000\u0000\u0000\u05fb\u05fc"+
-    "\u0007\u0014\u0000\u0000\u05fc\u05fd\u0007\u0002\u0000\u0000\u05fd\u05fe"+
-    "\u0007\u0001\u0000\u0000\u05fe\u05ff\u0007\t\u0000\u0000\u05ff\u0600\u0007"+
-    "\u0011\u0000\u0000\u0600\u0601\u0001\u0000\u0000\u0000\u0601\u0602\u0006"+
-    "\u00c2\r\u0000\u0602\u0603\u0006\u00c2\u0000\u0000\u0603\u0196\u0001\u0000"+
-    "\u0000\u0000\u0604\u0605\u0003\u00dfg\u0000\u0605\u0606\u0001\u0000\u0000"+
-    "\u0000\u0606\u0607\u0006\u00c3\u0016\u0000\u0607\u0198\u0001\u0000\u0000"+
-    "\u0000\u0608\u0609\u0003_\'\u0000\u0609\u060a\u0001\u0000\u0000\u0000"+
-    "\u060a\u060b\u0006\u00c4\u0017\u0000\u060b\u019a\u0001\u0000\u0000\u0000"+
-    "\u060c\u060d\u0003o/\u0000\u060d\u060e\u0001\u0000\u0000\u0000\u060e\u060f"+
-    "\u0006\u00c5\u0013\u0000\u060f\u019c\u0001\u0000\u0000\u0000\u0610\u0611"+
-    "\u0003\u00b9T\u0000\u0611\u0612\u0001\u0000\u0000\u0000\u0612\u0613\u0006"+
-    "\u00c6!\u0000\u0613\u019e\u0001\u0000\u0000\u0000\u0614\u0615\u0003\u00bd"+
-    "V\u0000\u0615\u0616\u0001\u0000\u0000\u0000\u0616\u0617\u0006\u00c7 \u0000"+
-    "\u0617\u01a0\u0001\u0000\u0000\u0000\u0618\u0619\u0003C\u0019\u0000\u0619"+
-    "\u061a\u0001\u0000\u0000\u0000\u061a\u061b\u0006\u00c8\f\u0000\u061b\u01a2"+
-    "\u0001\u0000\u0000\u0000\u061c\u061d\u0003E\u001a\u0000\u061d\u061e\u0001"+
-    "\u0000\u0000\u0000\u061e\u061f\u0006\u00c9\f\u0000\u061f\u01a4\u0001\u0000"+
-    "\u0000\u0000\u0620\u0621\u0003G\u001b\u0000\u0621\u0622\u0001\u0000\u0000"+
-    "\u0000\u0622\u0623\u0006\u00ca\f\u0000\u0623\u01a6\u0001\u0000\u0000\u0000"+
-    "\u0624\u0625\u0003I\u001c\u0000\u0625\u0626\u0001\u0000\u0000\u0000\u0626"+
-    "\u0627\u0006\u00cb\u0011\u0000\u0627\u0628\u0006\u00cb\r\u0000\u0628\u01a8"+
-    "\u0001\u0000\u0000\u0000\u0629\u062a\u0003\u00dfg\u0000\u062a\u062b\u0001"+
-    "\u0000\u0000\u0000\u062b\u062c\u0006\u00cc\u0016\u0000\u062c\u062d\u0006"+
-    "\u00cc\r\u0000\u062d\u062e\u0006\u00cc%\u0000\u062e\u01aa\u0001\u0000"+
-    "\u0000\u0000\u062f\u0630\u0003_\'\u0000\u0630\u0631\u0001\u0000\u0000"+
-    "\u0000\u0631\u0632\u0006\u00cd\u0017\u0000\u0632\u0633\u0006\u00cd\r\u0000"+
-    "\u0633\u0634\u0006\u00cd%\u0000\u0634\u01ac\u0001\u0000\u0000\u0000\u0635"+
-    "\u0636\u0003C\u0019\u0000\u0636\u0637\u0001\u0000\u0000\u0000\u0637\u0638"+
-    "\u0006\u00ce\f\u0000\u0638\u01ae\u0001\u0000\u0000\u0000\u0639\u063a\u0003"+
-    "E\u001a\u0000\u063a\u063b\u0001\u0000\u0000\u0000\u063b\u063c\u0006\u00cf"+
-    "\f\u0000\u063c\u01b0\u0001\u0000\u0000\u0000\u063d\u063e\u0003G\u001b"+
-    "\u0000\u063e\u063f\u0001\u0000\u0000\u0000\u063f\u0640\u0006\u00d0\f\u0000"+
-    "\u0640\u01b2\u0001\u0000\u0000\u0000\u0641\u0642\u0003o/\u0000\u0642\u0643"+
-    "\u0001\u0000\u0000\u0000\u0643\u0644\u0006\u00d1\u0013\u0000\u0644\u0645"+
-    "\u0006\u00d1\r\u0000\u0645\u0646\u0006\u00d1\u000b\u0000\u0646\u01b4\u0001"+
-    "\u0000\u0000\u0000\u0647\u0648\u0003q0\u0000\u0648\u0649\u0001\u0000\u0000"+
-    "\u0000\u0649\u064a\u0006\u00d2\u0014\u0000\u064a\u064b\u0006\u00d2\r\u0000"+
-    "\u064b\u064c\u0006\u00d2\u000b\u0000\u064c\u01b6\u0001\u0000\u0000\u0000"+
-    "\u064d\u064e\u0003C\u0019\u0000\u064e\u064f\u0001\u0000\u0000\u0000\u064f"+
-    "\u0650\u0006\u00d3\f\u0000\u0650\u01b8\u0001\u0000\u0000\u0000\u0651\u0652"+
-    "\u0003E\u001a\u0000\u0652\u0653\u0001\u0000\u0000\u0000\u0653\u0654\u0006"+
-    "\u00d4\f\u0000\u0654\u01ba\u0001\u0000\u0000\u0000\u0655\u0656\u0003G"+
-    "\u001b\u0000\u0656\u0657\u0001\u0000\u0000\u0000\u0657\u0658\u0006\u00d5"+
-    "\f\u0000\u0658\u01bc\u0001\u0000\u0000\u0000\u0659\u065a\u0003\u00bdV"+
-    "\u0000\u065a\u065b\u0001\u0000\u0000\u0000\u065b\u065c\u0006\u00d6\r\u0000"+
-    "\u065c\u065d\u0006\u00d6\u0000\u0000\u065d\u065e\u0006\u00d6 \u0000\u065e"+
-    "\u01be\u0001\u0000\u0000\u0000\u065f\u0660\u0003\u00b9T\u0000\u0660\u0661"+
-    "\u0001\u0000\u0000\u0000\u0661\u0662\u0006\u00d7\r\u0000\u0662\u0663\u0006"+
-    "\u00d7\u0000\u0000\u0663\u0664\u0006\u00d7!\u0000\u0664\u01c0\u0001\u0000"+
-    "\u0000\u0000\u0665\u0666\u0003e*\u0000\u0666\u0667\u0001\u0000\u0000\u0000"+
-    "\u0667\u0668\u0006\u00d8\r\u0000\u0668\u0669\u0006\u00d8\u0000\u0000\u0669"+
-    "\u066a\u0006\u00d8&\u0000\u066a\u01c2\u0001\u0000\u0000\u0000\u066b\u066c"+
-    "\u0003I\u001c\u0000\u066c\u066d\u0001\u0000\u0000\u0000\u066d\u066e\u0006"+
-    "\u00d9\u0011\u0000\u066e\u066f\u0006\u00d9\r\u0000\u066f\u01c4\u0001\u0000"+
-    "\u0000\u0000\u0670\u0671\u0003I\u001c\u0000\u0671\u0672\u0001\u0000\u0000"+
-    "\u0000\u0672\u0673\u0006\u00da\u0011\u0000\u0673\u0674\u0006\u00da\r\u0000"+
-    "\u0674\u01c6\u0001\u0000\u0000\u0000\u0675\u0676\u0003\u011b\u0085\u0000"+
-    "\u0676\u0677\u0001\u0000\u0000\u0000\u0677\u0678\u0006\u00db\"\u0000\u0678"+
-    "\u01c8\u0001\u0000\u0000\u0000\u0679\u067a\u0003\u010d~\u0000\u067a\u067b"+
-    "\u0001\u0000\u0000\u0000\u067b\u067c\u0006\u00dc$\u0000\u067c\u01ca\u0001"+
-    "\u0000\u0000\u0000\u067d\u067e\u0003u2\u0000\u067e\u067f\u0001\u0000\u0000"+
-    "\u0000\u067f\u0680\u0006\u00dd\u0018\u0000\u0680\u01cc\u0001\u0000\u0000"+
-    "\u0000\u0681\u0682\u0003q0\u0000\u0682\u0683\u0001\u0000\u0000\u0000\u0683"+
-    "\u0684\u0006\u00de\u0014\u0000\u0684\u01ce\u0001\u0000\u0000\u0000\u0685"+
-    "\u0686\u0003\u00bdV\u0000\u0686\u0687\u0001\u0000\u0000\u0000\u0687\u0688"+
-    "\u0006\u00df \u0000\u0688\u01d0\u0001\u0000\u0000\u0000\u0689\u068a\u0003"+
-    "\u00b9T\u0000\u068a\u068b\u0001\u0000\u0000\u0000\u068b\u068c\u0006\u00e0"+
-    "!\u0000\u068c\u01d2\u0001\u0000\u0000\u0000\u068d\u068e\u0003C\u0019\u0000"+
-    "\u068e\u068f\u0001\u0000\u0000\u0000\u068f\u0690\u0006\u00e1\f\u0000\u0690"+
-    "\u01d4\u0001\u0000\u0000\u0000\u0691\u0692\u0003E\u001a\u0000\u0692\u0693"+
-    "\u0001\u0000\u0000\u0000\u0693\u0694\u0006\u00e2\f\u0000\u0694\u01d6\u0001"+
-    "\u0000\u0000\u0000\u0695\u0696\u0003G\u001b\u0000\u0696\u0697\u0001\u0000"+
-    "\u0000\u0000\u0697\u0698\u0006\u00e3\f\u0000\u0698\u01d8\u0001\u0000\u0000"+
-    "\u0000C\u0000\u0001\u0002\u0003\u0004\u0005\u0006\u0007\b\t\n\u000b\f"+
-    "\r\u000e\u000f\u0010\u02b5\u02bf\u02c3\u02c6\u02cf\u02d1\u02dc\u02ef\u02f4"+
-    "\u02fd\u0304\u0309\u030b\u0316\u031e\u0321\u0323\u0328\u032d\u0333\u033a"+
-    "\u033f\u0345\u0348\u0350\u0354\u03d8\u03dd\u03e4\u03e6\u03f6\u03fb\u0400"+
-    "\u0402\u0408\u0455\u045a\u0489\u048d\u0492\u0497\u049c\u049e\u04a2\u04a4"+
-    "\u04f9\u04fd\u0502\u058f\u0591\'\u0005\u0001\u0000\u0005\u0004\u0000\u0005"+
-    "\u0006\u0000\u0005\u0002\u0000\u0005\u0003\u0000\u0005\b\u0000\u0005\u0005"+
-    "\u0000\u0005\t\u0000\u0005\r\u0000\u0005\u0010\u0000\u0005\u000b\u0000"+
-    "\u0005\u000e\u0000\u0000\u0001\u0000\u0004\u0000\u0000\u0007\u0010\u0000"+
-    "\u0007H\u0000\u0005\u0000\u0000\u0007\u001d\u0000\u0007I\u0000\u0007&"+
-    "\u0000\u0007\'\u0000\u0007$\u0000\u0007S\u0000\u0007\u001e\u0000\u0007"+
-    ")\u0000\u00075\u0000\u0007G\u0000\u0007W\u0000\u0005\n\u0000\u0005\u0007"+
-    "\u0000\u0007a\u0000\u0007`\u0000\u0007K\u0000\u0007J\u0000\u0007_\u0000"+
-    "\u0005\f\u0000\u0007[\u0000\u0005\u000f\u0000\u0007!\u0000";
+    "\u00db\u0001\u00db\u0001\u00db\u0001\u00db\u0001\u00dc\u0001\u00dc\u0001"+
+    "\u00dc\u0001\u00dc\u0001\u00dd\u0001\u00dd\u0001\u00dd\u0001\u00dd\u0001"+
+    "\u00de\u0001\u00de\u0001\u00de\u0001\u00de\u0001\u00df\u0001\u00df\u0001"+
+    "\u00df\u0001\u00df\u0001\u00e0\u0001\u00e0\u0001\u00e0\u0001\u00e0\u0001"+
+    "\u00e1\u0001\u00e1\u0001\u00e1\u0001\u00e1\u0001\u00e2\u0001\u00e2\u0001"+
+    "\u00e2\u0001\u00e2\u0001\u00e3\u0001\u00e3\u0001\u00e3\u0001\u00e3\u0001"+
+    "\u00e4\u0001\u00e4\u0001\u00e4\u0001\u00e4\u0001\u00e5\u0001\u00e5\u0001"+
+    "\u00e5\u0001\u00e5\u0001\u00e5\u0001\u00e6\u0001\u00e6\u0001\u00e6\u0001"+
+    "\u00e6\u0001\u00e7\u0001\u00e7\u0001\u00e7\u0001\u00e7\u0001\u00e8\u0001"+
+    "\u00e8\u0001\u00e8\u0001\u00e8\u0001\u00e9\u0001\u00e9\u0001\u00e9\u0001"+
+    "\u00e9\u0002\u02ea\u032f\u0000\u00ea\u0012\u0001\u0014\u0002\u0016\u0003"+
+    "\u0018\u0004\u001a\u0005\u001c\u0006\u001e\u0007 \b\"\t$\n&\u000b(\f*"+
+    "\r,\u000e.\u000f0\u00102\u00114\u00126\u00138\u0014:\u0015<\u0016>\u0017"+
+    "@\u0018B\u0019D\u001aF\u001bH\u001cJ\u001dL\u001eN\u0000P\u0000R\u0000"+
+    "T\u0000V\u0000X\u0000Z\u0000\\\u0000^\u0000`\u0000b\u001fd f!h\"j#l$n"+
+    "%p&r\'t(v)x*z+|,~-\u0080.\u0082/\u00840\u00861\u00882\u008a3\u008c4\u008e"+
+    "5\u00906\u00927\u00948\u00969\u0098:\u009a;\u009c<\u009e=\u00a0>\u00a2"+
+    "?\u00a4@\u00a6A\u00a8B\u00aaC\u00acD\u00aeE\u00b0F\u00b2G\u00b4\u0000"+
+    "\u00b6H\u00b8I\u00baJ\u00bcK\u00be\u0000\u00c0L\u00c2M\u00c4N\u00c6O\u00c8"+
+    "\u0000\u00ca\u0000\u00ccP\u00ceQ\u00d0R\u00d2\u0000\u00d4\u0000\u00d6"+
+    "\u0000\u00d8\u0000\u00da\u0000\u00dc\u0000\u00deS\u00e0\u0000\u00e2T\u00e4"+
+    "\u0000\u00e6\u0000\u00e8U\u00eaV\u00ecW\u00ee\u0000\u00f0\u0000\u00f2"+
+    "\u0000\u00f4\u0000\u00f6\u0000\u00f8\u0000\u00fa\u0000\u00fcX\u00feY\u0100"+
+    "Z\u0102[\u0104\u0000\u0106\u0000\u0108\u0000\u010a\u0000\u010c\u0000\u010e"+
+    "\u0000\u0110\\\u0112\u0000\u0114]\u0116^\u0118_\u011a\u0000\u011c\u0000"+
+    "\u011e`\u0120a\u0122\u0000\u0124b\u0126\u0000\u0128c\u012ad\u012ce\u012e"+
+    "\u0000\u0130\u0000\u0132\u0000\u0134\u0000\u0136\u0000\u0138\u0000\u013a"+
+    "\u0000\u013c\u0000\u013e\u0000\u0140f\u0142g\u0144h\u0146\u0000\u0148"+
+    "\u0000\u014a\u0000\u014c\u0000\u014e\u0000\u0150\u0000\u0152i\u0154j\u0156"+
+    "k\u0158\u0000\u015al\u015cm\u015en\u0160o\u0162\u0000\u0164\u0000\u0166"+
+    "p\u0168q\u016ar\u016cs\u016e\u0000\u0170\u0000\u0172\u0000\u0174\u0000"+
+    "\u0176\u0000\u0178\u0000\u017a\u0000\u017ct\u017eu\u0180v\u0182\u0000"+
+    "\u0184\u0000\u0186\u0000\u0188\u0000\u018aw\u018cx\u018ey\u0190\u0000"+
+    "\u0192z\u0194\u0000\u0196\u0000\u0198{\u019a\u0000\u019c\u0000\u019e\u0000"+
+    "\u01a0\u0000\u01a2\u0000\u01a4|\u01a6}\u01a8~\u01aa\u0000\u01ac\u0000"+
+    "\u01ae\u0000\u01b0\u007f\u01b2\u0080\u01b4\u0081\u01b6\u0000\u01b8\u0000"+
+    "\u01ba\u0082\u01bc\u0083\u01be\u0084\u01c0\u0000\u01c2\u0000\u01c4\u0000"+
+    "\u01c6\u0000\u01c8\u0000\u01ca\u0000\u01cc\u0000\u01ce\u0000\u01d0\u0000"+
+    "\u01d2\u0000\u01d4\u0000\u01d6\u0085\u01d8\u0086\u01da\u0087\u01dc\u0000"+
+    "\u01de\u0000\u01e0\u0088\u01e2\u0089\u01e4\u008a\u0012\u0000\u0001\u0002"+
+    "\u0003\u0004\u0005\u0006\u0007\b\t\n\u000b\f\r\u000e\u000f\u0010\u0011"+
+    "$\u0002\u0000DDdd\u0002\u0000IIii\u0002\u0000SSss\u0002\u0000EEee\u0002"+
+    "\u0000CCcc\u0002\u0000TTtt\u0002\u0000RRrr\u0002\u0000OOoo\u0002\u0000"+
+    "PPpp\u0002\u0000NNnn\u0002\u0000HHhh\u0002\u0000VVvv\u0002\u0000AAaa\u0002"+
+    "\u0000LLll\u0002\u0000XXxx\u0002\u0000FFff\u0002\u0000MMmm\u0002\u0000"+
+    "GGgg\u0002\u0000KKkk\u0002\u0000WWww\u0002\u0000UUuu\u0006\u0000\t\n\r"+
+    "\r  //[[]]\u0002\u0000\n\n\r\r\u0003\u0000\t\n\r\r  \u0001\u000009\u0002"+
+    "\u0000AZaz\b\u0000\"\"NNRRTT\\\\nnrrtt\u0004\u0000\n\n\r\r\"\"\\\\\u0002"+
+    "\u0000++--\u0001\u0000``\u0002\u0000BBbb\u0002\u0000YYyy\u000b\u0000\t"+
+    "\n\r\r  \"\",,//::==[[]]||\u0002\u0000**//\u000b\u0000\t\n\r\r  \"#,,"+
+    "//::<<>?\\\\||\u0002\u0000JJjj\u06e0\u0000\u0012\u0001\u0000\u0000\u0000"+
+    "\u0000\u0014\u0001\u0000\u0000\u0000\u0000\u0016\u0001\u0000\u0000\u0000"+
+    "\u0000\u0018\u0001\u0000\u0000\u0000\u0000\u001a\u0001\u0000\u0000\u0000"+
+    "\u0000\u001c\u0001\u0000\u0000\u0000\u0000\u001e\u0001\u0000\u0000\u0000"+
+    "\u0000 \u0001\u0000\u0000\u0000\u0000\"\u0001\u0000\u0000\u0000\u0000"+
+    "$\u0001\u0000\u0000\u0000\u0000&\u0001\u0000\u0000\u0000\u0000(\u0001"+
+    "\u0000\u0000\u0000\u0000*\u0001\u0000\u0000\u0000\u0000,\u0001\u0000\u0000"+
+    "\u0000\u0000.\u0001\u0000\u0000\u0000\u00000\u0001\u0000\u0000\u0000\u0000"+
+    "2\u0001\u0000\u0000\u0000\u00004\u0001\u0000\u0000\u0000\u00006\u0001"+
+    "\u0000\u0000\u0000\u00008\u0001\u0000\u0000\u0000\u0000:\u0001\u0000\u0000"+
+    "\u0000\u0000<\u0001\u0000\u0000\u0000\u0000>\u0001\u0000\u0000\u0000\u0000"+
+    "@\u0001\u0000\u0000\u0000\u0000B\u0001\u0000\u0000\u0000\u0000D\u0001"+
+    "\u0000\u0000\u0000\u0000F\u0001\u0000\u0000\u0000\u0000H\u0001\u0000\u0000"+
+    "\u0000\u0000J\u0001\u0000\u0000\u0000\u0001L\u0001\u0000\u0000\u0000\u0001"+
+    "b\u0001\u0000\u0000\u0000\u0001d\u0001\u0000\u0000\u0000\u0001f\u0001"+
+    "\u0000\u0000\u0000\u0001h\u0001\u0000\u0000\u0000\u0001j\u0001\u0000\u0000"+
+    "\u0000\u0001l\u0001\u0000\u0000\u0000\u0001n\u0001\u0000\u0000\u0000\u0001"+
+    "p\u0001\u0000\u0000\u0000\u0001r\u0001\u0000\u0000\u0000\u0001t\u0001"+
+    "\u0000\u0000\u0000\u0001v\u0001\u0000\u0000\u0000\u0001x\u0001\u0000\u0000"+
+    "\u0000\u0001z\u0001\u0000\u0000\u0000\u0001|\u0001\u0000\u0000\u0000\u0001"+
+    "~\u0001\u0000\u0000\u0000\u0001\u0080\u0001\u0000\u0000\u0000\u0001\u0082"+
+    "\u0001\u0000\u0000\u0000\u0001\u0084\u0001\u0000\u0000\u0000\u0001\u0086"+
+    "\u0001\u0000\u0000\u0000\u0001\u0088\u0001\u0000\u0000\u0000\u0001\u008a"+
+    "\u0001\u0000\u0000\u0000\u0001\u008c\u0001\u0000\u0000\u0000\u0001\u008e"+
+    "\u0001\u0000\u0000\u0000\u0001\u0090\u0001\u0000\u0000\u0000\u0001\u0092"+
+    "\u0001\u0000\u0000\u0000\u0001\u0094\u0001\u0000\u0000\u0000\u0001\u0096"+
+    "\u0001\u0000\u0000\u0000\u0001\u0098\u0001\u0000\u0000\u0000\u0001\u009a"+
+    "\u0001\u0000\u0000\u0000\u0001\u009c\u0001\u0000\u0000\u0000\u0001\u009e"+
+    "\u0001\u0000\u0000\u0000\u0001\u00a0\u0001\u0000\u0000\u0000\u0001\u00a2"+
+    "\u0001\u0000\u0000\u0000\u0001\u00a4\u0001\u0000\u0000\u0000\u0001\u00a6"+
+    "\u0001\u0000\u0000\u0000\u0001\u00a8\u0001\u0000\u0000\u0000\u0001\u00aa"+
+    "\u0001\u0000\u0000\u0000\u0001\u00ac\u0001\u0000\u0000\u0000\u0001\u00ae"+
+    "\u0001\u0000\u0000\u0000\u0001\u00b0\u0001\u0000\u0000\u0000\u0001\u00b2"+
+    "\u0001\u0000\u0000\u0000\u0001\u00b4\u0001\u0000\u0000\u0000\u0001\u00b6"+
+    "\u0001\u0000\u0000\u0000\u0001\u00b8\u0001\u0000\u0000\u0000\u0001\u00ba"+
+    "\u0001\u0000\u0000\u0000\u0001\u00bc\u0001\u0000\u0000\u0000\u0001\u00c0"+
+    "\u0001\u0000\u0000\u0000\u0001\u00c2\u0001\u0000\u0000\u0000\u0001\u00c4"+
+    "\u0001\u0000\u0000\u0000\u0001\u00c6\u0001\u0000\u0000\u0000\u0002\u00c8"+
+    "\u0001\u0000\u0000\u0000\u0002\u00ca\u0001\u0000\u0000\u0000\u0002\u00cc"+
+    "\u0001\u0000\u0000\u0000\u0002\u00ce\u0001\u0000\u0000\u0000\u0002\u00d0"+
+    "\u0001\u0000\u0000\u0000\u0003\u00d2\u0001\u0000\u0000\u0000\u0003\u00d4"+
+    "\u0001\u0000\u0000\u0000\u0003\u00d6\u0001\u0000\u0000\u0000\u0003\u00d8"+
+    "\u0001\u0000\u0000\u0000\u0003\u00da\u0001\u0000\u0000\u0000\u0003\u00dc"+
+    "\u0001\u0000\u0000\u0000\u0003\u00de\u0001\u0000\u0000\u0000\u0003\u00e2"+
+    "\u0001\u0000\u0000\u0000\u0003\u00e4\u0001\u0000\u0000\u0000\u0003\u00e6"+
+    "\u0001\u0000\u0000\u0000\u0003\u00e8\u0001\u0000\u0000\u0000\u0003\u00ea"+
+    "\u0001\u0000\u0000\u0000\u0003\u00ec\u0001\u0000\u0000\u0000\u0004\u00ee"+
+    "\u0001\u0000\u0000\u0000\u0004\u00f0\u0001\u0000\u0000\u0000\u0004\u00f2"+
+    "\u0001\u0000\u0000\u0000\u0004\u00f4\u0001\u0000\u0000\u0000\u0004\u00f6"+
+    "\u0001\u0000\u0000\u0000\u0004\u00fc\u0001\u0000\u0000\u0000\u0004\u00fe"+
+    "\u0001\u0000\u0000\u0000\u0004\u0100\u0001\u0000\u0000\u0000\u0004\u0102"+
+    "\u0001\u0000\u0000\u0000\u0005\u0104\u0001\u0000\u0000\u0000\u0005\u0106"+
+    "\u0001\u0000\u0000\u0000\u0005\u0108\u0001\u0000\u0000\u0000\u0005\u010a"+
+    "\u0001\u0000\u0000\u0000\u0005\u010c\u0001\u0000\u0000\u0000\u0005\u010e"+
+    "\u0001\u0000\u0000\u0000\u0005\u0110\u0001\u0000\u0000\u0000\u0005\u0112"+
+    "\u0001\u0000\u0000\u0000\u0005\u0114\u0001\u0000\u0000\u0000\u0005\u0116"+
+    "\u0001\u0000\u0000\u0000\u0005\u0118\u0001\u0000\u0000\u0000\u0006\u011a"+
+    "\u0001\u0000\u0000\u0000\u0006\u011c\u0001\u0000\u0000\u0000\u0006\u011e"+
+    "\u0001\u0000\u0000\u0000\u0006\u0120\u0001\u0000\u0000\u0000\u0006\u0124"+
+    "\u0001\u0000\u0000\u0000\u0006\u0126\u0001\u0000\u0000\u0000\u0006\u0128"+
+    "\u0001\u0000\u0000\u0000\u0006\u012a\u0001\u0000\u0000\u0000\u0006\u012c"+
+    "\u0001\u0000\u0000\u0000\u0007\u012e\u0001\u0000\u0000\u0000\u0007\u0130"+
+    "\u0001\u0000\u0000\u0000\u0007\u0132\u0001\u0000\u0000\u0000\u0007\u0134"+
+    "\u0001\u0000\u0000\u0000\u0007\u0136\u0001\u0000\u0000\u0000\u0007\u0138"+
+    "\u0001\u0000\u0000\u0000\u0007\u013a\u0001\u0000\u0000\u0000\u0007\u013c"+
+    "\u0001\u0000\u0000\u0000\u0007\u013e\u0001\u0000\u0000\u0000\u0007\u0140"+
+    "\u0001\u0000\u0000\u0000\u0007\u0142\u0001\u0000\u0000\u0000\u0007\u0144"+
+    "\u0001\u0000\u0000\u0000\b\u0146\u0001\u0000\u0000\u0000\b\u0148\u0001"+
+    "\u0000\u0000\u0000\b\u014a\u0001\u0000\u0000\u0000\b\u014c\u0001\u0000"+
+    "\u0000\u0000\b\u014e\u0001\u0000\u0000\u0000\b\u0150\u0001\u0000\u0000"+
+    "\u0000\b\u0152\u0001\u0000\u0000\u0000\b\u0154\u0001\u0000\u0000\u0000"+
+    "\b\u0156\u0001\u0000\u0000\u0000\t\u0158\u0001\u0000\u0000\u0000\t\u015a"+
+    "\u0001\u0000\u0000\u0000\t\u015c\u0001\u0000\u0000\u0000\t\u015e\u0001"+
+    "\u0000\u0000\u0000\t\u0160\u0001\u0000\u0000\u0000\n\u0162\u0001\u0000"+
+    "\u0000\u0000\n\u0164\u0001\u0000\u0000\u0000\n\u0166\u0001\u0000\u0000"+
+    "\u0000\n\u0168\u0001\u0000\u0000\u0000\n\u016a\u0001\u0000\u0000\u0000"+
+    "\n\u016c\u0001\u0000\u0000\u0000\u000b\u016e\u0001\u0000\u0000\u0000\u000b"+
+    "\u0170\u0001\u0000\u0000\u0000\u000b\u0172\u0001\u0000\u0000\u0000\u000b"+
+    "\u0174\u0001\u0000\u0000\u0000\u000b\u0176\u0001\u0000\u0000\u0000\u000b"+
+    "\u0178\u0001\u0000\u0000\u0000\u000b\u017a\u0001\u0000\u0000\u0000\u000b"+
+    "\u017c\u0001\u0000\u0000\u0000\u000b\u017e\u0001\u0000\u0000\u0000\u000b"+
+    "\u0180\u0001\u0000\u0000\u0000\f\u0182\u0001\u0000\u0000\u0000\f\u0184"+
+    "\u0001\u0000\u0000\u0000\f\u0186\u0001\u0000\u0000\u0000\f\u0188\u0001"+
+    "\u0000\u0000\u0000\f\u018a\u0001\u0000\u0000\u0000\f\u018c\u0001\u0000"+
+    "\u0000\u0000\f\u018e\u0001\u0000\u0000\u0000\r\u0190\u0001\u0000\u0000"+
+    "\u0000\r\u0192\u0001\u0000\u0000\u0000\r\u0194\u0001\u0000\u0000\u0000"+
+    "\r\u0196\u0001\u0000\u0000\u0000\r\u0198\u0001\u0000\u0000\u0000\r\u019a"+
+    "\u0001\u0000\u0000\u0000\r\u019c\u0001\u0000\u0000\u0000\r\u019e\u0001"+
+    "\u0000\u0000\u0000\r\u01a0\u0001\u0000\u0000\u0000\r\u01a2\u0001\u0000"+
+    "\u0000\u0000\r\u01a4\u0001\u0000\u0000\u0000\r\u01a6\u0001\u0000\u0000"+
+    "\u0000\r\u01a8\u0001\u0000\u0000\u0000\u000e\u01aa\u0001\u0000\u0000\u0000"+
+    "\u000e\u01ac\u0001\u0000\u0000\u0000\u000e\u01ae\u0001\u0000\u0000\u0000"+
+    "\u000e\u01b0\u0001\u0000\u0000\u0000\u000e\u01b2\u0001\u0000\u0000\u0000"+
+    "\u000e\u01b4\u0001\u0000\u0000\u0000\u000f\u01b6\u0001\u0000\u0000\u0000"+
+    "\u000f\u01b8\u0001\u0000\u0000\u0000\u000f\u01ba\u0001\u0000\u0000\u0000"+
+    "\u000f\u01bc\u0001\u0000\u0000\u0000\u000f\u01be\u0001\u0000\u0000\u0000"+
+    "\u000f\u01c0\u0001\u0000\u0000\u0000\u000f\u01c2\u0001\u0000\u0000\u0000"+
+    "\u000f\u01c4\u0001\u0000\u0000\u0000\u000f\u01c6\u0001\u0000\u0000\u0000"+
+    "\u0010\u01c8\u0001\u0000\u0000\u0000\u0010\u01ca\u0001\u0000\u0000\u0000"+
+    "\u0010\u01cc\u0001\u0000\u0000\u0000\u0010\u01ce\u0001\u0000\u0000\u0000"+
+    "\u0010\u01d0\u0001\u0000\u0000\u0000\u0010\u01d2\u0001\u0000\u0000\u0000"+
+    "\u0010\u01d4\u0001\u0000\u0000\u0000\u0010\u01d6\u0001\u0000\u0000\u0000"+
+    "\u0010\u01d8\u0001\u0000\u0000\u0000\u0010\u01da\u0001\u0000\u0000\u0000"+
+    "\u0011\u01dc\u0001\u0000\u0000\u0000\u0011\u01de\u0001\u0000\u0000\u0000"+
+    "\u0011\u01e0\u0001\u0000\u0000\u0000\u0011\u01e2\u0001\u0000\u0000\u0000"+
+    "\u0011\u01e4\u0001\u0000\u0000\u0000\u0012\u01e6\u0001\u0000\u0000\u0000"+
+    "\u0014\u01f0\u0001\u0000\u0000\u0000\u0016\u01f7\u0001\u0000\u0000\u0000"+
+    "\u0018\u0200\u0001\u0000\u0000\u0000\u001a\u0207\u0001\u0000\u0000\u0000"+
+    "\u001c\u0211\u0001\u0000\u0000\u0000\u001e\u0218\u0001\u0000\u0000\u0000"+
+    " \u021f\u0001\u0000\u0000\u0000\"\u0226\u0001\u0000\u0000\u0000$\u022e"+
+    "\u0001\u0000\u0000\u0000&\u023a\u0001\u0000\u0000\u0000(\u0243\u0001\u0000"+
+    "\u0000\u0000*\u0249\u0001\u0000\u0000\u0000,\u0250\u0001\u0000\u0000\u0000"+
+    ".\u0257\u0001\u0000\u0000\u00000\u025f\u0001\u0000\u0000\u00002\u0267"+
+    "\u0001\u0000\u0000\u00004\u0270\u0001\u0000\u0000\u00006\u0280\u0001\u0000"+
+    "\u0000\u00008\u028f\u0001\u0000\u0000\u0000:\u029b\u0001\u0000\u0000\u0000"+
+    "<\u02a7\u0001\u0000\u0000\u0000>\u02b2\u0001\u0000\u0000\u0000@\u02ba"+
+    "\u0001\u0000\u0000\u0000B\u02c2\u0001\u0000\u0000\u0000D\u02cc\u0001\u0000"+
+    "\u0000\u0000F\u02d2\u0001\u0000\u0000\u0000H\u02e3\u0001\u0000\u0000\u0000"+
+    "J\u02f3\u0001\u0000\u0000\u0000L\u02f9\u0001\u0000\u0000\u0000N\u02fd"+
+    "\u0001\u0000\u0000\u0000P\u02ff\u0001\u0000\u0000\u0000R\u0301\u0001\u0000"+
+    "\u0000\u0000T\u0304\u0001\u0000\u0000\u0000V\u0306\u0001\u0000\u0000\u0000"+
+    "X\u030f\u0001\u0000\u0000\u0000Z\u0311\u0001\u0000\u0000\u0000\\\u0316"+
+    "\u0001\u0000\u0000\u0000^\u0318\u0001\u0000\u0000\u0000`\u031d\u0001\u0000"+
+    "\u0000\u0000b\u033c\u0001\u0000\u0000\u0000d\u033f\u0001\u0000\u0000\u0000"+
+    "f\u036d\u0001\u0000\u0000\u0000h\u036f\u0001\u0000\u0000\u0000j\u0372"+
+    "\u0001\u0000\u0000\u0000l\u0376\u0001\u0000\u0000\u0000n\u037a\u0001\u0000"+
+    "\u0000\u0000p\u037c\u0001\u0000\u0000\u0000r\u037f\u0001\u0000\u0000\u0000"+
+    "t\u0381\u0001\u0000\u0000\u0000v\u0383\u0001\u0000\u0000\u0000x\u0388"+
+    "\u0001\u0000\u0000\u0000z\u038a\u0001\u0000\u0000\u0000|\u0390\u0001\u0000"+
+    "\u0000\u0000~\u0396\u0001\u0000\u0000\u0000\u0080\u0399\u0001\u0000\u0000"+
+    "\u0000\u0082\u039c\u0001\u0000\u0000\u0000\u0084\u03a1\u0001\u0000\u0000"+
+    "\u0000\u0086\u03a6\u0001\u0000\u0000\u0000\u0088\u03a8\u0001\u0000\u0000"+
+    "\u0000\u008a\u03ac\u0001\u0000\u0000\u0000\u008c\u03b1\u0001\u0000\u0000"+
+    "\u0000\u008e\u03b7\u0001\u0000\u0000\u0000\u0090\u03ba\u0001\u0000\u0000"+
+    "\u0000\u0092\u03bc\u0001\u0000\u0000\u0000\u0094\u03c2\u0001\u0000\u0000"+
+    "\u0000\u0096\u03c4\u0001\u0000\u0000\u0000\u0098\u03c9\u0001\u0000\u0000"+
+    "\u0000\u009a\u03cc\u0001\u0000\u0000\u0000\u009c\u03cf\u0001\u0000\u0000"+
+    "\u0000\u009e\u03d2\u0001\u0000\u0000\u0000\u00a0\u03d4\u0001\u0000\u0000"+
+    "\u0000\u00a2\u03d7\u0001\u0000\u0000\u0000\u00a4\u03d9\u0001\u0000\u0000"+
+    "\u0000\u00a6\u03dc\u0001\u0000\u0000\u0000\u00a8\u03de\u0001\u0000\u0000"+
+    "\u0000\u00aa\u03e0\u0001\u0000\u0000\u0000\u00ac\u03e2\u0001\u0000\u0000"+
+    "\u0000\u00ae\u03e4\u0001\u0000\u0000\u0000\u00b0\u03e6\u0001\u0000\u0000"+
+    "\u0000\u00b2\u03e8\u0001\u0000\u0000\u0000\u00b4\u03ea\u0001\u0000\u0000"+
+    "\u0000\u00b6\u03ff\u0001\u0000\u0000\u0000\u00b8\u0401\u0001\u0000\u0000"+
+    "\u0000\u00ba\u0406\u0001\u0000\u0000\u0000\u00bc\u041b\u0001\u0000\u0000"+
+    "\u0000\u00be\u041d\u0001\u0000\u0000\u0000\u00c0\u0425\u0001\u0000\u0000"+
+    "\u0000\u00c2\u0427\u0001\u0000\u0000\u0000\u00c4\u042b\u0001\u0000\u0000"+
+    "\u0000\u00c6\u042f\u0001\u0000\u0000\u0000\u00c8\u0433\u0001\u0000\u0000"+
+    "\u0000\u00ca\u0438\u0001\u0000\u0000\u0000\u00cc\u043d\u0001\u0000\u0000"+
+    "\u0000\u00ce\u0441\u0001\u0000\u0000\u0000\u00d0\u0445\u0001\u0000\u0000"+
+    "\u0000\u00d2\u0449\u0001\u0000\u0000\u0000\u00d4\u044e\u0001\u0000\u0000"+
+    "\u0000\u00d6\u0452\u0001\u0000\u0000\u0000\u00d8\u0456\u0001\u0000\u0000"+
+    "\u0000\u00da\u045a\u0001\u0000\u0000\u0000\u00dc\u045e\u0001\u0000\u0000"+
+    "\u0000\u00de\u0462\u0001\u0000\u0000\u0000\u00e0\u046e\u0001\u0000\u0000"+
+    "\u0000\u00e2\u0471\u0001\u0000\u0000\u0000\u00e4\u0475\u0001\u0000\u0000"+
+    "\u0000\u00e6\u0479\u0001\u0000\u0000\u0000\u00e8\u047d\u0001\u0000\u0000"+
+    "\u0000\u00ea\u0481\u0001\u0000\u0000\u0000\u00ec\u0485\u0001\u0000\u0000"+
+    "\u0000\u00ee\u0489\u0001\u0000\u0000\u0000\u00f0\u048e\u0001\u0000\u0000"+
+    "\u0000\u00f2\u0492\u0001\u0000\u0000\u0000\u00f4\u0496\u0001\u0000\u0000"+
+    "\u0000\u00f6\u049a\u0001\u0000\u0000\u0000\u00f8\u04a2\u0001\u0000\u0000"+
+    "\u0000\u00fa\u04b7\u0001\u0000\u0000\u0000\u00fc\u04bb\u0001\u0000\u0000"+
+    "\u0000\u00fe\u04bf\u0001\u0000\u0000\u0000\u0100\u04c3\u0001\u0000\u0000"+
+    "\u0000\u0102\u04c7\u0001\u0000\u0000\u0000\u0104\u04cb\u0001\u0000\u0000"+
+    "\u0000\u0106\u04d0\u0001\u0000\u0000\u0000\u0108\u04d4\u0001\u0000\u0000"+
+    "\u0000\u010a\u04d8\u0001\u0000\u0000\u0000\u010c\u04dc\u0001\u0000\u0000"+
+    "\u0000\u010e\u04e0\u0001\u0000\u0000\u0000\u0110\u04e4\u0001\u0000\u0000"+
+    "\u0000\u0112\u04e7\u0001\u0000\u0000\u0000\u0114\u04eb\u0001\u0000\u0000"+
+    "\u0000\u0116\u04ef\u0001\u0000\u0000\u0000\u0118\u04f3\u0001\u0000\u0000"+
+    "\u0000\u011a\u04f7\u0001\u0000\u0000\u0000\u011c\u04fc\u0001\u0000\u0000"+
+    "\u0000\u011e\u0501\u0001\u0000\u0000\u0000\u0120\u0506\u0001\u0000\u0000"+
+    "\u0000\u0122\u050d\u0001\u0000\u0000\u0000\u0124\u0516\u0001\u0000\u0000"+
+    "\u0000\u0126\u051d\u0001\u0000\u0000\u0000\u0128\u0521\u0001\u0000\u0000"+
+    "\u0000\u012a\u0525\u0001\u0000\u0000\u0000\u012c\u0529\u0001\u0000\u0000"+
+    "\u0000\u012e\u052d\u0001\u0000\u0000\u0000\u0130\u0533\u0001\u0000\u0000"+
+    "\u0000\u0132\u0537\u0001\u0000\u0000\u0000\u0134\u053b\u0001\u0000\u0000"+
+    "\u0000\u0136\u053f\u0001\u0000\u0000\u0000\u0138\u0543\u0001\u0000\u0000"+
+    "\u0000\u013a\u0547\u0001\u0000\u0000\u0000\u013c\u054b\u0001\u0000\u0000"+
+    "\u0000\u013e\u054f\u0001\u0000\u0000\u0000\u0140\u0553\u0001\u0000\u0000"+
+    "\u0000\u0142\u0557\u0001\u0000\u0000\u0000\u0144\u055b\u0001\u0000\u0000"+
+    "\u0000\u0146\u055f\u0001\u0000\u0000\u0000\u0148\u0564\u0001\u0000\u0000"+
+    "\u0000\u014a\u0568\u0001\u0000\u0000\u0000\u014c\u056c\u0001\u0000\u0000"+
+    "\u0000\u014e\u0570\u0001\u0000\u0000\u0000\u0150\u0574\u0001\u0000\u0000"+
+    "\u0000\u0152\u0578\u0001\u0000\u0000\u0000\u0154\u057c\u0001\u0000\u0000"+
+    "\u0000\u0156\u0580\u0001\u0000\u0000\u0000\u0158\u0584\u0001\u0000\u0000"+
+    "\u0000\u015a\u0589\u0001\u0000\u0000\u0000\u015c\u058e\u0001\u0000\u0000"+
+    "\u0000\u015e\u0592\u0001\u0000\u0000\u0000\u0160\u0596\u0001\u0000\u0000"+
+    "\u0000\u0162\u059a\u0001\u0000\u0000\u0000\u0164\u059f\u0001\u0000\u0000"+
+    "\u0000\u0166\u05a8\u0001\u0000\u0000\u0000\u0168\u05ac\u0001\u0000\u0000"+
+    "\u0000\u016a\u05b0\u0001\u0000\u0000\u0000\u016c\u05b4\u0001\u0000\u0000"+
+    "\u0000\u016e\u05b8\u0001\u0000\u0000\u0000\u0170\u05bd\u0001\u0000\u0000"+
+    "\u0000\u0172\u05c1\u0001\u0000\u0000\u0000\u0174\u05c5\u0001\u0000\u0000"+
+    "\u0000\u0176\u05c9\u0001\u0000\u0000\u0000\u0178\u05ce\u0001\u0000\u0000"+
+    "\u0000\u017a\u05d2\u0001\u0000\u0000\u0000\u017c\u05d6\u0001\u0000\u0000"+
+    "\u0000\u017e\u05da\u0001\u0000\u0000\u0000\u0180\u05de\u0001\u0000\u0000"+
+    "\u0000\u0182\u05e2\u0001\u0000\u0000\u0000\u0184\u05e8\u0001\u0000\u0000"+
+    "\u0000\u0186\u05ec\u0001\u0000\u0000\u0000\u0188\u05f0\u0001\u0000\u0000"+
+    "\u0000\u018a\u05f4\u0001\u0000\u0000\u0000\u018c\u05f8\u0001\u0000\u0000"+
+    "\u0000\u018e\u05fc\u0001\u0000\u0000\u0000\u0190\u0600\u0001\u0000\u0000"+
+    "\u0000\u0192\u0605\u0001\u0000\u0000\u0000\u0194\u060a\u0001\u0000\u0000"+
+    "\u0000\u0196\u060e\u0001\u0000\u0000\u0000\u0198\u0614\u0001\u0000\u0000"+
+    "\u0000\u019a\u061d\u0001\u0000\u0000\u0000\u019c\u0621\u0001\u0000\u0000"+
+    "\u0000\u019e\u0625\u0001\u0000\u0000\u0000\u01a0\u0629\u0001\u0000\u0000"+
+    "\u0000\u01a2\u062d\u0001\u0000\u0000\u0000\u01a4\u0631\u0001\u0000\u0000"+
+    "\u0000\u01a6\u0635\u0001\u0000\u0000\u0000\u01a8\u0639\u0001\u0000\u0000"+
+    "\u0000\u01aa\u063d\u0001\u0000\u0000\u0000\u01ac\u0642\u0001\u0000\u0000"+
+    "\u0000\u01ae\u0648\u0001\u0000\u0000\u0000\u01b0\u064e\u0001\u0000\u0000"+
+    "\u0000\u01b2\u0652\u0001\u0000\u0000\u0000\u01b4\u0656\u0001\u0000\u0000"+
+    "\u0000\u01b6\u065a\u0001\u0000\u0000\u0000\u01b8\u0660\u0001\u0000\u0000"+
+    "\u0000\u01ba\u0666\u0001\u0000\u0000\u0000\u01bc\u066a\u0001\u0000\u0000"+
+    "\u0000\u01be\u066e\u0001\u0000\u0000\u0000\u01c0\u0672\u0001\u0000\u0000"+
+    "\u0000\u01c2\u0678\u0001\u0000\u0000\u0000\u01c4\u067e\u0001\u0000\u0000"+
+    "\u0000\u01c6\u0684\u0001\u0000\u0000\u0000\u01c8\u0689\u0001\u0000\u0000"+
+    "\u0000\u01ca\u068e\u0001\u0000\u0000\u0000\u01cc\u0692\u0001\u0000\u0000"+
+    "\u0000\u01ce\u0696\u0001\u0000\u0000\u0000\u01d0\u069a\u0001\u0000\u0000"+
+    "\u0000\u01d2\u069e\u0001\u0000\u0000\u0000\u01d4\u06a2\u0001\u0000\u0000"+
+    "\u0000\u01d6\u06a6\u0001\u0000\u0000\u0000\u01d8\u06aa\u0001\u0000\u0000"+
+    "\u0000\u01da\u06ae\u0001\u0000\u0000\u0000\u01dc\u06b2\u0001\u0000\u0000"+
+    "\u0000\u01de\u06b7\u0001\u0000\u0000\u0000\u01e0\u06bb\u0001\u0000\u0000"+
+    "\u0000\u01e2\u06bf\u0001\u0000\u0000\u0000\u01e4\u06c3\u0001\u0000\u0000"+
+    "\u0000\u01e6\u01e7\u0007\u0000\u0000\u0000\u01e7\u01e8\u0007\u0001\u0000"+
+    "\u0000\u01e8\u01e9\u0007\u0002\u0000\u0000\u01e9\u01ea\u0007\u0002\u0000"+
+    "\u0000\u01ea\u01eb\u0007\u0003\u0000\u0000\u01eb\u01ec\u0007\u0004\u0000"+
+    "\u0000\u01ec\u01ed\u0007\u0005\u0000\u0000\u01ed\u01ee\u0001\u0000\u0000"+
+    "\u0000\u01ee\u01ef\u0006\u0000\u0000\u0000\u01ef\u0013\u0001\u0000\u0000"+
+    "\u0000\u01f0\u01f1\u0007\u0000\u0000\u0000\u01f1\u01f2\u0007\u0006\u0000"+
+    "\u0000\u01f2\u01f3\u0007\u0007\u0000\u0000\u01f3\u01f4\u0007\b\u0000\u0000"+
+    "\u01f4\u01f5\u0001\u0000\u0000\u0000\u01f5\u01f6\u0006\u0001\u0001\u0000"+
+    "\u01f6\u0015\u0001\u0000\u0000\u0000\u01f7\u01f8\u0007\u0003\u0000\u0000"+
+    "\u01f8\u01f9\u0007\t\u0000\u0000\u01f9\u01fa\u0007\u0006\u0000\u0000\u01fa"+
+    "\u01fb\u0007\u0001\u0000\u0000\u01fb\u01fc\u0007\u0004\u0000\u0000\u01fc"+
+    "\u01fd\u0007\n\u0000\u0000\u01fd\u01fe\u0001\u0000\u0000\u0000\u01fe\u01ff"+
+    "\u0006\u0002\u0002\u0000\u01ff\u0017\u0001\u0000\u0000\u0000\u0200\u0201"+
+    "\u0007\u0003\u0000\u0000\u0201\u0202\u0007\u000b\u0000\u0000\u0202\u0203"+
+    "\u0007\f\u0000\u0000\u0203\u0204\u0007\r\u0000\u0000\u0204\u0205\u0001"+
+    "\u0000\u0000\u0000\u0205\u0206\u0006\u0003\u0000\u0000\u0206\u0019\u0001"+
+    "\u0000\u0000\u0000\u0207\u0208\u0007\u0003\u0000\u0000\u0208\u0209\u0007"+
+    "\u000e\u0000\u0000\u0209\u020a\u0007\b\u0000\u0000\u020a\u020b\u0007\r"+
+    "\u0000\u0000\u020b\u020c\u0007\f\u0000\u0000\u020c\u020d\u0007\u0001\u0000"+
+    "\u0000\u020d\u020e\u0007\t\u0000\u0000\u020e\u020f\u0001\u0000\u0000\u0000"+
+    "\u020f\u0210\u0006\u0004\u0003\u0000\u0210\u001b\u0001\u0000\u0000\u0000"+
+    "\u0211\u0212\u0007\u000f\u0000\u0000\u0212\u0213\u0007\u0006\u0000\u0000"+
+    "\u0213\u0214\u0007\u0007\u0000\u0000\u0214\u0215\u0007\u0010\u0000\u0000"+
+    "\u0215\u0216\u0001\u0000\u0000\u0000\u0216\u0217\u0006\u0005\u0004\u0000"+
+    "\u0217\u001d\u0001\u0000\u0000\u0000\u0218\u0219\u0007\u0011\u0000\u0000"+
+    "\u0219\u021a\u0007\u0006\u0000\u0000\u021a\u021b\u0007\u0007\u0000\u0000"+
+    "\u021b\u021c\u0007\u0012\u0000\u0000\u021c\u021d\u0001\u0000\u0000\u0000"+
+    "\u021d\u021e\u0006\u0006\u0000\u0000\u021e\u001f\u0001\u0000\u0000\u0000"+
+    "\u021f\u0220\u0007\u0012\u0000\u0000\u0220\u0221\u0007\u0003\u0000\u0000"+
+    "\u0221\u0222\u0007\u0003\u0000\u0000\u0222\u0223\u0007\b\u0000\u0000\u0223"+
+    "\u0224\u0001\u0000\u0000\u0000\u0224\u0225\u0006\u0007\u0001\u0000\u0225"+
+    "!\u0001\u0000\u0000\u0000\u0226\u0227\u0007\r\u0000\u0000\u0227\u0228"+
+    "\u0007\u0001\u0000\u0000\u0228\u0229\u0007\u0010\u0000\u0000\u0229\u022a"+
+    "\u0007\u0001\u0000\u0000\u022a\u022b\u0007\u0005\u0000\u0000\u022b\u022c"+
+    "\u0001\u0000\u0000\u0000\u022c\u022d\u0006\b\u0000\u0000\u022d#\u0001"+
+    "\u0000\u0000\u0000\u022e\u022f\u0007\u0010\u0000\u0000\u022f\u0230\u0007"+
+    "\u000b\u0000\u0000\u0230\u0231\u0005_\u0000\u0000\u0231\u0232\u0007\u0003"+
+    "\u0000\u0000\u0232\u0233\u0007\u000e\u0000\u0000\u0233\u0234\u0007\b\u0000"+
+    "\u0000\u0234\u0235\u0007\f\u0000\u0000\u0235\u0236\u0007\t\u0000\u0000"+
+    "\u0236\u0237\u0007\u0000\u0000\u0000\u0237\u0238\u0001\u0000\u0000\u0000"+
+    "\u0238\u0239\u0006\t\u0005\u0000\u0239%\u0001\u0000\u0000\u0000\u023a"+
+    "\u023b\u0007\u0006\u0000\u0000\u023b\u023c\u0007\u0003\u0000\u0000\u023c"+
+    "\u023d\u0007\t\u0000\u0000\u023d\u023e\u0007\f\u0000\u0000\u023e\u023f"+
+    "\u0007\u0010\u0000\u0000\u023f\u0240\u0007\u0003\u0000\u0000\u0240\u0241"+
+    "\u0001\u0000\u0000\u0000\u0241\u0242\u0006\n\u0006\u0000\u0242\'\u0001"+
+    "\u0000\u0000\u0000\u0243\u0244\u0007\u0006\u0000\u0000\u0244\u0245\u0007"+
+    "\u0007\u0000\u0000\u0245\u0246\u0007\u0013\u0000\u0000\u0246\u0247\u0001"+
+    "\u0000\u0000\u0000\u0247\u0248\u0006\u000b\u0000\u0000\u0248)\u0001\u0000"+
+    "\u0000\u0000\u0249\u024a\u0007\u0002\u0000\u0000\u024a\u024b\u0007\n\u0000"+
+    "\u0000\u024b\u024c\u0007\u0007\u0000\u0000\u024c\u024d\u0007\u0013\u0000"+
+    "\u0000\u024d\u024e\u0001\u0000\u0000\u0000\u024e\u024f\u0006\f\u0007\u0000"+
+    "\u024f+\u0001\u0000\u0000\u0000\u0250\u0251\u0007\u0002\u0000\u0000\u0251"+
+    "\u0252\u0007\u0007\u0000\u0000\u0252\u0253\u0007\u0006\u0000\u0000\u0253"+
+    "\u0254\u0007\u0005\u0000\u0000\u0254\u0255\u0001\u0000\u0000\u0000\u0255"+
+    "\u0256\u0006\r\u0000\u0000\u0256-\u0001\u0000\u0000\u0000\u0257\u0258"+
+    "\u0007\u0002\u0000\u0000\u0258\u0259\u0007\u0005\u0000\u0000\u0259\u025a"+
+    "\u0007\f\u0000\u0000\u025a\u025b\u0007\u0005\u0000\u0000\u025b\u025c\u0007"+
+    "\u0002\u0000\u0000\u025c\u025d\u0001\u0000\u0000\u0000\u025d\u025e\u0006"+
+    "\u000e\u0000\u0000\u025e/\u0001\u0000\u0000\u0000\u025f\u0260\u0007\u0013"+
+    "\u0000\u0000\u0260\u0261\u0007\n\u0000\u0000\u0261\u0262\u0007\u0003\u0000"+
+    "\u0000\u0262\u0263\u0007\u0006\u0000\u0000\u0263\u0264\u0007\u0003\u0000"+
+    "\u0000\u0264\u0265\u0001\u0000\u0000\u0000\u0265\u0266\u0006\u000f\u0000"+
+    "\u0000\u02661\u0001\u0000\u0000\u0000\u0267\u0268\u0007\r\u0000\u0000"+
+    "\u0268\u0269\u0007\u0007\u0000\u0000\u0269\u026a\u0007\u0007\u0000\u0000"+
+    "\u026a\u026b\u0007\u0012\u0000\u0000\u026b\u026c\u0007\u0014\u0000\u0000"+
+    "\u026c\u026d\u0007\b\u0000\u0000\u026d\u026e\u0001\u0000\u0000\u0000\u026e"+
+    "\u026f\u0006\u0010\b\u0000\u026f3\u0001\u0000\u0000\u0000\u0270\u0271"+
+    "\u0004\u0011\u0000\u0000\u0271\u0272\u0007\u0004\u0000\u0000\u0272\u0273"+
+    "\u0007\n\u0000\u0000\u0273\u0274\u0007\f\u0000\u0000\u0274\u0275\u0007"+
+    "\t\u0000\u0000\u0275\u0276\u0007\u0011\u0000\u0000\u0276\u0277\u0007\u0003"+
+    "\u0000\u0000\u0277\u0278\u0005_\u0000\u0000\u0278\u0279\u0007\b\u0000"+
+    "\u0000\u0279\u027a\u0007\u0007\u0000\u0000\u027a\u027b\u0007\u0001\u0000"+
+    "\u0000\u027b\u027c\u0007\t\u0000\u0000\u027c\u027d\u0007\u0005\u0000\u0000"+
+    "\u027d\u027e\u0001\u0000\u0000\u0000\u027e\u027f\u0006\u0011\t\u0000\u027f"+
+    "5\u0001\u0000\u0000\u0000\u0280\u0281\u0004\u0012\u0001\u0000\u0281\u0282"+
+    "\u0007\u0001\u0000\u0000\u0282\u0283\u0007\t\u0000\u0000\u0283\u0284\u0007"+
+    "\r\u0000\u0000\u0284\u0285\u0007\u0001\u0000\u0000\u0285\u0286\u0007\t"+
+    "\u0000\u0000\u0286\u0287\u0007\u0003\u0000\u0000\u0287\u0288\u0007\u0002"+
+    "\u0000\u0000\u0288\u0289\u0007\u0005\u0000\u0000\u0289\u028a\u0007\f\u0000"+
+    "\u0000\u028a\u028b\u0007\u0005\u0000\u0000\u028b\u028c\u0007\u0002\u0000"+
+    "\u0000\u028c\u028d\u0001\u0000\u0000\u0000\u028d\u028e\u0006\u0012\u0000"+
+    "\u0000\u028e7\u0001\u0000\u0000\u0000\u028f\u0290\u0004\u0013\u0002\u0000"+
+    "\u0290\u0291\u0007\u0001\u0000\u0000\u0291\u0292\u0007\t\u0000\u0000\u0292"+
+    "\u0293\u0007\u0002\u0000\u0000\u0293\u0294\u0007\u0001\u0000\u0000\u0294"+
+    "\u0295\u0007\u0002\u0000\u0000\u0295\u0296\u0007\u0005\u0000\u0000\u0296"+
+    "\u0297\u0005_\u0000\u0000\u0297\u0298\u0005\u8001\uf414\u0000\u0000\u0298"+
+    "\u0299\u0001\u0000\u0000\u0000\u0299\u029a\u0006\u0013\u0001\u0000\u029a"+
+    "9\u0001\u0000\u0000\u0000\u029b\u029c\u0004\u0014\u0003\u0000\u029c\u029d"+
+    "\u0007\r\u0000\u0000\u029d\u029e\u0007\u0007\u0000\u0000\u029e\u029f\u0007"+
+    "\u0007\u0000\u0000\u029f\u02a0\u0007\u0012\u0000\u0000\u02a0\u02a1\u0007"+
+    "\u0014\u0000\u0000\u02a1\u02a2\u0007\b\u0000\u0000\u02a2\u02a3\u0005_"+
+    "\u0000\u0000\u02a3\u02a4\u0005\u8001\uf414\u0000\u0000\u02a4\u02a5\u0001"+
+    "\u0000\u0000\u0000\u02a5\u02a6\u0006\u0014\n\u0000\u02a6;\u0001\u0000"+
+    "\u0000\u0000\u02a7\u02a8\u0004\u0015\u0004\u0000\u02a8\u02a9\u0007\u0010"+
+    "\u0000\u0000\u02a9\u02aa\u0007\u0003\u0000\u0000\u02aa\u02ab\u0007\u0005"+
+    "\u0000\u0000\u02ab\u02ac\u0007\u0006\u0000\u0000\u02ac\u02ad\u0007\u0001"+
+    "\u0000\u0000\u02ad\u02ae\u0007\u0004\u0000\u0000\u02ae\u02af\u0007\u0002"+
+    "\u0000\u0000\u02af\u02b0\u0001\u0000\u0000\u0000\u02b0\u02b1\u0006\u0015"+
+    "\u000b\u0000\u02b1=\u0001\u0000\u0000\u0000\u02b2\u02b3\u0004\u0016\u0005"+
+    "\u0000\u02b3\u02b4\u0007\u000f\u0000\u0000\u02b4\u02b5\u0007\u0014\u0000"+
+    "\u0000\u02b5\u02b6\u0007\r\u0000\u0000\u02b6\u02b7\u0007\r\u0000\u0000"+
+    "\u02b7\u02b8\u0001\u0000\u0000\u0000\u02b8\u02b9\u0006\u0016\b\u0000\u02b9"+
+    "?\u0001\u0000\u0000\u0000\u02ba\u02bb\u0004\u0017\u0006\u0000\u02bb\u02bc"+
+    "\u0007\r\u0000\u0000\u02bc\u02bd\u0007\u0003\u0000\u0000\u02bd\u02be\u0007"+
+    "\u000f\u0000\u0000\u02be\u02bf\u0007\u0005\u0000\u0000\u02bf\u02c0\u0001"+
+    "\u0000\u0000\u0000\u02c0\u02c1\u0006\u0017\b\u0000\u02c1A\u0001\u0000"+
+    "\u0000\u0000\u02c2\u02c3\u0004\u0018\u0007\u0000\u02c3\u02c4\u0007\u0006"+
+    "\u0000\u0000\u02c4\u02c5\u0007\u0001\u0000\u0000\u02c5\u02c6\u0007\u0011"+
+    "\u0000\u0000\u02c6\u02c7\u0007\n\u0000\u0000\u02c7\u02c8\u0007\u0005\u0000"+
+    "\u0000\u02c8\u02c9\u0001\u0000\u0000\u0000\u02c9\u02ca\u0006\u0018\b\u0000"+
+    "\u02caC\u0001\u0000\u0000\u0000\u02cb\u02cd\b\u0015\u0000\u0000\u02cc"+
+    "\u02cb\u0001\u0000\u0000\u0000\u02cd\u02ce\u0001\u0000\u0000\u0000\u02ce"+
+    "\u02cc\u0001\u0000\u0000\u0000\u02ce\u02cf\u0001\u0000\u0000\u0000\u02cf"+
+    "\u02d0\u0001\u0000\u0000\u0000\u02d0\u02d1\u0006\u0019\u0000\u0000\u02d1"+
+    "E\u0001\u0000\u0000\u0000\u02d2\u02d3\u0005/\u0000\u0000\u02d3\u02d4\u0005"+
+    "/\u0000\u0000\u02d4\u02d8\u0001\u0000\u0000\u0000\u02d5\u02d7\b\u0016"+
+    "\u0000\u0000\u02d6\u02d5\u0001\u0000\u0000\u0000\u02d7\u02da\u0001\u0000"+
+    "\u0000\u0000\u02d8\u02d6\u0001\u0000\u0000\u0000\u02d8\u02d9\u0001\u0000"+
+    "\u0000\u0000\u02d9\u02dc\u0001\u0000\u0000\u0000\u02da\u02d8\u0001\u0000"+
+    "\u0000\u0000\u02db\u02dd\u0005\r\u0000\u0000\u02dc\u02db\u0001\u0000\u0000"+
+    "\u0000\u02dc\u02dd\u0001\u0000\u0000\u0000\u02dd\u02df\u0001\u0000\u0000"+
+    "\u0000\u02de\u02e0\u0005\n\u0000\u0000\u02df\u02de\u0001\u0000\u0000\u0000"+
+    "\u02df\u02e0\u0001\u0000\u0000\u0000\u02e0\u02e1\u0001\u0000\u0000\u0000"+
+    "\u02e1\u02e2\u0006\u001a\f\u0000\u02e2G\u0001\u0000\u0000\u0000\u02e3"+
+    "\u02e4\u0005/\u0000\u0000\u02e4\u02e5\u0005*\u0000\u0000\u02e5\u02ea\u0001"+
+    "\u0000\u0000\u0000\u02e6\u02e9\u0003H\u001b\u0000\u02e7\u02e9\t\u0000"+
+    "\u0000\u0000\u02e8\u02e6\u0001\u0000\u0000\u0000\u02e8\u02e7\u0001\u0000"+
+    "\u0000\u0000\u02e9\u02ec\u0001\u0000\u0000\u0000\u02ea\u02eb\u0001\u0000"+
+    "\u0000\u0000\u02ea\u02e8\u0001\u0000\u0000\u0000\u02eb\u02ed\u0001\u0000"+
+    "\u0000\u0000\u02ec\u02ea\u0001\u0000\u0000\u0000\u02ed\u02ee\u0005*\u0000"+
+    "\u0000\u02ee\u02ef\u0005/\u0000\u0000\u02ef\u02f0\u0001\u0000\u0000\u0000"+
+    "\u02f0\u02f1\u0006\u001b\f\u0000\u02f1I\u0001\u0000\u0000\u0000\u02f2"+
+    "\u02f4\u0007\u0017\u0000\u0000\u02f3\u02f2\u0001\u0000\u0000\u0000\u02f4"+
+    "\u02f5\u0001\u0000\u0000\u0000\u02f5\u02f3\u0001\u0000\u0000\u0000\u02f5"+
+    "\u02f6\u0001\u0000\u0000\u0000\u02f6\u02f7\u0001\u0000\u0000\u0000\u02f7"+
+    "\u02f8\u0006\u001c\f\u0000\u02f8K\u0001\u0000\u0000\u0000\u02f9\u02fa"+
+    "\u0005|\u0000\u0000\u02fa\u02fb\u0001\u0000\u0000\u0000\u02fb\u02fc\u0006"+
+    "\u001d\r\u0000\u02fcM\u0001\u0000\u0000\u0000\u02fd\u02fe\u0007\u0018"+
+    "\u0000\u0000\u02feO\u0001\u0000\u0000\u0000\u02ff\u0300\u0007\u0019\u0000"+
+    "\u0000\u0300Q\u0001\u0000\u0000\u0000\u0301\u0302\u0005\\\u0000\u0000"+
+    "\u0302\u0303\u0007\u001a\u0000\u0000\u0303S\u0001\u0000\u0000\u0000\u0304"+
+    "\u0305\b\u001b\u0000\u0000\u0305U\u0001\u0000\u0000\u0000\u0306\u0308"+
+    "\u0007\u0003\u0000\u0000\u0307\u0309\u0007\u001c\u0000\u0000\u0308\u0307"+
+    "\u0001\u0000\u0000\u0000\u0308\u0309\u0001\u0000\u0000\u0000\u0309\u030b"+
+    "\u0001\u0000\u0000\u0000\u030a\u030c\u0003N\u001e\u0000\u030b\u030a\u0001"+
+    "\u0000\u0000\u0000\u030c\u030d\u0001\u0000\u0000\u0000\u030d\u030b\u0001"+
+    "\u0000\u0000\u0000\u030d\u030e\u0001\u0000\u0000\u0000\u030eW\u0001\u0000"+
+    "\u0000\u0000\u030f\u0310\u0005@\u0000\u0000\u0310Y\u0001\u0000\u0000\u0000"+
+    "\u0311\u0312\u0005`\u0000\u0000\u0312[\u0001\u0000\u0000\u0000\u0313\u0317"+
+    "\b\u001d\u0000\u0000\u0314\u0315\u0005`\u0000\u0000\u0315\u0317\u0005"+
+    "`\u0000\u0000\u0316\u0313\u0001\u0000\u0000\u0000\u0316\u0314\u0001\u0000"+
+    "\u0000\u0000\u0317]\u0001\u0000\u0000\u0000\u0318\u0319\u0005_\u0000\u0000"+
+    "\u0319_\u0001\u0000\u0000\u0000\u031a\u031e\u0003P\u001f\u0000\u031b\u031e"+
+    "\u0003N\u001e\u0000\u031c\u031e\u0003^&\u0000\u031d\u031a\u0001\u0000"+
+    "\u0000\u0000\u031d\u031b\u0001\u0000\u0000\u0000\u031d\u031c\u0001\u0000"+
+    "\u0000\u0000\u031ea\u0001\u0000\u0000\u0000\u031f\u0324\u0005\"\u0000"+
+    "\u0000\u0320\u0323\u0003R \u0000\u0321\u0323\u0003T!\u0000\u0322\u0320"+
+    "\u0001\u0000\u0000\u0000\u0322\u0321\u0001\u0000\u0000\u0000\u0323\u0326"+
+    "\u0001\u0000\u0000\u0000\u0324\u0322\u0001\u0000\u0000\u0000\u0324\u0325"+
+    "\u0001\u0000\u0000\u0000\u0325\u0327\u0001\u0000\u0000\u0000\u0326\u0324"+
+    "\u0001\u0000\u0000\u0000\u0327\u033d\u0005\"\u0000\u0000\u0328\u0329\u0005"+
+    "\"\u0000\u0000\u0329\u032a\u0005\"\u0000\u0000\u032a\u032b\u0005\"\u0000"+
+    "\u0000\u032b\u032f\u0001\u0000\u0000\u0000\u032c\u032e\b\u0016\u0000\u0000"+
+    "\u032d\u032c\u0001\u0000\u0000\u0000\u032e\u0331\u0001\u0000\u0000\u0000"+
+    "\u032f\u0330\u0001\u0000\u0000\u0000\u032f\u032d\u0001\u0000\u0000\u0000"+
+    "\u0330\u0332\u0001\u0000\u0000\u0000\u0331\u032f\u0001\u0000\u0000\u0000"+
+    "\u0332\u0333\u0005\"\u0000\u0000\u0333\u0334\u0005\"\u0000\u0000\u0334"+
+    "\u0335\u0005\"\u0000\u0000\u0335\u0337\u0001\u0000\u0000\u0000\u0336\u0338"+
+    "\u0005\"\u0000\u0000\u0337\u0336\u0001\u0000\u0000\u0000\u0337\u0338\u0001"+
+    "\u0000\u0000\u0000\u0338\u033a\u0001\u0000\u0000\u0000\u0339\u033b\u0005"+
+    "\"\u0000\u0000\u033a\u0339\u0001\u0000\u0000\u0000\u033a\u033b\u0001\u0000"+
+    "\u0000\u0000\u033b\u033d\u0001\u0000\u0000\u0000\u033c\u031f\u0001\u0000"+
+    "\u0000\u0000\u033c\u0328\u0001\u0000\u0000\u0000\u033dc\u0001\u0000\u0000"+
+    "\u0000\u033e\u0340\u0003N\u001e\u0000\u033f\u033e\u0001\u0000\u0000\u0000"+
+    "\u0340\u0341\u0001\u0000\u0000\u0000\u0341\u033f\u0001\u0000\u0000\u0000"+
+    "\u0341\u0342\u0001\u0000\u0000\u0000\u0342e\u0001\u0000\u0000\u0000\u0343"+
+    "\u0345\u0003N\u001e\u0000\u0344\u0343\u0001\u0000\u0000\u0000\u0345\u0346"+
+    "\u0001\u0000\u0000\u0000\u0346\u0344\u0001\u0000\u0000\u0000\u0346\u0347"+
+    "\u0001\u0000\u0000\u0000\u0347\u0348\u0001\u0000\u0000\u0000\u0348\u034c"+
+    "\u0003x3\u0000\u0349\u034b\u0003N\u001e\u0000\u034a\u0349\u0001\u0000"+
+    "\u0000\u0000\u034b\u034e\u0001\u0000\u0000\u0000\u034c\u034a\u0001\u0000"+
+    "\u0000\u0000\u034c\u034d\u0001\u0000\u0000\u0000\u034d\u036e\u0001\u0000"+
+    "\u0000\u0000\u034e\u034c\u0001\u0000\u0000\u0000\u034f\u0351\u0003x3\u0000"+
+    "\u0350\u0352\u0003N\u001e\u0000\u0351\u0350\u0001\u0000\u0000\u0000\u0352"+
+    "\u0353\u0001\u0000\u0000\u0000\u0353\u0351\u0001\u0000\u0000\u0000\u0353"+
+    "\u0354\u0001\u0000\u0000\u0000\u0354\u036e\u0001\u0000\u0000\u0000\u0355"+
+    "\u0357\u0003N\u001e\u0000\u0356\u0355\u0001\u0000\u0000\u0000\u0357\u0358"+
+    "\u0001\u0000\u0000\u0000\u0358\u0356\u0001\u0000\u0000\u0000\u0358\u0359"+
+    "\u0001\u0000\u0000\u0000\u0359\u0361\u0001\u0000\u0000\u0000\u035a\u035e"+
+    "\u0003x3\u0000\u035b\u035d\u0003N\u001e\u0000\u035c\u035b\u0001\u0000"+
+    "\u0000\u0000\u035d\u0360\u0001\u0000\u0000\u0000\u035e\u035c\u0001\u0000"+
+    "\u0000\u0000\u035e\u035f\u0001\u0000\u0000\u0000\u035f\u0362\u0001\u0000"+
+    "\u0000\u0000\u0360\u035e\u0001\u0000\u0000\u0000\u0361\u035a\u0001\u0000"+
+    "\u0000\u0000\u0361\u0362\u0001\u0000\u0000\u0000\u0362\u0363\u0001\u0000"+
+    "\u0000\u0000\u0363\u0364\u0003V\"\u0000\u0364\u036e\u0001\u0000\u0000"+
+    "\u0000\u0365\u0367\u0003x3\u0000\u0366\u0368\u0003N\u001e\u0000\u0367"+
+    "\u0366\u0001\u0000\u0000\u0000\u0368\u0369\u0001\u0000\u0000\u0000\u0369"+
+    "\u0367\u0001\u0000\u0000\u0000\u0369\u036a\u0001\u0000\u0000\u0000\u036a"+
+    "\u036b\u0001\u0000\u0000\u0000\u036b\u036c\u0003V\"\u0000\u036c\u036e"+
+    "\u0001\u0000\u0000\u0000\u036d\u0344\u0001\u0000\u0000\u0000\u036d\u034f"+
+    "\u0001\u0000\u0000\u0000\u036d\u0356\u0001\u0000\u0000\u0000\u036d\u0365"+
+    "\u0001\u0000\u0000\u0000\u036eg\u0001\u0000\u0000\u0000\u036f\u0370\u0007"+
+    "\u001e\u0000\u0000\u0370\u0371\u0007\u001f\u0000\u0000\u0371i\u0001\u0000"+
+    "\u0000\u0000\u0372\u0373\u0007\f\u0000\u0000\u0373\u0374\u0007\t\u0000"+
+    "\u0000\u0374\u0375\u0007\u0000\u0000\u0000\u0375k\u0001\u0000\u0000\u0000"+
+    "\u0376\u0377\u0007\f\u0000\u0000\u0377\u0378\u0007\u0002\u0000\u0000\u0378"+
+    "\u0379\u0007\u0004\u0000\u0000\u0379m\u0001\u0000\u0000\u0000\u037a\u037b"+
+    "\u0005=\u0000\u0000\u037bo\u0001\u0000\u0000\u0000\u037c\u037d\u0005:"+
+    "\u0000\u0000\u037d\u037e\u0005:\u0000\u0000\u037eq\u0001\u0000\u0000\u0000"+
+    "\u037f\u0380\u0005:\u0000\u0000\u0380s\u0001\u0000\u0000\u0000\u0381\u0382"+
+    "\u0005,\u0000\u0000\u0382u\u0001\u0000\u0000\u0000\u0383\u0384\u0007\u0000"+
+    "\u0000\u0000\u0384\u0385\u0007\u0003\u0000\u0000\u0385\u0386\u0007\u0002"+
+    "\u0000\u0000\u0386\u0387\u0007\u0004\u0000\u0000\u0387w\u0001\u0000\u0000"+
+    "\u0000\u0388\u0389\u0005.\u0000\u0000\u0389y\u0001\u0000\u0000\u0000\u038a"+
+    "\u038b\u0007\u000f\u0000\u0000\u038b\u038c\u0007\f\u0000\u0000\u038c\u038d"+
+    "\u0007\r\u0000\u0000\u038d\u038e\u0007\u0002\u0000\u0000\u038e\u038f\u0007"+
+    "\u0003\u0000\u0000\u038f{\u0001\u0000\u0000\u0000\u0390\u0391\u0007\u000f"+
+    "\u0000\u0000\u0391\u0392\u0007\u0001\u0000\u0000\u0392\u0393\u0007\u0006"+
+    "\u0000\u0000\u0393\u0394\u0007\u0002\u0000\u0000\u0394\u0395\u0007\u0005"+
+    "\u0000\u0000\u0395}\u0001\u0000\u0000\u0000\u0396\u0397\u0007\u0001\u0000"+
+    "\u0000\u0397\u0398\u0007\t\u0000\u0000\u0398\u007f\u0001\u0000\u0000\u0000"+
+    "\u0399\u039a\u0007\u0001\u0000\u0000\u039a\u039b\u0007\u0002\u0000\u0000"+
+    "\u039b\u0081\u0001\u0000\u0000\u0000\u039c\u039d\u0007\r\u0000\u0000\u039d"+
+    "\u039e\u0007\f\u0000\u0000\u039e\u039f\u0007\u0002\u0000\u0000\u039f\u03a0"+
+    "\u0007\u0005\u0000\u0000\u03a0\u0083\u0001\u0000\u0000\u0000\u03a1\u03a2"+
+    "\u0007\r\u0000\u0000\u03a2\u03a3\u0007\u0001\u0000\u0000\u03a3\u03a4\u0007"+
+    "\u0012\u0000\u0000\u03a4\u03a5\u0007\u0003\u0000\u0000\u03a5\u0085\u0001"+
+    "\u0000\u0000\u0000\u03a6\u03a7\u0005(\u0000\u0000\u03a7\u0087\u0001\u0000"+
+    "\u0000\u0000\u03a8\u03a9\u0007\t\u0000\u0000\u03a9\u03aa\u0007\u0007\u0000"+
+    "\u0000\u03aa\u03ab\u0007\u0005\u0000\u0000\u03ab\u0089\u0001\u0000\u0000"+
+    "\u0000\u03ac\u03ad\u0007\t\u0000\u0000\u03ad\u03ae\u0007\u0014\u0000\u0000"+
+    "\u03ae\u03af\u0007\r\u0000\u0000\u03af\u03b0\u0007\r\u0000\u0000\u03b0"+
+    "\u008b\u0001\u0000\u0000\u0000\u03b1\u03b2\u0007\t\u0000\u0000\u03b2\u03b3"+
+    "\u0007\u0014\u0000\u0000\u03b3\u03b4\u0007\r\u0000\u0000\u03b4\u03b5\u0007"+
+    "\r\u0000\u0000\u03b5\u03b6\u0007\u0002\u0000\u0000\u03b6\u008d\u0001\u0000"+
+    "\u0000\u0000\u03b7\u03b8\u0007\u0007\u0000\u0000\u03b8\u03b9\u0007\u0006"+
+    "\u0000\u0000\u03b9\u008f\u0001\u0000\u0000\u0000\u03ba\u03bb\u0005?\u0000"+
+    "\u0000\u03bb\u0091\u0001\u0000\u0000\u0000\u03bc\u03bd\u0007\u0006\u0000"+
+    "\u0000\u03bd\u03be\u0007\r\u0000\u0000\u03be\u03bf\u0007\u0001\u0000\u0000"+
+    "\u03bf\u03c0\u0007\u0012\u0000\u0000\u03c0\u03c1\u0007\u0003\u0000\u0000"+
+    "\u03c1\u0093\u0001\u0000\u0000\u0000\u03c2\u03c3\u0005)\u0000\u0000\u03c3"+
+    "\u0095\u0001\u0000\u0000\u0000\u03c4\u03c5\u0007\u0005\u0000\u0000\u03c5"+
+    "\u03c6\u0007\u0006\u0000\u0000\u03c6\u03c7\u0007\u0014\u0000\u0000\u03c7"+
+    "\u03c8\u0007\u0003\u0000\u0000\u03c8\u0097\u0001\u0000\u0000\u0000\u03c9"+
+    "\u03ca\u0005=\u0000\u0000\u03ca\u03cb\u0005=\u0000\u0000\u03cb\u0099\u0001"+
+    "\u0000\u0000\u0000\u03cc\u03cd\u0005=\u0000\u0000\u03cd\u03ce\u0005~\u0000"+
+    "\u0000\u03ce\u009b\u0001\u0000\u0000\u0000\u03cf\u03d0\u0005!\u0000\u0000"+
+    "\u03d0\u03d1\u0005=\u0000\u0000\u03d1\u009d\u0001\u0000\u0000\u0000\u03d2"+
+    "\u03d3\u0005<\u0000\u0000\u03d3\u009f\u0001\u0000\u0000\u0000\u03d4\u03d5"+
+    "\u0005<\u0000\u0000\u03d5\u03d6\u0005=\u0000\u0000\u03d6\u00a1\u0001\u0000"+
+    "\u0000\u0000\u03d7\u03d8\u0005>\u0000\u0000\u03d8\u00a3\u0001\u0000\u0000"+
+    "\u0000\u03d9\u03da\u0005>\u0000\u0000\u03da\u03db\u0005=\u0000\u0000\u03db"+
+    "\u00a5\u0001\u0000\u0000\u0000\u03dc\u03dd\u0005+\u0000\u0000\u03dd\u00a7"+
+    "\u0001\u0000\u0000\u0000\u03de\u03df\u0005-\u0000\u0000\u03df\u00a9\u0001"+
+    "\u0000\u0000\u0000\u03e0\u03e1\u0005*\u0000\u0000\u03e1\u00ab\u0001\u0000"+
+    "\u0000\u0000\u03e2\u03e3\u0005/\u0000\u0000\u03e3\u00ad\u0001\u0000\u0000"+
+    "\u0000\u03e4\u03e5\u0005%\u0000\u0000\u03e5\u00af\u0001\u0000\u0000\u0000"+
+    "\u03e6\u03e7\u0005{\u0000\u0000\u03e7\u00b1\u0001\u0000\u0000\u0000\u03e8"+
+    "\u03e9\u0005}\u0000\u0000\u03e9\u00b3\u0001\u0000\u0000\u0000\u03ea\u03eb"+
+    "\u00030\u000f\u0000\u03eb\u03ec\u0001\u0000\u0000\u0000\u03ec\u03ed\u0006"+
+    "Q\u000e\u0000\u03ed\u00b5\u0001\u0000\u0000\u0000\u03ee\u03f1\u0003\u0090"+
+    "?\u0000\u03ef\u03f2\u0003P\u001f\u0000\u03f0\u03f2\u0003^&\u0000\u03f1"+
+    "\u03ef\u0001\u0000\u0000\u0000\u03f1\u03f0\u0001\u0000\u0000\u0000\u03f2"+
+    "\u03f6\u0001\u0000\u0000\u0000\u03f3\u03f5\u0003`\'\u0000\u03f4\u03f3"+
+    "\u0001\u0000\u0000\u0000\u03f5\u03f8\u0001\u0000\u0000\u0000\u03f6\u03f4"+
+    "\u0001\u0000\u0000\u0000\u03f6\u03f7\u0001\u0000\u0000\u0000\u03f7\u0400"+
+    "\u0001\u0000\u0000\u0000\u03f8\u03f6\u0001\u0000\u0000\u0000\u03f9\u03fb"+
+    "\u0003\u0090?\u0000\u03fa\u03fc\u0003N\u001e\u0000\u03fb\u03fa\u0001\u0000"+
+    "\u0000\u0000\u03fc\u03fd\u0001\u0000\u0000\u0000\u03fd\u03fb\u0001\u0000"+
+    "\u0000\u0000\u03fd\u03fe\u0001\u0000\u0000\u0000\u03fe\u0400\u0001\u0000"+
+    "\u0000\u0000\u03ff\u03ee\u0001\u0000\u0000\u0000\u03ff\u03f9\u0001\u0000"+
+    "\u0000\u0000\u0400\u00b7\u0001\u0000\u0000\u0000\u0401\u0402\u0005[\u0000"+
+    "\u0000\u0402\u0403\u0001\u0000\u0000\u0000\u0403\u0404\u0006S\u0000\u0000"+
+    "\u0404\u0405\u0006S\u0000\u0000\u0405\u00b9\u0001\u0000\u0000\u0000\u0406"+
+    "\u0407\u0005]\u0000\u0000\u0407\u0408\u0001\u0000\u0000\u0000\u0408\u0409"+
+    "\u0006T\r\u0000\u0409\u040a\u0006T\r\u0000\u040a\u00bb\u0001\u0000\u0000"+
+    "\u0000\u040b\u040f\u0003P\u001f\u0000\u040c\u040e\u0003`\'\u0000\u040d"+
+    "\u040c\u0001\u0000\u0000\u0000\u040e\u0411\u0001\u0000\u0000\u0000\u040f"+
+    "\u040d\u0001\u0000\u0000\u0000\u040f\u0410\u0001\u0000\u0000\u0000\u0410"+
+    "\u041c\u0001\u0000\u0000\u0000\u0411\u040f\u0001\u0000\u0000\u0000\u0412"+
+    "\u0415\u0003^&\u0000\u0413\u0415\u0003X#\u0000\u0414\u0412\u0001\u0000"+
+    "\u0000\u0000\u0414\u0413\u0001\u0000\u0000\u0000\u0415\u0417\u0001\u0000"+
+    "\u0000\u0000\u0416\u0418\u0003`\'\u0000\u0417\u0416\u0001\u0000\u0000"+
+    "\u0000\u0418\u0419\u0001\u0000\u0000\u0000\u0419\u0417\u0001\u0000\u0000"+
+    "\u0000\u0419\u041a\u0001\u0000\u0000\u0000\u041a\u041c\u0001\u0000\u0000"+
+    "\u0000\u041b\u040b\u0001\u0000\u0000\u0000\u041b\u0414\u0001\u0000\u0000"+
+    "\u0000\u041c\u00bd\u0001\u0000\u0000\u0000\u041d\u041f\u0003Z$\u0000\u041e"+
+    "\u0420\u0003\\%\u0000\u041f\u041e\u0001\u0000\u0000\u0000\u0420\u0421"+
+    "\u0001\u0000\u0000\u0000\u0421\u041f\u0001\u0000\u0000\u0000\u0421\u0422"+
+    "\u0001\u0000\u0000\u0000\u0422\u0423\u0001\u0000\u0000\u0000\u0423\u0424"+
+    "\u0003Z$\u0000\u0424\u00bf\u0001\u0000\u0000\u0000\u0425\u0426\u0003\u00be"+
+    "V\u0000\u0426\u00c1\u0001\u0000\u0000\u0000\u0427\u0428\u0003F\u001a\u0000"+
+    "\u0428\u0429\u0001\u0000\u0000\u0000\u0429\u042a\u0006X\f\u0000\u042a"+
+    "\u00c3\u0001\u0000\u0000\u0000\u042b\u042c\u0003H\u001b\u0000\u042c\u042d"+
+    "\u0001\u0000\u0000\u0000\u042d\u042e\u0006Y\f\u0000\u042e\u00c5\u0001"+
+    "\u0000\u0000\u0000\u042f\u0430\u0003J\u001c\u0000\u0430\u0431\u0001\u0000"+
+    "\u0000\u0000\u0431\u0432\u0006Z\f\u0000\u0432\u00c7\u0001\u0000\u0000"+
+    "\u0000\u0433\u0434\u0003\u00b8S\u0000\u0434\u0435\u0001\u0000\u0000\u0000"+
+    "\u0435\u0436\u0006[\u000f\u0000\u0436\u0437\u0006[\u0010\u0000\u0437\u00c9"+
+    "\u0001\u0000\u0000\u0000\u0438\u0439\u0003L\u001d\u0000\u0439\u043a\u0001"+
+    "\u0000\u0000\u0000\u043a\u043b\u0006\\\u0011\u0000\u043b\u043c\u0006\\"+
+    "\r\u0000\u043c\u00cb\u0001\u0000\u0000\u0000\u043d\u043e\u0003J\u001c"+
+    "\u0000\u043e\u043f\u0001\u0000\u0000\u0000\u043f\u0440\u0006]\f\u0000"+
+    "\u0440\u00cd\u0001\u0000\u0000\u0000\u0441\u0442\u0003F\u001a\u0000\u0442"+
+    "\u0443\u0001\u0000\u0000\u0000\u0443\u0444\u0006^\f\u0000\u0444\u00cf"+
+    "\u0001\u0000\u0000\u0000\u0445\u0446\u0003H\u001b\u0000\u0446\u0447\u0001"+
+    "\u0000\u0000\u0000\u0447\u0448\u0006_\f\u0000\u0448\u00d1\u0001\u0000"+
+    "\u0000\u0000\u0449\u044a\u0003L\u001d\u0000\u044a\u044b\u0001\u0000\u0000"+
+    "\u0000\u044b\u044c\u0006`\u0011\u0000\u044c\u044d\u0006`\r\u0000\u044d"+
+    "\u00d3\u0001\u0000\u0000\u0000\u044e\u044f\u0003\u00b8S\u0000\u044f\u0450"+
+    "\u0001\u0000\u0000\u0000\u0450\u0451\u0006a\u000f\u0000\u0451\u00d5\u0001"+
+    "\u0000\u0000\u0000\u0452\u0453\u0003\u00baT\u0000\u0453\u0454\u0001\u0000"+
+    "\u0000\u0000\u0454\u0455\u0006b\u0012\u0000\u0455\u00d7\u0001\u0000\u0000"+
+    "\u0000\u0456\u0457\u0003r0\u0000\u0457\u0458\u0001\u0000\u0000\u0000\u0458"+
+    "\u0459\u0006c\u0013\u0000\u0459\u00d9\u0001\u0000\u0000\u0000\u045a\u045b"+
+    "\u0003t1\u0000\u045b\u045c\u0001\u0000\u0000\u0000\u045c\u045d\u0006d"+
+    "\u0014\u0000\u045d\u00db\u0001\u0000\u0000\u0000\u045e\u045f\u0003n.\u0000"+
+    "\u045f\u0460\u0001\u0000\u0000\u0000\u0460\u0461\u0006e\u0015\u0000\u0461"+
+    "\u00dd\u0001\u0000\u0000\u0000\u0462\u0463\u0007\u0010\u0000\u0000\u0463"+
+    "\u0464\u0007\u0003\u0000\u0000\u0464\u0465\u0007\u0005\u0000\u0000\u0465"+
+    "\u0466\u0007\f\u0000\u0000\u0466\u0467\u0007\u0000\u0000\u0000\u0467\u0468"+
+    "\u0007\f\u0000\u0000\u0468\u0469\u0007\u0005\u0000\u0000\u0469\u046a\u0007"+
+    "\f\u0000\u0000\u046a\u00df\u0001\u0000\u0000\u0000\u046b\u046f\b \u0000"+
+    "\u0000\u046c\u046d\u0005/\u0000\u0000\u046d\u046f\b!\u0000\u0000\u046e"+
+    "\u046b\u0001\u0000\u0000\u0000\u046e\u046c\u0001\u0000\u0000\u0000\u046f"+
+    "\u00e1\u0001\u0000\u0000\u0000\u0470\u0472\u0003\u00e0g\u0000\u0471\u0470"+
+    "\u0001\u0000\u0000\u0000\u0472\u0473\u0001\u0000\u0000\u0000\u0473\u0471"+
+    "\u0001\u0000\u0000\u0000\u0473\u0474\u0001\u0000\u0000\u0000\u0474\u00e3"+
+    "\u0001\u0000\u0000\u0000\u0475\u0476\u0003\u00e2h\u0000\u0476\u0477\u0001"+
+    "\u0000\u0000\u0000\u0477\u0478\u0006i\u0016\u0000\u0478\u00e5\u0001\u0000"+
+    "\u0000\u0000\u0479\u047a\u0003b(\u0000\u047a\u047b\u0001\u0000\u0000\u0000"+
+    "\u047b\u047c\u0006j\u0017\u0000\u047c\u00e7\u0001\u0000\u0000\u0000\u047d"+
+    "\u047e\u0003F\u001a\u0000\u047e\u047f\u0001\u0000\u0000\u0000\u047f\u0480"+
+    "\u0006k\f\u0000\u0480\u00e9\u0001\u0000\u0000\u0000\u0481\u0482\u0003"+
+    "H\u001b\u0000\u0482\u0483\u0001\u0000\u0000\u0000\u0483\u0484\u0006l\f"+
+    "\u0000\u0484\u00eb\u0001\u0000\u0000\u0000\u0485\u0486\u0003J\u001c\u0000"+
+    "\u0486\u0487\u0001\u0000\u0000\u0000\u0487\u0488\u0006m\f\u0000\u0488"+
+    "\u00ed\u0001\u0000\u0000\u0000\u0489\u048a\u0003L\u001d\u0000\u048a\u048b"+
+    "\u0001\u0000\u0000\u0000\u048b\u048c\u0006n\u0011\u0000\u048c\u048d\u0006"+
+    "n\r\u0000\u048d\u00ef\u0001\u0000\u0000\u0000\u048e\u048f\u0003x3\u0000"+
+    "\u048f\u0490\u0001\u0000\u0000\u0000\u0490\u0491\u0006o\u0018\u0000\u0491"+
+    "\u00f1\u0001\u0000\u0000\u0000\u0492\u0493\u0003t1\u0000\u0493\u0494\u0001"+
+    "\u0000\u0000\u0000\u0494\u0495\u0006p\u0014\u0000\u0495\u00f3\u0001\u0000"+
+    "\u0000\u0000\u0496\u0497\u0003\u0090?\u0000\u0497\u0498\u0001\u0000\u0000"+
+    "\u0000\u0498\u0499\u0006q\u0019\u0000\u0499\u00f5\u0001\u0000\u0000\u0000"+
+    "\u049a\u049b\u0003\u00b6R\u0000\u049b\u049c\u0001\u0000\u0000\u0000\u049c"+
+    "\u049d\u0006r\u001a\u0000\u049d\u00f7\u0001\u0000\u0000\u0000\u049e\u04a3"+
+    "\u0003P\u001f\u0000\u049f\u04a3\u0003N\u001e\u0000\u04a0\u04a3\u0003^"+
+    "&\u0000\u04a1\u04a3\u0003\u00aaL\u0000\u04a2\u049e\u0001\u0000\u0000\u0000"+
+    "\u04a2\u049f\u0001\u0000\u0000\u0000\u04a2\u04a0\u0001\u0000\u0000\u0000"+
+    "\u04a2\u04a1\u0001\u0000\u0000\u0000\u04a3\u00f9\u0001\u0000\u0000\u0000"+
+    "\u04a4\u04a7\u0003P\u001f\u0000\u04a5\u04a7\u0003\u00aaL\u0000\u04a6\u04a4"+
+    "\u0001\u0000\u0000\u0000\u04a6\u04a5\u0001\u0000\u0000\u0000\u04a7\u04ab"+
+    "\u0001\u0000\u0000\u0000\u04a8\u04aa\u0003\u00f8s\u0000\u04a9\u04a8\u0001"+
+    "\u0000\u0000\u0000\u04aa\u04ad\u0001\u0000\u0000\u0000\u04ab\u04a9\u0001"+
+    "\u0000\u0000\u0000\u04ab\u04ac\u0001\u0000\u0000\u0000\u04ac\u04b8\u0001"+
+    "\u0000\u0000\u0000\u04ad\u04ab\u0001\u0000\u0000\u0000\u04ae\u04b1\u0003"+
+    "^&\u0000\u04af\u04b1\u0003X#\u0000\u04b0\u04ae\u0001\u0000\u0000\u0000"+
+    "\u04b0\u04af\u0001\u0000\u0000\u0000\u04b1\u04b3\u0001\u0000\u0000\u0000"+
+    "\u04b2\u04b4\u0003\u00f8s\u0000\u04b3\u04b2\u0001\u0000\u0000\u0000\u04b4"+
+    "\u04b5\u0001\u0000\u0000\u0000\u04b5\u04b3\u0001\u0000\u0000\u0000\u04b5"+
+    "\u04b6\u0001\u0000\u0000\u0000\u04b6\u04b8\u0001\u0000\u0000\u0000\u04b7"+
+    "\u04a6\u0001\u0000\u0000\u0000\u04b7\u04b0\u0001\u0000\u0000\u0000\u04b8"+
+    "\u00fb\u0001\u0000\u0000\u0000\u04b9\u04bc\u0003\u00fat\u0000\u04ba\u04bc"+
+    "\u0003\u00beV\u0000\u04bb\u04b9\u0001\u0000\u0000\u0000\u04bb\u04ba\u0001"+
+    "\u0000\u0000\u0000\u04bc\u04bd\u0001\u0000\u0000\u0000\u04bd\u04bb\u0001"+
+    "\u0000\u0000\u0000\u04bd\u04be\u0001\u0000\u0000\u0000\u04be\u00fd\u0001"+
+    "\u0000\u0000\u0000\u04bf\u04c0\u0003F\u001a\u0000\u04c0\u04c1\u0001\u0000"+
+    "\u0000\u0000\u04c1\u04c2\u0006v\f\u0000\u04c2\u00ff\u0001\u0000\u0000"+
+    "\u0000\u04c3\u04c4\u0003H\u001b\u0000\u04c4\u04c5\u0001\u0000\u0000\u0000"+
+    "\u04c5\u04c6\u0006w\f\u0000\u04c6\u0101\u0001\u0000\u0000\u0000\u04c7"+
+    "\u04c8\u0003J\u001c\u0000\u04c8\u04c9\u0001\u0000\u0000\u0000\u04c9\u04ca"+
+    "\u0006x\f\u0000\u04ca\u0103\u0001\u0000\u0000\u0000\u04cb\u04cc\u0003"+
+    "L\u001d\u0000\u04cc\u04cd\u0001\u0000\u0000\u0000\u04cd\u04ce\u0006y\u0011"+
+    "\u0000\u04ce\u04cf\u0006y\r\u0000\u04cf\u0105\u0001\u0000\u0000\u0000"+
+    "\u04d0\u04d1\u0003n.\u0000\u04d1\u04d2\u0001\u0000\u0000\u0000\u04d2\u04d3"+
+    "\u0006z\u0015\u0000\u04d3\u0107\u0001\u0000\u0000\u0000\u04d4\u04d5\u0003"+
+    "t1\u0000\u04d5\u04d6\u0001\u0000\u0000\u0000\u04d6\u04d7\u0006{\u0014"+
+    "\u0000\u04d7\u0109\u0001\u0000\u0000\u0000\u04d8\u04d9\u0003x3\u0000\u04d9"+
+    "\u04da\u0001\u0000\u0000\u0000\u04da\u04db\u0006|\u0018\u0000\u04db\u010b"+
+    "\u0001\u0000\u0000\u0000\u04dc\u04dd\u0003\u0090?\u0000\u04dd\u04de\u0001"+
+    "\u0000\u0000\u0000\u04de\u04df\u0006}\u0019\u0000\u04df\u010d\u0001\u0000"+
+    "\u0000\u0000\u04e0\u04e1\u0003\u00b6R\u0000\u04e1\u04e2\u0001\u0000\u0000"+
+    "\u0000\u04e2\u04e3\u0006~\u001a\u0000\u04e3\u010f\u0001\u0000\u0000\u0000"+
+    "\u04e4\u04e5\u0007\f\u0000\u0000\u04e5\u04e6\u0007\u0002\u0000\u0000\u04e6"+
+    "\u0111\u0001\u0000\u0000\u0000\u04e7\u04e8\u0003\u00fcu\u0000\u04e8\u04e9"+
+    "\u0001\u0000\u0000\u0000\u04e9\u04ea\u0006\u0080\u001b\u0000\u04ea\u0113"+
+    "\u0001\u0000\u0000\u0000\u04eb\u04ec\u0003F\u001a\u0000\u04ec\u04ed\u0001"+
+    "\u0000\u0000\u0000\u04ed\u04ee\u0006\u0081\f\u0000\u04ee\u0115\u0001\u0000"+
+    "\u0000\u0000\u04ef\u04f0\u0003H\u001b\u0000\u04f0\u04f1\u0001\u0000\u0000"+
+    "\u0000\u04f1\u04f2\u0006\u0082\f\u0000\u04f2\u0117\u0001\u0000\u0000\u0000"+
+    "\u04f3\u04f4\u0003J\u001c\u0000\u04f4\u04f5\u0001\u0000\u0000\u0000\u04f5"+
+    "\u04f6\u0006\u0083\f\u0000\u04f6\u0119\u0001\u0000\u0000\u0000\u04f7\u04f8"+
+    "\u0003L\u001d\u0000\u04f8\u04f9\u0001\u0000\u0000\u0000\u04f9\u04fa\u0006"+
+    "\u0084\u0011\u0000\u04fa\u04fb\u0006\u0084\r\u0000\u04fb\u011b\u0001\u0000"+
+    "\u0000\u0000\u04fc\u04fd\u0003\u00b8S\u0000\u04fd\u04fe\u0001\u0000\u0000"+
+    "\u0000\u04fe\u04ff\u0006\u0085\u000f\u0000\u04ff\u0500\u0006\u0085\u001c"+
+    "\u0000\u0500\u011d\u0001\u0000\u0000\u0000\u0501\u0502\u0007\u0007\u0000"+
+    "\u0000\u0502\u0503\u0007\t\u0000\u0000\u0503\u0504\u0001\u0000\u0000\u0000"+
+    "\u0504\u0505\u0006\u0086\u001d\u0000\u0505\u011f\u0001\u0000\u0000\u0000"+
+    "\u0506\u0507\u0007\u0013\u0000\u0000\u0507\u0508\u0007\u0001\u0000\u0000"+
+    "\u0508\u0509\u0007\u0005\u0000\u0000\u0509\u050a\u0007\n\u0000\u0000\u050a"+
+    "\u050b\u0001\u0000\u0000\u0000\u050b\u050c\u0006\u0087\u001d\u0000\u050c"+
+    "\u0121\u0001\u0000\u0000\u0000\u050d\u050e\b\"\u0000\u0000\u050e\u0123"+
+    "\u0001\u0000\u0000\u0000\u050f\u0511\u0003\u0122\u0088\u0000\u0510\u050f"+
+    "\u0001\u0000\u0000\u0000\u0511\u0512\u0001\u0000\u0000\u0000\u0512\u0510"+
+    "\u0001\u0000\u0000\u0000\u0512\u0513\u0001\u0000\u0000\u0000\u0513\u0514"+
+    "\u0001\u0000\u0000\u0000\u0514\u0515\u0003r0\u0000\u0515\u0517\u0001\u0000"+
+    "\u0000\u0000\u0516\u0510\u0001\u0000\u0000\u0000\u0516\u0517\u0001\u0000"+
+    "\u0000\u0000\u0517\u0519\u0001\u0000\u0000\u0000\u0518\u051a\u0003\u0122"+
+    "\u0088\u0000\u0519\u0518\u0001\u0000\u0000\u0000\u051a\u051b\u0001\u0000"+
+    "\u0000\u0000\u051b\u0519\u0001\u0000\u0000\u0000\u051b\u051c\u0001\u0000"+
+    "\u0000\u0000\u051c\u0125\u0001\u0000\u0000\u0000\u051d\u051e\u0003\u0124"+
+    "\u0089\u0000\u051e\u051f\u0001\u0000\u0000\u0000\u051f\u0520\u0006\u008a"+
+    "\u001e\u0000\u0520\u0127\u0001\u0000\u0000\u0000\u0521\u0522\u0003F\u001a"+
+    "\u0000\u0522\u0523\u0001\u0000\u0000\u0000\u0523\u0524\u0006\u008b\f\u0000"+
+    "\u0524\u0129\u0001\u0000\u0000\u0000\u0525\u0526\u0003H\u001b\u0000\u0526"+
+    "\u0527\u0001\u0000\u0000\u0000\u0527\u0528\u0006\u008c\f\u0000\u0528\u012b"+
+    "\u0001\u0000\u0000\u0000\u0529\u052a\u0003J\u001c\u0000\u052a\u052b\u0001"+
+    "\u0000\u0000\u0000\u052b\u052c\u0006\u008d\f\u0000\u052c\u012d\u0001\u0000"+
+    "\u0000\u0000\u052d\u052e\u0003L\u001d\u0000\u052e\u052f\u0001\u0000\u0000"+
+    "\u0000\u052f\u0530\u0006\u008e\u0011\u0000\u0530\u0531\u0006\u008e\r\u0000"+
+    "\u0531\u0532\u0006\u008e\r\u0000\u0532\u012f\u0001\u0000\u0000\u0000\u0533"+
+    "\u0534\u0003n.\u0000\u0534\u0535\u0001\u0000\u0000\u0000\u0535\u0536\u0006"+
+    "\u008f\u0015\u0000\u0536\u0131\u0001\u0000\u0000\u0000\u0537\u0538\u0003"+
+    "t1\u0000\u0538\u0539\u0001\u0000\u0000\u0000\u0539\u053a\u0006\u0090\u0014"+
+    "\u0000\u053a\u0133\u0001\u0000\u0000\u0000\u053b\u053c\u0003x3\u0000\u053c"+
+    "\u053d\u0001\u0000\u0000\u0000\u053d\u053e\u0006\u0091\u0018\u0000\u053e"+
+    "\u0135\u0001\u0000\u0000\u0000\u053f\u0540\u0003\u0120\u0087\u0000\u0540"+
+    "\u0541\u0001\u0000\u0000\u0000\u0541\u0542\u0006\u0092\u001f\u0000\u0542"+
+    "\u0137\u0001\u0000\u0000\u0000\u0543\u0544\u0003\u00fcu\u0000\u0544\u0545"+
+    "\u0001\u0000\u0000\u0000\u0545\u0546\u0006\u0093\u001b\u0000\u0546\u0139"+
+    "\u0001\u0000\u0000\u0000\u0547\u0548\u0003\u00c0W\u0000\u0548\u0549\u0001"+
+    "\u0000\u0000\u0000\u0549\u054a\u0006\u0094 \u0000\u054a\u013b\u0001\u0000"+
+    "\u0000\u0000\u054b\u054c\u0003\u0090?\u0000\u054c\u054d\u0001\u0000\u0000"+
+    "\u0000\u054d\u054e\u0006\u0095\u0019\u0000\u054e\u013d\u0001\u0000\u0000"+
+    "\u0000\u054f\u0550\u0003\u00b6R\u0000\u0550\u0551\u0001\u0000\u0000\u0000"+
+    "\u0551\u0552\u0006\u0096\u001a\u0000\u0552\u013f\u0001\u0000\u0000\u0000"+
+    "\u0553\u0554\u0003F\u001a\u0000\u0554\u0555\u0001\u0000\u0000\u0000\u0555"+
+    "\u0556\u0006\u0097\f\u0000\u0556\u0141\u0001\u0000\u0000\u0000\u0557\u0558"+
+    "\u0003H\u001b\u0000\u0558\u0559\u0001\u0000\u0000\u0000\u0559\u055a\u0006"+
+    "\u0098\f\u0000\u055a\u0143\u0001\u0000\u0000\u0000\u055b\u055c\u0003J"+
+    "\u001c\u0000\u055c\u055d\u0001\u0000\u0000\u0000\u055d\u055e\u0006\u0099"+
+    "\f\u0000\u055e\u0145\u0001\u0000\u0000\u0000\u055f\u0560\u0003L\u001d"+
+    "\u0000\u0560\u0561\u0001\u0000\u0000\u0000\u0561\u0562\u0006\u009a\u0011"+
+    "\u0000\u0562\u0563\u0006\u009a\r\u0000\u0563\u0147\u0001\u0000\u0000\u0000"+
+    "\u0564\u0565\u0003x3\u0000\u0565\u0566\u0001\u0000\u0000\u0000\u0566\u0567"+
+    "\u0006\u009b\u0018\u0000\u0567\u0149\u0001\u0000\u0000\u0000\u0568\u0569"+
+    "\u0003\u0090?\u0000\u0569\u056a\u0001\u0000\u0000\u0000\u056a\u056b\u0006"+
+    "\u009c\u0019\u0000\u056b\u014b\u0001\u0000\u0000\u0000\u056c\u056d\u0003"+
+    "\u00b6R\u0000\u056d\u056e\u0001\u0000\u0000\u0000\u056e\u056f\u0006\u009d"+
+    "\u001a\u0000\u056f\u014d\u0001\u0000\u0000\u0000\u0570\u0571\u0003\u00c0"+
+    "W\u0000\u0571\u0572\u0001\u0000\u0000\u0000\u0572\u0573\u0006\u009e \u0000"+
+    "\u0573\u014f\u0001\u0000\u0000\u0000\u0574\u0575\u0003\u00bcU\u0000\u0575"+
+    "\u0576\u0001\u0000\u0000\u0000\u0576\u0577\u0006\u009f!\u0000\u0577\u0151"+
+    "\u0001\u0000\u0000\u0000\u0578\u0579\u0003F\u001a\u0000\u0579\u057a\u0001"+
+    "\u0000\u0000\u0000\u057a\u057b\u0006\u00a0\f\u0000\u057b\u0153\u0001\u0000"+
+    "\u0000\u0000\u057c\u057d\u0003H\u001b\u0000\u057d\u057e\u0001\u0000\u0000"+
+    "\u0000\u057e\u057f\u0006\u00a1\f\u0000\u057f\u0155\u0001\u0000\u0000\u0000"+
+    "\u0580\u0581\u0003J\u001c\u0000\u0581\u0582\u0001\u0000\u0000\u0000\u0582"+
+    "\u0583\u0006\u00a2\f\u0000\u0583\u0157\u0001\u0000\u0000\u0000\u0584\u0585"+
+    "\u0003L\u001d\u0000\u0585\u0586\u0001\u0000\u0000\u0000\u0586\u0587\u0006"+
+    "\u00a3\u0011\u0000\u0587\u0588\u0006\u00a3\r\u0000\u0588\u0159\u0001\u0000"+
+    "\u0000\u0000\u0589\u058a\u0007\u0001\u0000\u0000\u058a\u058b\u0007\t\u0000"+
+    "\u0000\u058b\u058c\u0007\u000f\u0000\u0000\u058c\u058d\u0007\u0007\u0000"+
+    "\u0000\u058d\u015b\u0001\u0000\u0000\u0000\u058e\u058f\u0003F\u001a\u0000"+
+    "\u058f\u0590\u0001\u0000\u0000\u0000\u0590\u0591\u0006\u00a5\f\u0000\u0591"+
+    "\u015d\u0001\u0000\u0000\u0000\u0592\u0593\u0003H\u001b\u0000\u0593\u0594"+
+    "\u0001\u0000\u0000\u0000\u0594\u0595\u0006\u00a6\f\u0000\u0595\u015f\u0001"+
+    "\u0000\u0000\u0000\u0596\u0597\u0003J\u001c\u0000\u0597\u0598\u0001\u0000"+
+    "\u0000\u0000\u0598\u0599\u0006\u00a7\f\u0000\u0599\u0161\u0001\u0000\u0000"+
+    "\u0000\u059a\u059b\u0003\u00baT\u0000\u059b\u059c\u0001\u0000\u0000\u0000"+
+    "\u059c\u059d\u0006\u00a8\u0012\u0000\u059d\u059e\u0006\u00a8\r\u0000\u059e"+
+    "\u0163\u0001\u0000\u0000\u0000\u059f\u05a0\u0003r0\u0000\u05a0\u05a1\u0001"+
+    "\u0000\u0000\u0000\u05a1\u05a2\u0006\u00a9\u0013\u0000\u05a2\u0165\u0001"+
+    "\u0000\u0000\u0000\u05a3\u05a9\u0003X#\u0000\u05a4\u05a9\u0003N\u001e"+
+    "\u0000\u05a5\u05a9\u0003x3\u0000\u05a6\u05a9\u0003P\u001f\u0000\u05a7"+
+    "\u05a9\u0003^&\u0000\u05a8\u05a3\u0001\u0000\u0000\u0000\u05a8\u05a4\u0001"+
+    "\u0000\u0000\u0000\u05a8\u05a5\u0001\u0000\u0000\u0000\u05a8\u05a6\u0001"+
+    "\u0000\u0000\u0000\u05a8\u05a7\u0001\u0000\u0000\u0000\u05a9\u05aa\u0001"+
+    "\u0000\u0000\u0000\u05aa\u05a8\u0001\u0000\u0000\u0000\u05aa\u05ab\u0001"+
+    "\u0000\u0000\u0000\u05ab\u0167\u0001\u0000\u0000\u0000\u05ac\u05ad\u0003"+
+    "F\u001a\u0000\u05ad\u05ae\u0001\u0000\u0000\u0000\u05ae\u05af\u0006\u00ab"+
+    "\f\u0000\u05af\u0169\u0001\u0000\u0000\u0000\u05b0\u05b1\u0003H\u001b"+
+    "\u0000\u05b1\u05b2\u0001\u0000\u0000\u0000\u05b2\u05b3\u0006\u00ac\f\u0000"+
+    "\u05b3\u016b\u0001\u0000\u0000\u0000\u05b4\u05b5\u0003J\u001c\u0000\u05b5"+
+    "\u05b6\u0001\u0000\u0000\u0000\u05b6\u05b7\u0006\u00ad\f\u0000\u05b7\u016d"+
+    "\u0001\u0000\u0000\u0000\u05b8\u05b9\u0003L\u001d\u0000\u05b9\u05ba\u0001"+
+    "\u0000\u0000\u0000\u05ba\u05bb\u0006\u00ae\u0011\u0000\u05bb\u05bc\u0006"+
+    "\u00ae\r\u0000\u05bc\u016f\u0001\u0000\u0000\u0000\u05bd\u05be\u0003r"+
+    "0\u0000\u05be\u05bf\u0001\u0000\u0000\u0000\u05bf\u05c0\u0006\u00af\u0013"+
+    "\u0000\u05c0\u0171\u0001\u0000\u0000\u0000\u05c1\u05c2\u0003t1\u0000\u05c2"+
+    "\u05c3\u0001\u0000\u0000\u0000\u05c3\u05c4\u0006\u00b0\u0014\u0000\u05c4"+
+    "\u0173\u0001\u0000\u0000\u0000\u05c5\u05c6\u0003x3\u0000\u05c6\u05c7\u0001"+
+    "\u0000\u0000\u0000\u05c7\u05c8\u0006\u00b1\u0018\u0000\u05c8\u0175\u0001"+
+    "\u0000\u0000\u0000\u05c9\u05ca\u0003\u011e\u0086\u0000\u05ca\u05cb\u0001"+
+    "\u0000\u0000\u0000\u05cb\u05cc\u0006\u00b2\"\u0000\u05cc\u05cd\u0006\u00b2"+
+    "#\u0000\u05cd\u0177\u0001\u0000\u0000\u0000\u05ce\u05cf\u0003\u00e2h\u0000"+
+    "\u05cf\u05d0\u0001\u0000\u0000\u0000\u05d0\u05d1\u0006\u00b3\u0016\u0000"+
+    "\u05d1\u0179\u0001\u0000\u0000\u0000\u05d2\u05d3\u0003b(\u0000\u05d3\u05d4"+
+    "\u0001\u0000\u0000\u0000\u05d4\u05d5\u0006\u00b4\u0017\u0000\u05d5\u017b"+
+    "\u0001\u0000\u0000\u0000\u05d6\u05d7\u0003F\u001a\u0000\u05d7\u05d8\u0001"+
+    "\u0000\u0000\u0000\u05d8\u05d9\u0006\u00b5\f\u0000\u05d9\u017d\u0001\u0000"+
+    "\u0000\u0000\u05da\u05db\u0003H\u001b\u0000\u05db\u05dc\u0001\u0000\u0000"+
+    "\u0000\u05dc\u05dd\u0006\u00b6\f\u0000\u05dd\u017f\u0001\u0000\u0000\u0000"+
+    "\u05de\u05df\u0003J\u001c\u0000\u05df\u05e0\u0001\u0000\u0000\u0000\u05e0"+
+    "\u05e1\u0006\u00b7\f\u0000\u05e1\u0181\u0001\u0000\u0000\u0000\u05e2\u05e3"+
+    "\u0003L\u001d\u0000\u05e3\u05e4\u0001\u0000\u0000\u0000\u05e4\u05e5\u0006"+
+    "\u00b8\u0011\u0000\u05e5\u05e6\u0006\u00b8\r\u0000\u05e6\u05e7\u0006\u00b8"+
+    "\r\u0000\u05e7\u0183\u0001\u0000\u0000\u0000\u05e8\u05e9\u0003t1\u0000"+
+    "\u05e9\u05ea\u0001\u0000\u0000\u0000\u05ea\u05eb\u0006\u00b9\u0014\u0000"+
+    "\u05eb\u0185\u0001\u0000\u0000\u0000\u05ec\u05ed\u0003x3\u0000\u05ed\u05ee"+
+    "\u0001\u0000\u0000\u0000\u05ee\u05ef\u0006\u00ba\u0018\u0000\u05ef\u0187"+
+    "\u0001\u0000\u0000\u0000\u05f0\u05f1\u0003\u00fcu\u0000\u05f1\u05f2\u0001"+
+    "\u0000\u0000\u0000\u05f2\u05f3\u0006\u00bb\u001b\u0000\u05f3\u0189\u0001"+
+    "\u0000\u0000\u0000\u05f4\u05f5\u0003F\u001a\u0000\u05f5\u05f6\u0001\u0000"+
+    "\u0000\u0000\u05f6\u05f7\u0006\u00bc\f\u0000\u05f7\u018b\u0001\u0000\u0000"+
+    "\u0000\u05f8\u05f9\u0003H\u001b\u0000\u05f9\u05fa\u0001\u0000\u0000\u0000"+
+    "\u05fa\u05fb\u0006\u00bd\f\u0000\u05fb\u018d\u0001\u0000\u0000\u0000\u05fc"+
+    "\u05fd\u0003J\u001c\u0000\u05fd\u05fe\u0001\u0000\u0000\u0000\u05fe\u05ff"+
+    "\u0006\u00be\f\u0000\u05ff\u018f\u0001\u0000\u0000\u0000\u0600\u0601\u0003"+
+    "L\u001d\u0000\u0601\u0602\u0001\u0000\u0000\u0000\u0602\u0603\u0006\u00bf"+
+    "\u0011\u0000\u0603\u0604\u0006\u00bf\r\u0000\u0604\u0191\u0001\u0000\u0000"+
+    "\u0000\u0605\u0606\u0007#\u0000\u0000\u0606\u0607\u0007\u0007\u0000\u0000"+
+    "\u0607\u0608\u0007\u0001\u0000\u0000\u0608\u0609\u0007\t\u0000\u0000\u0609"+
+    "\u0193\u0001\u0000\u0000\u0000\u060a\u060b\u0003\u0110\u007f\u0000\u060b"+
+    "\u060c\u0001\u0000\u0000\u0000\u060c\u060d\u0006\u00c1$\u0000\u060d\u0195"+
+    "\u0001\u0000\u0000\u0000\u060e\u060f\u0003\u011e\u0086\u0000\u060f\u0610"+
+    "\u0001\u0000\u0000\u0000\u0610\u0611\u0006\u00c2\"\u0000\u0611\u0612\u0006"+
+    "\u00c2\r\u0000\u0612\u0613\u0006\u00c2\u0000\u0000\u0613\u0197\u0001\u0000"+
+    "\u0000\u0000\u0614\u0615\u0007\u0014\u0000\u0000\u0615\u0616\u0007\u0002"+
+    "\u0000\u0000\u0616\u0617\u0007\u0001\u0000\u0000\u0617\u0618\u0007\t\u0000"+
+    "\u0000\u0618\u0619\u0007\u0011\u0000\u0000\u0619\u061a\u0001\u0000\u0000"+
+    "\u0000\u061a\u061b\u0006\u00c3\r\u0000\u061b\u061c\u0006\u00c3\u0000\u0000"+
+    "\u061c\u0199\u0001\u0000\u0000\u0000\u061d\u061e\u0003\u00e2h\u0000\u061e"+
+    "\u061f\u0001\u0000\u0000\u0000\u061f\u0620\u0006\u00c4\u0016\u0000\u0620"+
+    "\u019b\u0001\u0000\u0000\u0000\u0621\u0622\u0003b(\u0000\u0622\u0623\u0001"+
+    "\u0000\u0000\u0000\u0623\u0624\u0006\u00c5\u0017\u0000\u0624\u019d\u0001"+
+    "\u0000\u0000\u0000\u0625\u0626\u0003r0\u0000\u0626\u0627\u0001\u0000\u0000"+
+    "\u0000\u0627\u0628\u0006\u00c6\u0013\u0000\u0628\u019f\u0001\u0000\u0000"+
+    "\u0000\u0629\u062a\u0003\u00bcU\u0000\u062a\u062b\u0001\u0000\u0000\u0000"+
+    "\u062b\u062c\u0006\u00c7!\u0000\u062c\u01a1\u0001\u0000\u0000\u0000\u062d"+
+    "\u062e\u0003\u00c0W\u0000\u062e\u062f\u0001\u0000\u0000\u0000\u062f\u0630"+
+    "\u0006\u00c8 \u0000\u0630\u01a3\u0001\u0000\u0000\u0000\u0631\u0632\u0003"+
+    "F\u001a\u0000\u0632\u0633\u0001\u0000\u0000\u0000\u0633\u0634\u0006\u00c9"+
+    "\f\u0000\u0634\u01a5\u0001\u0000\u0000\u0000\u0635\u0636\u0003H\u001b"+
+    "\u0000\u0636\u0637\u0001\u0000\u0000\u0000\u0637\u0638\u0006\u00ca\f\u0000"+
+    "\u0638\u01a7\u0001\u0000\u0000\u0000\u0639\u063a\u0003J\u001c\u0000\u063a"+
+    "\u063b\u0001\u0000\u0000\u0000\u063b\u063c\u0006\u00cb\f\u0000\u063c\u01a9"+
+    "\u0001\u0000\u0000\u0000\u063d\u063e\u0003L\u001d\u0000\u063e\u063f\u0001"+
+    "\u0000\u0000\u0000\u063f\u0640\u0006\u00cc\u0011\u0000\u0640\u0641\u0006"+
+    "\u00cc\r\u0000\u0641\u01ab\u0001\u0000\u0000\u0000\u0642\u0643\u0003\u00e2"+
+    "h\u0000\u0643\u0644\u0001\u0000\u0000\u0000\u0644\u0645\u0006\u00cd\u0016"+
+    "\u0000\u0645\u0646\u0006\u00cd\r\u0000\u0646\u0647\u0006\u00cd%\u0000"+
+    "\u0647\u01ad\u0001\u0000\u0000\u0000\u0648\u0649\u0003b(\u0000\u0649\u064a"+
+    "\u0001\u0000\u0000\u0000\u064a\u064b\u0006\u00ce\u0017\u0000\u064b\u064c"+
+    "\u0006\u00ce\r\u0000\u064c\u064d\u0006\u00ce%\u0000\u064d\u01af\u0001"+
+    "\u0000\u0000\u0000\u064e\u064f\u0003F\u001a\u0000\u064f\u0650\u0001\u0000"+
+    "\u0000\u0000\u0650\u0651\u0006\u00cf\f\u0000\u0651\u01b1\u0001\u0000\u0000"+
+    "\u0000\u0652\u0653\u0003H\u001b\u0000\u0653\u0654\u0001\u0000\u0000\u0000"+
+    "\u0654\u0655\u0006\u00d0\f\u0000\u0655\u01b3\u0001\u0000\u0000\u0000\u0656"+
+    "\u0657\u0003J\u001c\u0000\u0657\u0658\u0001\u0000\u0000\u0000\u0658\u0659"+
+    "\u0006\u00d1\f\u0000\u0659\u01b5\u0001\u0000\u0000\u0000\u065a\u065b\u0003"+
+    "r0\u0000\u065b\u065c\u0001\u0000\u0000\u0000\u065c\u065d\u0006\u00d2\u0013"+
+    "\u0000\u065d\u065e\u0006\u00d2\r\u0000\u065e\u065f\u0006\u00d2\u000b\u0000"+
+    "\u065f\u01b7\u0001\u0000\u0000\u0000\u0660\u0661\u0003t1\u0000\u0661\u0662"+
+    "\u0001\u0000\u0000\u0000\u0662\u0663\u0006\u00d3\u0014\u0000\u0663\u0664"+
+    "\u0006\u00d3\r\u0000\u0664\u0665\u0006\u00d3\u000b\u0000\u0665\u01b9\u0001"+
+    "\u0000\u0000\u0000\u0666\u0667\u0003F\u001a\u0000\u0667\u0668\u0001\u0000"+
+    "\u0000\u0000\u0668\u0669\u0006\u00d4\f\u0000\u0669\u01bb\u0001\u0000\u0000"+
+    "\u0000\u066a\u066b\u0003H\u001b\u0000\u066b\u066c\u0001\u0000\u0000\u0000"+
+    "\u066c\u066d\u0006\u00d5\f\u0000\u066d\u01bd\u0001\u0000\u0000\u0000\u066e"+
+    "\u066f\u0003J\u001c\u0000\u066f\u0670\u0001\u0000\u0000\u0000\u0670\u0671"+
+    "\u0006\u00d6\f\u0000\u0671\u01bf\u0001\u0000\u0000\u0000\u0672\u0673\u0003"+
+    "\u00c0W\u0000\u0673\u0674\u0001\u0000\u0000\u0000\u0674\u0675\u0006\u00d7"+
+    "\r\u0000\u0675\u0676\u0006\u00d7\u0000\u0000\u0676\u0677\u0006\u00d7 "+
+    "\u0000\u0677\u01c1\u0001\u0000\u0000\u0000\u0678\u0679\u0003\u00bcU\u0000"+
+    "\u0679\u067a\u0001\u0000\u0000\u0000\u067a\u067b\u0006\u00d8\r\u0000\u067b"+
+    "\u067c\u0006\u00d8\u0000\u0000\u067c\u067d\u0006\u00d8!\u0000\u067d\u01c3"+
+    "\u0001\u0000\u0000\u0000\u067e\u067f\u0003h+\u0000\u067f\u0680\u0001\u0000"+
+    "\u0000\u0000\u0680\u0681\u0006\u00d9\r\u0000\u0681\u0682\u0006\u00d9\u0000"+
+    "\u0000\u0682\u0683\u0006\u00d9&\u0000\u0683\u01c5\u0001\u0000\u0000\u0000"+
+    "\u0684\u0685\u0003L\u001d\u0000\u0685\u0686\u0001\u0000\u0000\u0000\u0686"+
+    "\u0687\u0006\u00da\u0011\u0000\u0687\u0688\u0006\u00da\r\u0000\u0688\u01c7"+
+    "\u0001\u0000\u0000\u0000\u0689\u068a\u0003L\u001d\u0000\u068a\u068b\u0001"+
+    "\u0000\u0000\u0000\u068b\u068c\u0006\u00db\u0011\u0000\u068c\u068d\u0006"+
+    "\u00db\r\u0000\u068d\u01c9\u0001\u0000\u0000\u0000\u068e\u068f\u0003\u011e"+
+    "\u0086\u0000\u068f\u0690\u0001\u0000\u0000\u0000\u0690\u0691\u0006\u00dc"+
+    "\"\u0000\u0691\u01cb\u0001\u0000\u0000\u0000\u0692\u0693\u0003\u0110\u007f"+
+    "\u0000\u0693\u0694\u0001\u0000\u0000\u0000\u0694\u0695\u0006\u00dd$\u0000"+
+    "\u0695\u01cd\u0001\u0000\u0000\u0000\u0696\u0697\u0003x3\u0000\u0697\u0698"+
+    "\u0001\u0000\u0000\u0000\u0698\u0699\u0006\u00de\u0018\u0000\u0699\u01cf"+
+    "\u0001\u0000\u0000\u0000\u069a\u069b\u0003t1\u0000\u069b\u069c\u0001\u0000"+
+    "\u0000\u0000\u069c\u069d\u0006\u00df\u0014\u0000\u069d\u01d1\u0001\u0000"+
+    "\u0000\u0000\u069e\u069f\u0003\u00c0W\u0000\u069f\u06a0\u0001\u0000\u0000"+
+    "\u0000\u06a0\u06a1\u0006\u00e0 \u0000\u06a1\u01d3\u0001\u0000\u0000\u0000"+
+    "\u06a2\u06a3\u0003\u00bcU\u0000\u06a3\u06a4\u0001\u0000\u0000\u0000\u06a4"+
+    "\u06a5\u0006\u00e1!\u0000\u06a5\u01d5\u0001\u0000\u0000\u0000\u06a6\u06a7"+
+    "\u0003F\u001a\u0000\u06a7\u06a8\u0001\u0000\u0000\u0000\u06a8\u06a9\u0006"+
+    "\u00e2\f\u0000\u06a9\u01d7\u0001\u0000\u0000\u0000\u06aa\u06ab\u0003H"+
+    "\u001b\u0000\u06ab\u06ac\u0001\u0000\u0000\u0000\u06ac\u06ad\u0006\u00e3"+
+    "\f\u0000\u06ad\u01d9\u0001\u0000\u0000\u0000\u06ae\u06af\u0003J\u001c"+
+    "\u0000\u06af\u06b0\u0001\u0000\u0000\u0000\u06b0\u06b1\u0006\u00e4\f\u0000"+
+    "\u06b1\u01db\u0001\u0000\u0000\u0000\u06b2\u06b3\u0003L\u001d\u0000\u06b3"+
+    "\u06b4\u0001\u0000\u0000\u0000\u06b4\u06b5\u0006\u00e5\u0011\u0000\u06b5"+
+    "\u06b6\u0006\u00e5\r\u0000\u06b6\u01dd\u0001\u0000\u0000\u0000\u06b7\u06b8"+
+    "\u0003\u00bcU\u0000\u06b8\u06b9\u0001\u0000\u0000\u0000\u06b9\u06ba\u0006"+
+    "\u00e6!\u0000\u06ba\u01df\u0001\u0000\u0000\u0000\u06bb\u06bc\u0003J\u001c"+
+    "\u0000\u06bc\u06bd\u0001\u0000\u0000\u0000\u06bd\u06be\u0006\u00e7\f\u0000"+
+    "\u06be\u01e1\u0001\u0000\u0000\u0000\u06bf\u06c0\u0003F\u001a\u0000\u06c0"+
+    "\u06c1\u0001\u0000\u0000\u0000\u06c1\u06c2\u0006\u00e8\f\u0000\u06c2\u01e3"+
+    "\u0001\u0000\u0000\u0000\u06c3\u06c4\u0003H\u001b\u0000\u06c4\u06c5\u0001"+
+    "\u0000\u0000\u0000\u06c5\u06c6\u0006\u00e9\f\u0000\u06c6\u01e5\u0001\u0000"+
+    "\u0000\u0000D\u0000\u0001\u0002\u0003\u0004\u0005\u0006\u0007\b\t\n\u000b"+
+    "\f\r\u000e\u000f\u0010\u0011\u02ce\u02d8\u02dc\u02df\u02e8\u02ea\u02f5"+
+    "\u0308\u030d\u0316\u031d\u0322\u0324\u032f\u0337\u033a\u033c\u0341\u0346"+
+    "\u034c\u0353\u0358\u035e\u0361\u0369\u036d\u03f1\u03f6\u03fd\u03ff\u040f"+
+    "\u0414\u0419\u041b\u0421\u046e\u0473\u04a2\u04a6\u04ab\u04b0\u04b5\u04b7"+
+    "\u04bb\u04bd\u0512\u0516\u051b\u05a8\u05aa\'\u0005\u0001\u0000\u0005\u0004"+
+    "\u0000\u0005\u0006\u0000\u0005\u0002\u0000\u0005\u0003\u0000\u0005\b\u0000"+
+    "\u0005\u0005\u0000\u0005\t\u0000\u0005\r\u0000\u0005\u0010\u0000\u0005"+
+    "\u000b\u0000\u0005\u000e\u0000\u0000\u0001\u0000\u0004\u0000\u0000\u0007"+
+    "\u0010\u0000\u0007I\u0000\u0005\u0000\u0000\u0007\u001e\u0000\u0007J\u0000"+
+    "\u0007\'\u0000\u0007(\u0000\u0007%\u0000\u0007T\u0000\u0007\u001f\u0000"+
+    "\u0007*\u0000\u00076\u0000\u0007H\u0000\u0007X\u0000\u0005\n\u0000\u0005"+
+    "\u0007\u0000\u0007b\u0000\u0007a\u0000\u0007L\u0000\u0007K\u0000\u0007"+
+    "`\u0000\u0005\f\u0000\u0007\\\u0000\u0005\u000f\u0000\u0007\"\u0000";
   public static final ATN _ATN =
     new ATNDeserializer().deserialize(_serializedATN.toCharArray());
   static {

Fișier diff suprimat deoarece este prea mare
+ 9 - 0
x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/parser/EsqlBaseParser.interp


Fișier diff suprimat deoarece este prea mare
+ 189 - 174
x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/parser/EsqlBaseParser.java


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

@@ -1112,6 +1112,18 @@ public class EsqlBaseParserBaseListener implements EsqlBaseParserListener {
    * <p>The default implementation does nothing.</p>
    */
   @Override public void exitChangePointCommand(EsqlBaseParser.ChangePointCommandContext ctx) { }
+  /**
+   * {@inheritDoc}
+   *
+   * <p>The default implementation does nothing.</p>
+   */
+  @Override public void enterInsistCommand(EsqlBaseParser.InsistCommandContext ctx) { }
+  /**
+   * {@inheritDoc}
+   *
+   * <p>The default implementation does nothing.</p>
+   */
+  @Override public void exitInsistCommand(EsqlBaseParser.InsistCommandContext ctx) { }
 
   /**
    * {@inheritDoc}

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

@@ -657,4 +657,11 @@ public class EsqlBaseParserBaseVisitor<T> extends AbstractParseTreeVisitor<T> im
    * {@link #visitChildren} on {@code ctx}.</p>
    */
   @Override public T visitChangePointCommand(EsqlBaseParser.ChangePointCommandContext ctx) { return visitChildren(ctx); }
+  /**
+   * {@inheritDoc}
+   *
+   * <p>The default implementation returns the result of calling
+   * {@link #visitChildren} on {@code ctx}.</p>
+   */
+  @Override public T visitInsistCommand(EsqlBaseParser.InsistCommandContext ctx) { return visitChildren(ctx); }
 }

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

@@ -991,4 +991,14 @@ public interface EsqlBaseParserListener extends ParseTreeListener {
    * @param ctx the parse tree
    */
   void exitChangePointCommand(EsqlBaseParser.ChangePointCommandContext ctx);
+  /**
+   * Enter a parse tree produced by {@link EsqlBaseParser#insistCommand}.
+   * @param ctx the parse tree
+   */
+  void enterInsistCommand(EsqlBaseParser.InsistCommandContext ctx);
+  /**
+   * Exit a parse tree produced by {@link EsqlBaseParser#insistCommand}.
+   * @param ctx the parse tree
+   */
+  void exitInsistCommand(EsqlBaseParser.InsistCommandContext ctx);
 }

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

@@ -597,4 +597,10 @@ public interface EsqlBaseParserVisitor<T> extends ParseTreeVisitor<T> {
    * @return the visitor result
    */
   T visitChangePointCommand(EsqlBaseParser.ChangePointCommandContext ctx);
+  /**
+   * Visit a parse tree produced by {@link EsqlBaseParser#insistCommand}.
+   * @param ctx the parse tree
+   * @return the visitor result
+   */
+  T visitInsistCommand(EsqlBaseParser.InsistCommandContext ctx);
 }

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

@@ -50,6 +50,7 @@ import org.elasticsearch.xpack.esql.plan.logical.Explain;
 import org.elasticsearch.xpack.esql.plan.logical.Filter;
 import org.elasticsearch.xpack.esql.plan.logical.Grok;
 import org.elasticsearch.xpack.esql.plan.logical.InlineStats;
+import org.elasticsearch.xpack.esql.plan.logical.Insist;
 import org.elasticsearch.xpack.esql.plan.logical.Keep;
 import org.elasticsearch.xpack.esql.plan.logical.Limit;
 import org.elasticsearch.xpack.esql.plan.logical.LogicalPlan;
@@ -287,6 +288,22 @@ public class LogicalPlanBuilder extends ExpressionBuilder {
         );
     }
 
+    @Override
+    public PlanFactory visitInsistCommand(EsqlBaseParser.InsistCommandContext ctx) {
+        var source = source(ctx);
+        List<NamedExpression> fields = visitQualifiedNamePatterns(ctx.qualifiedNamePatterns(), ne -> {
+            if (ne instanceof UnresolvedStar || ne instanceof UnresolvedNamePattern) {
+                Source neSource = ne.source();
+                throw new ParsingException(neSource, "INSIST doesn't support wildcards, found [{}]", neSource.text());
+            }
+        });
+        return input -> new Insist(
+            source,
+            input,
+            fields.stream().map(ne -> (Attribute) new UnresolvedAttribute(ne.source(), ne.name())).toList()
+        );
+    }
+
     @Override
     public PlanFactory visitStatsCommand(EsqlBaseParser.StatsCommandContext ctx) {
         final Stats stats = stats(source(ctx), ctx.grouping, ctx.stats);

+ 1 - 1
x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/plan/PlanWritables.java

@@ -70,8 +70,8 @@ public class PlanWritables {
             Eval.ENTRY,
             Filter.ENTRY,
             Grok.ENTRY,
-            InlineStats.ENTRY,
             InlineJoin.ENTRY,
+            InlineStats.ENTRY,
             Join.ENTRY,
             LocalRelation.ENTRY,
             Limit.ENTRY,

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

@@ -226,4 +226,8 @@ public class EsRelation extends LeafPlan {
             throw new IllegalStateException("not ready to support index mode [" + indexMode + "]");
         }
     }
+
+    public EsRelation withAttributes(List<Attribute> newAttributes) {
+        return new EsRelation(source(), indexPattern, indexMode, indexNameWithModes, newAttributes);
+    }
 }

+ 91 - 0
x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/plan/logical/Insist.java

@@ -0,0 +1,91 @@
+/*
+ * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
+ * or more contributor license agreements. Licensed under the Elastic License
+ * 2.0; you may not use this file except in compliance with the Elastic License
+ * 2.0.
+ */
+package org.elasticsearch.xpack.esql.plan.logical;
+
+import org.elasticsearch.common.io.stream.StreamOutput;
+import org.elasticsearch.core.Nullable;
+import org.elasticsearch.xpack.esql.core.expression.Attribute;
+import org.elasticsearch.xpack.esql.core.tree.NodeInfo;
+import org.elasticsearch.xpack.esql.core.tree.Source;
+import org.elasticsearch.xpack.esql.expression.NamedExpressions;
+import org.elasticsearch.xpack.esql.expression.function.UnsupportedAttribute;
+
+import java.io.IOException;
+import java.util.List;
+import java.util.Objects;
+
+public class Insist extends UnaryPlan implements SurrogateLogicalPlan {
+    private final List<? extends Attribute> insistedAttributes;
+    private @Nullable List<Attribute> lazyOutput = null;
+
+    public Insist(Source source, LogicalPlan child, List<? extends Attribute> insistedAttributes) {
+        super(source, child);
+        this.insistedAttributes = insistedAttributes;
+    }
+
+    @Override
+    public List<Attribute> output() {
+        if (lazyOutput == null) {
+            lazyOutput = NamedExpressions.mergeOutputAttributes(insistedAttributes, child().output());
+        }
+        return lazyOutput;
+    }
+
+    public List<? extends Attribute> insistedAttributes() {
+        return insistedAttributes;
+    }
+
+    @Override
+    public Insist replaceChild(LogicalPlan newChild) {
+        return new Insist(source(), newChild, insistedAttributes);
+    }
+
+    @Override
+    public boolean expressionsResolved() {
+        // Like EsqlProject, we allow unsupported attributes to flow through the engine.
+        return insistedAttributes().stream().allMatch(a -> a.resolved() || a instanceof UnsupportedAttribute);
+    }
+
+    @Override
+    protected NodeInfo<? extends LogicalPlan> info() {
+        return NodeInfo.create(
+            this,
+            (source, insistedAttributes1, child) -> new Insist(source, child, insistedAttributes1),
+            insistedAttributes,
+            child()
+        );
+    }
+
+    @Override
+    public void writeTo(StreamOutput out) throws IOException {
+        throw new UnsupportedOperationException("doesn't escape the coordinator node");
+    }
+
+    @Override
+    public String getWriteableName() {
+        throw new UnsupportedOperationException("doesn't escape the coordinator node");
+    }
+
+    @Override
+    public int hashCode() {
+        return Objects.hash(super.hashCode(), Objects.hashCode(insistedAttributes));
+    }
+
+    @Override
+    public boolean equals(Object obj) {
+        return super.equals(obj) && Objects.equals(((Insist) obj).insistedAttributes, insistedAttributes);
+    }
+
+    @Override
+    public LogicalPlan surrogate() {
+        return new Project(source(), child(), output());
+    }
+
+    public Insist withAttributes(List<Attribute> attributes) {
+        return new Insist(source(), child(), attributes);
+    }
+}

+ 3 - 2
x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/plan/physical/EnrichExec.java

@@ -121,8 +121,9 @@ public class EnrichExec extends UnaryExec implements EstimatesRowSize {
             out.writeMap(concreteIndices(), StreamOutput::writeString, StreamOutput::writeString);
         } else {
             if (concreteIndices().keySet().equals(Set.of(RemoteClusterAware.LOCAL_CLUSTER_GROUP_KEY))) {
-                String concreteIndex = concreteIndices().get(RemoteClusterAware.LOCAL_CLUSTER_GROUP_KEY);
-                new EsIndex(concreteIndex, Map.of(), Map.of(concreteIndex, IndexMode.STANDARD)).writeTo(out);
+                String enrichIndex = concreteIndices().get(RemoteClusterAware.LOCAL_CLUSTER_GROUP_KEY);
+                EsIndex esIndex = new EsIndex(enrichIndex, Map.of(), Map.of(enrichIndex, IndexMode.STANDARD));
+                esIndex.writeTo(out);
             } else {
                 throw new IllegalStateException("expected a single concrete enrich index; got " + concreteIndices());
             }

+ 45 - 21
x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/planner/EsPhysicalOperationProviders.java

@@ -26,11 +26,13 @@ import org.elasticsearch.compute.lucene.ValuesSourceReaderOperator;
 import org.elasticsearch.compute.operator.Operator;
 import org.elasticsearch.compute.operator.OrdinalsGroupingOperator;
 import org.elasticsearch.compute.operator.SourceOperator;
+import org.elasticsearch.core.Nullable;
 import org.elasticsearch.index.IndexMode;
 import org.elasticsearch.index.IndexSettings;
 import org.elasticsearch.index.analysis.AnalysisRegistry;
 import org.elasticsearch.index.mapper.BlockLoader;
 import org.elasticsearch.index.mapper.FieldNamesFieldMapper;
+import org.elasticsearch.index.mapper.KeywordFieldMapper;
 import org.elasticsearch.index.mapper.MappedFieldType;
 import org.elasticsearch.index.mapper.NestedLookup;
 import org.elasticsearch.index.mapper.SourceLoader;
@@ -49,7 +51,9 @@ import org.elasticsearch.xpack.esql.core.expression.FieldAttribute;
 import org.elasticsearch.xpack.esql.core.expression.FoldContext;
 import org.elasticsearch.xpack.esql.core.expression.MetadataAttribute;
 import org.elasticsearch.xpack.esql.core.type.DataType;
+import org.elasticsearch.xpack.esql.core.type.KeywordEsField;
 import org.elasticsearch.xpack.esql.core.type.MultiTypeEsField;
+import org.elasticsearch.xpack.esql.core.type.PotentiallyUnmappedKeywordEsField;
 import org.elasticsearch.xpack.esql.expression.function.scalar.convert.AbstractConvertFunction;
 import org.elasticsearch.xpack.esql.plan.physical.AggregateExec;
 import org.elasticsearch.xpack.esql.plan.physical.EsQueryExec;
@@ -62,6 +66,7 @@ import org.elasticsearch.xpack.esql.planner.LocalExecutionPlanner.PhysicalOperat
 import java.io.IOException;
 import java.util.ArrayList;
 import java.util.List;
+import java.util.Map;
 import java.util.Optional;
 import java.util.Set;
 import java.util.function.Function;
@@ -110,28 +115,29 @@ public class EsPhysicalOperationProviders extends AbstractPhysicalOperationProvi
         int docChannel = source.layout.get(sourceAttr.id()).channel();
         for (Attribute attr : fieldExtractExec.attributesToExtract()) {
             layout.append(attr);
-            var unionTypes = findUnionTypes(attr);
             DataType dataType = attr.dataType();
             MappedFieldType.FieldExtractPreference fieldExtractPreference = fieldExtractExec.fieldExtractPreference(attr);
             ElementType elementType = PlannerUtils.toElementType(dataType, fieldExtractPreference);
-            // Do not use the field attribute name, this can deviate from the field name for union types.
-            String fieldName = attr instanceof FieldAttribute fa ? fa.fieldName() : attr.name();
-            boolean isUnsupported = dataType == DataType.UNSUPPORTED;
-            IntFunction<BlockLoader> loader = s -> getBlockLoaderFor(s, fieldName, isUnsupported, fieldExtractPreference, unionTypes);
-            fields.add(new ValuesSourceReaderOperator.FieldInfo(fieldName, elementType, loader));
+            IntFunction<BlockLoader> loader = s -> getBlockLoaderFor(s, attr, fieldExtractPreference);
+            fields.add(new ValuesSourceReaderOperator.FieldInfo(getFieldName(attr), elementType, loader));
         }
         return source.with(new ValuesSourceReaderOperator.Factory(fields, readers, docChannel), layout.build());
     }
 
-    private BlockLoader getBlockLoaderFor(
-        int shardId,
-        String fieldName,
-        boolean isUnsupported,
-        MappedFieldType.FieldExtractPreference fieldExtractPreference,
-        MultiTypeEsField unionTypes
-    ) {
+    private static String getFieldName(Attribute attr) {
+        // Do not use the field attribute name, this can deviate from the field name for union types.
+        return attr instanceof FieldAttribute fa ? fa.fieldName() : attr.name();
+    }
+
+    private BlockLoader getBlockLoaderFor(int shardId, Attribute attr, MappedFieldType.FieldExtractPreference fieldExtractPreference) {
         DefaultShardContext shardContext = (DefaultShardContext) shardContexts.get(shardId);
-        BlockLoader blockLoader = shardContext.blockLoader(fieldName, isUnsupported, fieldExtractPreference);
+        if (attr instanceof FieldAttribute fa && fa.field() instanceof PotentiallyUnmappedKeywordEsField kf) {
+            shardContext = new DefaultShardContextForUnmappedField(shardContext, kf);
+        }
+
+        boolean isUnsupported = attr.dataType() == DataType.UNSUPPORTED;
+        BlockLoader blockLoader = shardContext.blockLoader(getFieldName(attr), isUnsupported, fieldExtractPreference);
+        MultiTypeEsField unionTypes = findUnionTypes(attr);
         if (unionTypes != null) {
             String indexName = shardContext.ctx.index().getName();
             Expression conversion = unionTypes.getConversionExpressionForIndex(indexName);
@@ -142,7 +148,25 @@ public class EsPhysicalOperationProviders extends AbstractPhysicalOperationProvi
         return blockLoader;
     }
 
-    private MultiTypeEsField findUnionTypes(Attribute attr) {
+    /** A hack to pretend an unmapped field still exists. */
+    private static class DefaultShardContextForUnmappedField extends DefaultShardContext {
+        private final KeywordEsField unmappedEsField;
+
+        DefaultShardContextForUnmappedField(DefaultShardContext ctx, PotentiallyUnmappedKeywordEsField unmappedEsField) {
+            super(ctx.index, ctx.ctx, ctx.aliasFilter);
+            this.unmappedEsField = unmappedEsField;
+        }
+
+        @Override
+        protected @Nullable MappedFieldType fieldType(String name) {
+            var superResult = super.fieldType(name);
+            return superResult == null && name.equals(unmappedEsField.getName())
+                ? new KeywordFieldMapper.KeywordFieldType(name, false /* isIndexed */, false /* hasDocValues */, Map.of() /* meta */)
+                : superResult;
+        }
+    }
+
+    private static @Nullable MultiTypeEsField findUnionTypes(Attribute attr) {
         if (attr instanceof FieldAttribute fa && fa.field() instanceof MultiTypeEsField multiTypeEsField) {
             return multiTypeEsField;
         }
@@ -237,12 +261,8 @@ public class EsPhysicalOperationProviders extends AbstractPhysicalOperationProvi
             .toList();
         // The grouping-by values are ready, let's group on them directly.
         // Costin: why are they ready and not already exposed in the layout?
-        boolean isUnsupported = attrSource.dataType() == DataType.UNSUPPORTED;
-        var unionTypes = findUnionTypes(attrSource);
-        // Do not use the field attribute name, this can deviate from the field name for union types.
-        String fieldName = attrSource instanceof FieldAttribute fa ? fa.fieldName() : attrSource.name();
         return new OrdinalsGroupingOperator.OrdinalsGroupingOperatorFactory(
-            shardIdx -> getBlockLoaderFor(shardIdx, fieldName, isUnsupported, NONE, unionTypes),
+            shardIdx -> getBlockLoaderFor(shardIdx, attrSource, NONE),
             vsShardContexts,
             groupElementType,
             docChannel,
@@ -315,7 +335,7 @@ public class EsPhysicalOperationProviders extends AbstractPhysicalOperationProvi
             if (asUnsupportedSource) {
                 return BlockLoader.CONSTANT_NULLS;
             }
-            MappedFieldType fieldType = ctx.getFieldType(name);
+            MappedFieldType fieldType = fieldType(name);
             if (fieldType == null) {
                 // the field does not exist in this context
                 return BlockLoader.CONSTANT_NULLS;
@@ -363,6 +383,10 @@ public class EsPhysicalOperationProviders extends AbstractPhysicalOperationProvi
 
             return loader;
         }
+
+        protected @Nullable MappedFieldType fieldType(String name) {
+            return ctx.getFieldType(name);
+        }
     }
 
     private static class TypeConvertingBlockLoader implements BlockLoader {

+ 17 - 11
x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/session/IndexResolver.java

@@ -92,7 +92,8 @@ public class IndexResolver {
     }
 
     // public for testing only
-    public IndexResolution mergedMappings(String indexPattern, FieldCapabilitiesResponse fieldCapsResponse) {
+    public static IndexResolution mergedMappings(String indexPattern, FieldCapabilitiesResponse fieldCapsResponse) {
+        var numberOfIndices = fieldCapsResponse.getIndexResponses().size();
         assert ThreadPool.assertCurrentThreadPool(ThreadPool.Names.SEARCH_COORDINATION); // too expensive to run this on a transport worker
         if (fieldCapsResponse.getIndexResponses().isEmpty()) {
             return IndexResolution.notFound(indexPattern);
@@ -105,6 +106,7 @@ public class IndexResolver {
         String[] names = fieldsCaps.keySet().toArray(new String[0]);
         Arrays.sort(names);
         Map<String, EsField> rootFields = new HashMap<>();
+        Set<String> partiallyUnmappedFields = new HashSet<>();
         for (String name : names) {
             Map<String, EsField> fields = rootFields;
             String fullName = name;
@@ -129,8 +131,9 @@ public class IndexResolver {
             }
             // TODO we're careful to make isAlias match IndexResolver - but do we use it?
 
+            List<IndexFieldCapabilities> fcs = fieldsCaps.get(fullName);
             EsField field = firstUnsupportedParent == null
-                ? createField(fieldCapsResponse, name, fullName, fieldsCaps.get(fullName), isAlias)
+                ? createField(fieldCapsResponse, name, fullName, fcs, isAlias)
                 : new UnsupportedEsField(
                     fullName,
                     firstUnsupportedParent.getOriginalType(),
@@ -138,6 +141,11 @@ public class IndexResolver {
                     new HashMap<>()
                 );
             fields.put(name, field);
+
+            var isPartiallyUnmapped = fcs.size() < numberOfIndices;
+            if (isPartiallyUnmapped) {
+                partiallyUnmappedFields.add(fullName);
+            }
         }
 
         Map<String, FieldCapabilitiesFailure> unavailableRemotes = EsqlCCSUtils.determineUnavailableRemoteClusters(
@@ -153,11 +161,9 @@ public class IndexResolver {
         for (FieldCapabilitiesIndexResponse ir : fieldCapsResponse.getIndexResponses()) {
             allEmpty &= ir.get().isEmpty();
         }
-        if (allEmpty) {
-            // If all the mappings are empty we return an empty set of resolved indices to line up with QL
-            return IndexResolution.valid(new EsIndex(indexPattern, rootFields, Map.of()), concreteIndices.keySet(), unavailableRemotes);
-        }
-        return IndexResolution.valid(new EsIndex(indexPattern, rootFields, concreteIndices), concreteIndices.keySet(), unavailableRemotes);
+        // If all the mappings are empty we return an empty set of resolved indices to line up with QL
+        var index = new EsIndex(indexPattern, rootFields, allEmpty ? Map.of() : concreteIndices, partiallyUnmappedFields);
+        return IndexResolution.valid(index, concreteIndices.keySet(), unavailableRemotes);
     }
 
     private static Map<String, List<IndexFieldCapabilities>> collectFieldCaps(FieldCapabilitiesResponse fieldCapsResponse) {
@@ -179,7 +185,7 @@ public class IndexResolver {
         return fieldsCaps;
     }
 
-    private EsField createField(
+    private static EsField createField(
         FieldCapabilitiesResponse fieldCapsResponse,
         String name,
         String fullName,
@@ -227,12 +233,12 @@ public class IndexResolver {
         return new EsField(name, type, new HashMap<>(), aggregatable, isAlias);
     }
 
-    private UnsupportedEsField unsupported(String name, IndexFieldCapabilities fc) {
+    private static UnsupportedEsField unsupported(String name, IndexFieldCapabilities fc) {
         String originalType = fc.metricType() == TimeSeriesParams.MetricType.COUNTER ? "counter" : fc.type();
         return new UnsupportedEsField(name, originalType);
     }
 
-    private EsField conflictingTypes(String name, String fullName, FieldCapabilitiesResponse fieldCapsResponse) {
+    private static EsField conflictingTypes(String name, String fullName, FieldCapabilitiesResponse fieldCapsResponse) {
         Map<String, Set<String>> typesToIndices = new TreeMap<>();
         for (FieldCapabilitiesIndexResponse ir : fieldCapsResponse.getIndexResponses()) {
             IndexFieldCapabilities fc = ir.get().get(fullName);
@@ -247,7 +253,7 @@ public class IndexResolver {
         return new InvalidMappedField(name, typesToIndices);
     }
 
-    private EsField conflictingMetricTypes(String name, String fullName, FieldCapabilitiesResponse fieldCapsResponse) {
+    private static EsField conflictingMetricTypes(String name, String fullName, FieldCapabilitiesResponse fieldCapsResponse) {
         TreeSet<String> indices = new TreeSet<>();
         for (FieldCapabilitiesIndexResponse ir : fieldCapsResponse.getIndexResponses()) {
             IndexFieldCapabilities fc = ir.get().get(fullName);

+ 21 - 4
x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/CsvTests.java

@@ -279,6 +279,10 @@ public class CsvTests extends ESTestCase {
                 "CSV tests cannot correctly handle the field caps change",
                 testCase.requiredCapabilities.contains(EsqlCapabilities.Cap.SEMANTIC_TEXT_FIELD_CAPS.capabilityName())
             );
+            assumeFalse(
+                "CSV tests cannot currently handle the _source field mapping directives",
+                testCase.requiredCapabilities.contains(EsqlCapabilities.Cap.SOURCE_FIELD_MAPPING.capabilityName())
+            );
             if (Build.current().isSnapshot()) {
                 assertThat(
                     "Capability is not included in the enabled list capabilities on a snapshot build. Spelling mistake?",
@@ -355,7 +359,10 @@ public class CsvTests extends ESTestCase {
             .stream()
             .map(ds -> new MappingPerIndex(ds.indexName(), createMappingForIndex(ds)))
             .toList();
-        return IndexResolution.valid(new EsIndex(datasets.indexPattern(), mergeMappings(mappings), indexModes));
+        var mergedMappings = mergeMappings(mappings);
+        return IndexResolution.valid(
+            new EsIndex(datasets.indexPattern(), mergedMappings.mapping, indexModes, mergedMappings.partiallyUnmappedFields)
+        );
     }
 
     private static Map<String, EsField> createMappingForIndex(CsvTestsDataLoader.TestDataset dataset) {
@@ -376,7 +383,10 @@ public class CsvTests extends ESTestCase {
 
     record MappingPerIndex(String index, Map<String, EsField> mapping) {}
 
-    private static Map<String, EsField> mergeMappings(List<MappingPerIndex> mappingsPerIndex) {
+    record MergedResult(Map<String, EsField> mapping, Set<String> partiallyUnmappedFields) {}
+
+    private static MergedResult mergeMappings(List<MappingPerIndex> mappingsPerIndex) {
+        int numberOfIndices = mappingsPerIndex.size();
         Map<String, Map<String, EsField>> columnNamesToFieldByIndices = new HashMap<>();
         for (var mappingPerIndex : mappingsPerIndex) {
             for (var entry : mappingPerIndex.mapping().entrySet()) {
@@ -386,9 +396,15 @@ public class CsvTests extends ESTestCase {
             }
         }
 
-        return columnNamesToFieldByIndices.entrySet()
+        var partiallyUnmappedFields = columnNamesToFieldByIndices.entrySet()
+            .stream()
+            .filter(e -> e.getValue().size() < numberOfIndices)
+            .map(Map.Entry::getKey)
+            .collect(Collectors.toSet());
+        var mappings = columnNamesToFieldByIndices.entrySet()
             .stream()
             .collect(Collectors.toMap(Map.Entry::getKey, e -> mergeFields(e.getKey(), e.getValue())));
+        return new MergedResult(mappings, partiallyUnmappedFields);
     }
 
     private static EsField mergeFields(String index, Map<String, EsField> columnNameToField) {
@@ -494,7 +510,8 @@ public class CsvTests extends ESTestCase {
         var indexPages = new ArrayList<TestPhysicalOperationProviders.IndexPage>();
         for (CsvTestsDataLoader.TestDataset dataset : datasets.datasets()) {
             var testData = loadPageFromCsv(CsvTests.class.getResource("/data/" + dataset.dataFileName()), dataset.typeMapping());
-            indexPages.add(new TestPhysicalOperationProviders.IndexPage(dataset.indexName(), testData.v1(), testData.v2()));
+            Set<String> mappedFields = loadMapping(dataset.mappingFileName()).keySet();
+            indexPages.add(new TestPhysicalOperationProviders.IndexPage(dataset.indexName(), testData.v1(), testData.v2(), mappedFields));
         }
         return TestPhysicalOperationProviders.create(foldCtx, indexPages);
     }

+ 178 - 1
x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/analysis/AnalyzerTests.java

@@ -10,6 +10,7 @@ package org.elasticsearch.xpack.esql.analysis;
 import org.elasticsearch.Build;
 import org.elasticsearch.action.fieldcaps.FieldCapabilitiesIndexResponse;
 import org.elasticsearch.action.fieldcaps.FieldCapabilitiesResponse;
+import org.elasticsearch.action.fieldcaps.IndexFieldCapabilities;
 import org.elasticsearch.common.settings.Settings;
 import org.elasticsearch.index.IndexMode;
 import org.elasticsearch.index.analysis.IndexAnalyzers;
@@ -29,9 +30,12 @@ import org.elasticsearch.xpack.esql.core.expression.MapExpression;
 import org.elasticsearch.xpack.esql.core.expression.NamedExpression;
 import org.elasticsearch.xpack.esql.core.expression.ReferenceAttribute;
 import org.elasticsearch.xpack.esql.core.expression.UnresolvedAttribute;
+import org.elasticsearch.xpack.esql.core.tree.Source;
 import org.elasticsearch.xpack.esql.core.type.DataType;
+import org.elasticsearch.xpack.esql.core.type.PotentiallyUnmappedKeywordEsField;
 import org.elasticsearch.xpack.esql.enrich.ResolvedEnrichPolicy;
 import org.elasticsearch.xpack.esql.expression.function.EsqlFunctionRegistry;
+import org.elasticsearch.xpack.esql.expression.function.UnsupportedAttribute;
 import org.elasticsearch.xpack.esql.expression.function.aggregate.Count;
 import org.elasticsearch.xpack.esql.expression.function.aggregate.Max;
 import org.elasticsearch.xpack.esql.expression.function.aggregate.Min;
@@ -47,6 +51,7 @@ import org.elasticsearch.xpack.esql.plan.logical.Enrich;
 import org.elasticsearch.xpack.esql.plan.logical.EsRelation;
 import org.elasticsearch.xpack.esql.plan.logical.Eval;
 import org.elasticsearch.xpack.esql.plan.logical.Filter;
+import org.elasticsearch.xpack.esql.plan.logical.Insist;
 import org.elasticsearch.xpack.esql.plan.logical.Limit;
 import org.elasticsearch.xpack.esql.plan.logical.LogicalPlan;
 import org.elasticsearch.xpack.esql.plan.logical.Lookup;
@@ -85,10 +90,12 @@ import static org.elasticsearch.xpack.esql.analysis.AnalyzerTestUtils.tsdbIndexR
 import static org.elasticsearch.xpack.esql.core.tree.Source.EMPTY;
 import static org.hamcrest.Matchers.contains;
 import static org.hamcrest.Matchers.containsString;
+import static org.hamcrest.Matchers.empty;
 import static org.hamcrest.Matchers.equalTo;
 import static org.hamcrest.Matchers.hasItem;
 import static org.hamcrest.Matchers.hasSize;
 import static org.hamcrest.Matchers.instanceOf;
+import static org.hamcrest.Matchers.is;
 import static org.hamcrest.Matchers.matchesRegex;
 import static org.hamcrest.Matchers.not;
 import static org.hamcrest.Matchers.startsWith;
@@ -2587,6 +2594,176 @@ public class AnalyzerTests extends ESTestCase {
         assertEquals(DataType.DOUBLE, ee.dataType());
     }
 
+    public void testResolveInsist_fieldExists_insistedOutputContainsNoUnmappedFields() {
+        assumeTrue("Requires UNMAPPED FIELDS", EsqlCapabilities.Cap.UNMAPPED_FIELDS.isEnabled());
+
+        LogicalPlan plan = analyze("FROM test | INSIST_🐔 emp_no");
+
+        Attribute last = plan.output().getLast();
+        assertThat(last.name(), is("emp_no"));
+        assertThat(last.dataType(), is(DataType.INTEGER));
+        assertThat(
+            plan.output()
+                .stream()
+                .filter(a -> a instanceof FieldAttribute fa && fa.field() instanceof PotentiallyUnmappedKeywordEsField)
+                .toList(),
+            is(empty())
+        );
+    }
+
+    public void testInsist_afterRowThrowsException() {
+        assumeTrue("Requires UNMAPPED FIELDS", EsqlCapabilities.Cap.UNMAPPED_FIELDS.isEnabled());
+
+        VerificationException e = expectThrows(
+            VerificationException.class,
+            () -> analyze("ROW x = 1 | INSIST_🐔 x", analyzer(TEST_VERIFIER))
+        );
+        assertThat(e.getMessage(), containsString("[insist] can only be used after [from] or [insist] commands, but was [ROW x = 1]"));
+    }
+
+    public void testResolveInsist_fieldDoesNotExist_createsUnmappedField() {
+        assumeTrue("Requires UNMAPPED FIELDS", EsqlCapabilities.Cap.UNMAPPED_FIELDS.isEnabled());
+
+        LogicalPlan plan = analyze("FROM test | INSIST_🐔 foo");
+
+        var limit = as(plan, Limit.class);
+        var insist = as(limit.child(), Insist.class);
+        assertThat(insist.output(), hasSize(analyze("FROM test").output().size() + 1));
+        var expectedAttribute = new FieldAttribute(Source.EMPTY, "foo", new PotentiallyUnmappedKeywordEsField("foo"));
+        assertThat(insist.insistedAttributes(), is(List.of(expectedAttribute)));
+        assertThat(insist.output().getLast(), is(expectedAttribute));
+    }
+
+    public void testResolveInsist_multiIndexFieldPartiallyMappedWithSingleKeywordType_createsUnmappedField() {
+        assumeTrue("Requires UNMAPPED FIELDS", EsqlCapabilities.Cap.UNMAPPED_FIELDS.isEnabled());
+
+        IndexResolution resolution = IndexResolver.mergedMappings(
+            "foo, bar",
+            new FieldCapabilitiesResponse(
+                List.of(
+                    fieldCapabilitiesIndexResponse("foo", messageResponseMap("keyword")),
+                    fieldCapabilitiesIndexResponse("bar", Map.of())
+                ),
+                List.of()
+            )
+        );
+
+        String query = "FROM foo, bar | INSIST_🐔 message";
+        var plan = analyze(query, analyzer(resolution, TEST_VERIFIER, configuration(query)));
+        var limit = as(plan, Limit.class);
+        var insist = as(limit.child(), Insist.class);
+        var attribute = (FieldAttribute) EsqlTestUtils.singleValue(insist.output());
+        assertThat(attribute.name(), is("message"));
+        assertThat(attribute.field(), is(new PotentiallyUnmappedKeywordEsField("message")));
+    }
+
+    public void testResolveInsist_multiIndexFieldExistsWithSingleTypeButIsNotKeywordAndMissingCast_createsAnInvalidMappedField() {
+        assumeTrue("Requires UNMAPPED FIELDS", EsqlCapabilities.Cap.UNMAPPED_FIELDS.isEnabled());
+
+        IndexResolution resolution = IndexResolver.mergedMappings(
+            "foo, bar",
+            new FieldCapabilitiesResponse(
+                List.of(fieldCapabilitiesIndexResponse("foo", messageResponseMap("long")), fieldCapabilitiesIndexResponse("bar", Map.of())),
+                List.of()
+            )
+        );
+        var plan = analyze("FROM foo, bar | INSIST_🐔 message", analyzer(resolution, TEST_VERIFIER));
+        var limit = as(plan, Limit.class);
+        var insist = as(limit.child(), Insist.class);
+        var attribute = (UnsupportedAttribute) EsqlTestUtils.singleValue(insist.output());
+        assertThat(attribute.name(), is("message"));
+
+        String expected = "Cannot use field [message] due to ambiguities being mapped as [2] incompatible types: "
+            + "[keyword] enforced by INSIST command, and [long] in index mappings";
+        assertThat(attribute.unresolvedMessage(), is(expected));
+    }
+
+    public void testResolveInsist_multiIndexFieldPartiallyExistsWithMultiTypesNoKeyword_createsAnInvalidMappedField() {
+        assumeTrue("Requires UNMAPPED FIELDS", EsqlCapabilities.Cap.UNMAPPED_FIELDS.isEnabled());
+
+        IndexResolution resolution = IndexResolver.mergedMappings(
+            "foo, bar",
+            new FieldCapabilitiesResponse(
+                List.of(
+                    fieldCapabilitiesIndexResponse("foo", messageResponseMap("long")),
+                    fieldCapabilitiesIndexResponse("bar", messageResponseMap("date")),
+                    fieldCapabilitiesIndexResponse("bazz", Map.of())
+                ),
+                List.of()
+            )
+        );
+        var plan = analyze("FROM foo, bar | INSIST_🐔 message", analyzer(resolution, TEST_VERIFIER));
+        var limit = as(plan, Limit.class);
+        var insist = as(limit.child(), Insist.class);
+        var attr = (UnsupportedAttribute) EsqlTestUtils.singleValue(insist.output());
+
+        String expected = "Cannot use field [message] due to ambiguities being mapped as [3] incompatible types: "
+            + "[keyword] enforced by INSIST command, [datetime] in [bar], [long] in [foo]";
+        assertThat(attr.unresolvedMessage(), is(expected));
+    }
+
+    public void testResolveInsist_multiIndexFieldPartiallyExistsWithMultiTypesWithKeyword_createsAnInvalidMappedField() {
+        assumeTrue("Requires UNMAPPED FIELDS", EsqlCapabilities.Cap.UNMAPPED_FIELDS.isEnabled());
+
+        IndexResolution resolution = IndexResolver.mergedMappings(
+            "foo, bar",
+            new FieldCapabilitiesResponse(
+                List.of(
+                    fieldCapabilitiesIndexResponse("foo", messageResponseMap("long")),
+                    fieldCapabilitiesIndexResponse("bar", messageResponseMap("date")),
+                    fieldCapabilitiesIndexResponse("bazz", messageResponseMap("keyword")),
+                    fieldCapabilitiesIndexResponse("qux", Map.of())
+                ),
+                List.of()
+            )
+        );
+        var plan = analyze("FROM foo, bar | INSIST_🐔 message", analyzer(resolution, TEST_VERIFIER));
+        var limit = as(plan, Limit.class);
+        var insist = as(limit.child(), Insist.class);
+        var attr = (UnsupportedAttribute) EsqlTestUtils.singleValue(insist.output());
+
+        String expected = "Cannot use field [message] due to ambiguities being mapped as [3] incompatible types: "
+            + "[datetime] in [bar], [keyword] enforced by INSIST command and in [bazz], [long] in [foo]";
+        assertThat(attr.unresolvedMessage(), is(expected));
+    }
+
+    public void testResolveInsist_multiIndexFieldPartiallyExistsWithMultiTypesWithCast_castsAreNotSupported() {
+        assumeTrue("Requires UNMAPPED FIELDS", EsqlCapabilities.Cap.UNMAPPED_FIELDS.isEnabled());
+
+        IndexResolution resolution = IndexResolver.mergedMappings(
+            "foo, bar",
+            new FieldCapabilitiesResponse(
+                List.of(
+                    fieldCapabilitiesIndexResponse("foo", messageResponseMap("long")),
+                    fieldCapabilitiesIndexResponse("bar", messageResponseMap("date")),
+                    fieldCapabilitiesIndexResponse("bazz", Map.of())
+                ),
+                List.of()
+            )
+        );
+        VerificationException e = expectThrows(
+            VerificationException.class,
+            () -> analyze("FROM multi_index | INSIST_🐔 message | EVAL message = message :: keyword", analyzer(resolution, TEST_VERIFIER))
+        );
+        // This isn't the most informative error, but it'll do for now.
+        assertThat(
+            e.getMessage(),
+            containsString("EVAL does not support type [unsupported] as the return data type of expression [message]")
+        );
+    }
+
+    // TODO There's too much boilerplate involved here! We need a better way of creating FieldCapabilitiesResponses from a mapping or index.
+    private static FieldCapabilitiesIndexResponse fieldCapabilitiesIndexResponse(
+        String indexName,
+        Map<String, IndexFieldCapabilities> fields
+    ) {
+        return new FieldCapabilitiesIndexResponse(indexName, indexName, fields, false, IndexMode.STANDARD);
+    }
+
+    private static Map<String, IndexFieldCapabilities> messageResponseMap(String date) {
+        return Map.of("message", new IndexFieldCapabilities("message", date, false, true, true, false, null, null));
+    }
+
     private void verifyUnsupported(String query, String errorMessage) {
         verifyUnsupported(query, errorMessage, "mapping-multi-field-variation.json");
     }
@@ -2638,7 +2815,7 @@ public class AnalyzerTests extends ESTestCase {
             new FieldCapabilitiesIndexResponse("idx", "idx", Map.of(), true, IndexMode.STANDARD)
         );
         FieldCapabilitiesResponse caps = new FieldCapabilitiesResponse(idxResponses, List.of());
-        IndexResolution resolution = new IndexResolver(null).mergedMappings("test*", caps);
+        IndexResolution resolution = IndexResolver.mergedMappings("test*", caps);
         var analyzer = analyzer(resolution, TEST_VERIFIER, configuration(query));
         return analyze(query, analyzer);
     }

+ 9 - 0
x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/analysis/VerifierTests.java

@@ -2155,6 +2155,15 @@ public class VerifierTests extends ESTestCase {
         );
     }
 
+    public void testInsistNotOnTopOfFrom() {
+        assumeTrue("requires snapshot builds", Build.current().isSnapshot());
+
+        assertThat(
+            error("FROM test | EVAL foo = 42 | INSIST_🐔 bar"),
+            containsString("1:29: [insist] can only be used after [from] or [insist] commands, but was [EVAL foo = 42]")
+        );
+    }
+
     private void query(String query) {
         query(query, defaultAnalyzer);
     }

+ 68 - 6
x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/optimizer/LogicalPlanOptimizerTests.java

@@ -45,6 +45,7 @@ import org.elasticsearch.xpack.esql.core.expression.predicate.operator.compariso
 import org.elasticsearch.xpack.esql.core.tree.Source;
 import org.elasticsearch.xpack.esql.core.type.DataType;
 import org.elasticsearch.xpack.esql.core.type.EsField;
+import org.elasticsearch.xpack.esql.core.type.PotentiallyUnmappedKeywordEsField;
 import org.elasticsearch.xpack.esql.core.util.Holder;
 import org.elasticsearch.xpack.esql.core.util.StringUtils;
 import org.elasticsearch.xpack.esql.expression.Order;
@@ -135,6 +136,7 @@ import java.util.Arrays;
 import java.util.List;
 import java.util.Locale;
 import java.util.Map;
+import java.util.Set;
 import java.util.function.BiFunction;
 import java.util.function.Function;
 
@@ -157,6 +159,7 @@ import static org.elasticsearch.xpack.esql.EsqlTestUtils.getFieldAttribute;
 import static org.elasticsearch.xpack.esql.EsqlTestUtils.loadMapping;
 import static org.elasticsearch.xpack.esql.EsqlTestUtils.localSource;
 import static org.elasticsearch.xpack.esql.EsqlTestUtils.referenceAttribute;
+import static org.elasticsearch.xpack.esql.EsqlTestUtils.singleValue;
 import static org.elasticsearch.xpack.esql.EsqlTestUtils.unboundLogicalOptimizerContext;
 import static org.elasticsearch.xpack.esql.EsqlTestUtils.withDefaultLimitWarning;
 import static org.elasticsearch.xpack.esql.analysis.Analyzer.NO_FIELDS;
@@ -192,23 +195,24 @@ import static org.hamcrest.Matchers.startsWith;
 
 //@TestLogging(value = "org.elasticsearch.xpack.esql:TRACE", reason = "debug")
 public class LogicalPlanOptimizerTests extends ESTestCase {
-
     private static EsqlParser parser;
-    private static Analyzer analyzer;
     private static LogicalOptimizerContext logicalOptimizerCtx;
     private static LogicalPlanOptimizer logicalOptimizer;
+
     private static Map<String, EsField> mapping;
+    private static Analyzer analyzer;
     private static Map<String, EsField> mappingAirports;
-    private static Map<String, EsField> mappingTypes;
     private static Analyzer analyzerAirports;
+    private static Map<String, EsField> mappingTypes;
     private static Analyzer analyzerTypes;
     private static Map<String, EsField> mappingExtra;
     private static Analyzer analyzerExtra;
-    private static EnrichResolution enrichResolution;
-    private static final LiteralsOnTheRight LITERALS_ON_THE_RIGHT = new LiteralsOnTheRight();
-
     private static Map<String, EsField> metricMapping;
     private static Analyzer metricsAnalyzer;
+    private static Analyzer multiIndexAnalyzer;
+
+    private static EnrichResolution enrichResolution;
+    private static final LiteralsOnTheRight LITERALS_ON_THE_RIGHT = new LiteralsOnTheRight();
 
     private static class SubstitutionOnlyOptimizer extends LogicalPlanOptimizer {
         static SubstitutionOnlyOptimizer INSTANCE = new SubstitutionOnlyOptimizer(unboundLogicalOptimizerContext());
@@ -279,6 +283,21 @@ public class LogicalPlanOptimizerTests extends ESTestCase {
             new AnalyzerContext(EsqlTestUtils.TEST_CFG, new EsqlFunctionRegistry(), metricsIndex, enrichResolution),
             TEST_VERIFIER
         );
+
+        var multiIndexMapping = loadMapping("mapping-basic.json");
+        multiIndexMapping.put("partial_type_keyword", new EsField("partial_type_keyword", KEYWORD, emptyMap(), true));
+        var multiIndex = IndexResolution.valid(
+            new EsIndex(
+                "multi_index",
+                multiIndexMapping,
+                Map.of("test1", IndexMode.STANDARD, "test2", IndexMode.STANDARD),
+                Set.of("partial_type_keyword")
+            )
+        );
+        multiIndexAnalyzer = new Analyzer(
+            new AnalyzerContext(EsqlTestUtils.TEST_CFG, new EsqlFunctionRegistry(), multiIndex, enrichResolution),
+            TEST_VERIFIER
+        );
     }
 
     public void testEmptyProjections() {
@@ -2900,6 +2919,45 @@ public class LogicalPlanOptimizerTests extends ESTestCase {
         );
     }
 
+    public void testInsist_fieldDoesNotExist_createsUnmappedFieldInRelation() {
+        assumeTrue("Requires UNMAPPED FIELDS", EsqlCapabilities.Cap.UNMAPPED_FIELDS.isEnabled());
+
+        LogicalPlan plan = optimizedPlan("FROM test | INSIST_🐔 foo");
+
+        var project = as(plan, Project.class);
+        var limit = as(project.child(), Limit.class);
+        var relation = as(limit.child(), EsRelation.class);
+        assertPartialTypeKeyword(relation, "foo");
+    }
+
+    public void testInsist_multiIndexFieldPartiallyExistsAndIsKeyword_castsAreNotSupported() {
+        assumeTrue("Requires UNMAPPED FIELDS", EsqlCapabilities.Cap.UNMAPPED_FIELDS.isEnabled());
+
+        var plan = planMultiIndex("FROM multi_index | INSIST_🐔 partial_type_keyword");
+        var project = as(plan, Project.class);
+        var limit = as(project.child(), Limit.class);
+        var relation = as(limit.child(), EsRelation.class);
+
+        assertPartialTypeKeyword(relation, "partial_type_keyword");
+    }
+
+    public void testInsist_multipleInsistClauses_insistsAreFolded() {
+        assumeTrue("Requires UNMAPPED FIELDS", EsqlCapabilities.Cap.UNMAPPED_FIELDS.isEnabled());
+
+        var plan = planMultiIndex("FROM multi_index | INSIST_🐔 partial_type_keyword | INSIST_🐔 foo");
+        var project = as(plan, Project.class);
+        var limit = as(project.child(), Limit.class);
+        var relation = as(limit.child(), EsRelation.class);
+
+        assertPartialTypeKeyword(relation, "partial_type_keyword");
+        assertPartialTypeKeyword(relation, "foo");
+    }
+
+    private static void assertPartialTypeKeyword(EsRelation relation, String name) {
+        var attribute = (FieldAttribute) singleValue(relation.output().stream().filter(attr -> attr.name().equals(name)).toList());
+        assertThat(attribute.field(), instanceOf(PotentiallyUnmappedKeywordEsField.class));
+    }
+
     public void testSimplifyLikeNoWildcard() {
         LogicalPlan plan = optimizedPlan("""
             from test
@@ -5888,6 +5946,10 @@ public class LogicalPlanOptimizerTests extends ESTestCase {
         return logicalOptimizer.optimize(analyzerTypes.analyze(parser.createStatement(query)));
     }
 
+    private LogicalPlan planMultiIndex(String query) {
+        return logicalOptimizer.optimize(multiIndexAnalyzer.analyze(parser.createStatement(query)));
+    }
+
     private EsqlBinaryComparison extractPlannedBinaryComparison(String expression) {
         LogicalPlan plan = planTypes("FROM types | WHERE " + expression);
 

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

@@ -2982,4 +2982,10 @@ public class StatementParserTests extends AbstractStatementParserTests {
             );
         }
     }
+
+    public void testInvalidInsistAsterisk() {
+        assumeTrue("requires snapshot build", Build.current().isSnapshot());
+        expectError("FROM text | EVAL x = 4 | INSIST_🐔 *", "INSIST doesn't support wildcards, found [*]");
+        expectError("FROM text | EVAL x = 4 | INSIST_🐔 foo*", "INSIST doesn't support wildcards, found [foo*]");
+    }
 }

+ 62 - 30
x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/planner/TestPhysicalOperationProviders.java

@@ -51,6 +51,7 @@ import org.elasticsearch.xpack.esql.core.expression.FoldContext;
 import org.elasticsearch.xpack.esql.core.expression.MetadataAttribute;
 import org.elasticsearch.xpack.esql.core.type.DataType;
 import org.elasticsearch.xpack.esql.core.type.MultiTypeEsField;
+import org.elasticsearch.xpack.esql.core.type.PotentiallyUnmappedKeywordEsField;
 import org.elasticsearch.xpack.esql.core.util.SpatialCoordinateTypes;
 import org.elasticsearch.xpack.esql.expression.function.UnsupportedAttribute;
 import org.elasticsearch.xpack.esql.expression.function.scalar.convert.AbstractConvertFunction;
@@ -64,8 +65,9 @@ import org.elasticsearch.xpack.ml.MachineLearning;
 import java.io.IOException;
 import java.util.ArrayList;
 import java.util.List;
-import java.util.OptionalInt;
+import java.util.Optional;
 import java.util.Random;
+import java.util.Set;
 import java.util.function.BiFunction;
 import java.util.function.Consumer;
 import java.util.function.Function;
@@ -91,9 +93,10 @@ public class TestPhysicalOperationProviders extends AbstractPhysicalOperationPro
         return new TestPhysicalOperationProviders(foldContext, indexPages, createAnalysisRegistry());
     }
 
-    public record IndexPage(String index, Page page, List<String> columnNames) {
-        OptionalInt columnIndex(String columnName) {
-            return IntStream.range(0, columnNames.size()).filter(i -> columnNames.get(i).equals(columnName)).findFirst();
+    public record IndexPage(String index, Page page, List<String> columnNames, Set<String> mappedFields) {
+        Optional<Integer> columnIndex(String columnName) {
+            var result = IntStream.range(0, columnNames.size()).filter(i -> columnNames.get(i).equals(columnName)).findFirst();
+            return result.isPresent() ? Optional.of(result.getAsInt()) : Optional.empty();
         }
     }
 
@@ -264,43 +267,72 @@ public class TestPhysicalOperationProviders extends AbstractPhysicalOperationPro
 
     private Block getBlock(DocBlock docBlock, Attribute attribute, FieldExtractPreference extractPreference) {
         if (attribute instanceof UnsupportedAttribute) {
-            return docBlock.blockFactory().newConstantNullBlock(docBlock.getPositionCount());
-        }
-        return extractBlockForColumn(
-            docBlock,
-            attribute.dataType(),
-            extractPreference,
-            attribute instanceof FieldAttribute fa && fa.field() instanceof MultiTypeEsField multiTypeEsField
-                ? (indexDoc, blockCopier) -> getBlockForMultiType(indexDoc, multiTypeEsField, blockCopier)
-                : (indexDoc, blockCopier) -> extractBlockForSingleDoc(indexDoc, attribute.name(), blockCopier)
-        );
+            return getNullsBlock(docBlock);
+        }
+        BiFunction<DocBlock, TestBlockCopier, Block> blockExtraction = getBlockExtraction(attribute);
+        return extractBlockForColumn(docBlock, attribute.dataType(), extractPreference, blockExtraction);
+    }
+
+    private BiFunction<DocBlock, TestBlockCopier, Block> getBlockExtraction(Attribute attribute) {
+        if (attribute instanceof FieldAttribute fa) {
+            if (fa.field() instanceof MultiTypeEsField m) {
+                return (doc, copier) -> getBlockForMultiType(doc, m, copier);
+
+            }
+            if (fa.field() instanceof PotentiallyUnmappedKeywordEsField k) {
+                return (doc, copier) -> switch (extractBlockForSingleDoc(doc, k.getName(), copier)) {
+                    case BlockResultMissing unused -> getNullsBlock(doc);
+                    case BlockResultSuccess success -> success.block;
+                };
+            }
+        }
+        return (indexDoc, blockCopier) -> switch (extractBlockForSingleDoc(indexDoc, attribute.name(), blockCopier)) {
+            case BlockResultMissing missing -> throw new EsqlIllegalArgumentException(
+                "Cannot find column named [{}] in {}",
+                missing.columnName,
+                missing.columnNames
+            );
+            case BlockResultSuccess success -> success.block;
+        };
     }
 
     private Block getBlockForMultiType(DocBlock indexDoc, MultiTypeEsField multiTypeEsField, TestBlockCopier blockCopier) {
-        var indexId = indexDoc.asVector().shards().getInt(0);
-        var indexPage = indexPages.get(indexId);
-        var conversion = (AbstractConvertFunction) multiTypeEsField.getConversionExpressionForIndex(indexPage.index);
-        Supplier<Block> nulls = () -> indexDoc.blockFactory().newConstantNullBlock(indexDoc.getPositionCount());
+        var conversion = (AbstractConvertFunction) multiTypeEsField.getConversionExpressionForIndex(getIndexPage(indexDoc).index);
         if (conversion == null) {
-            return nulls.get();
+            return getNullsBlock(indexDoc);
         }
-        var field = (FieldAttribute) conversion.field();
-        return indexPage.columnIndex(field.fieldName()).isEmpty()
-            ? nulls.get()
-            : TypeConverter.fromConvertFunction(conversion).convert(extractBlockForSingleDoc(indexDoc, field.fieldName(), blockCopier));
+        return switch (extractBlockForSingleDoc(indexDoc, ((FieldAttribute) conversion.field()).fieldName(), blockCopier)) {
+            case BlockResultMissing unused -> getNullsBlock(indexDoc);
+            case BlockResultSuccess success -> TypeConverter.fromConvertFunction(conversion).convert(success.block);
+        };
+    }
+
+    private IndexPage getIndexPage(DocBlock indexDoc) {
+        return indexPages.get(indexDoc.asVector().shards().getInt(0));
+    }
+
+    private static Block getNullsBlock(DocBlock indexDoc) {
+        return indexDoc.blockFactory().newConstantNullBlock(indexDoc.getPositionCount());
     }
 
-    private Block extractBlockForSingleDoc(DocBlock docBlock, String columnName, TestBlockCopier blockCopier) {
+    private sealed interface BlockResult {}
+
+    private record BlockResultSuccess(Block block) implements BlockResult {}
+
+    private record BlockResultMissing(String columnName, List<String> columnNames) implements BlockResult {}
+
+    private BlockResult extractBlockForSingleDoc(DocBlock docBlock, String columnName, TestBlockCopier blockCopier) {
         var indexId = docBlock.asVector().shards().getInt(0);
         var indexPage = indexPages.get(indexId);
         if (MetadataAttribute.INDEX.equals(columnName)) {
-            return docBlock.blockFactory()
-                .newConstantBytesRefBlockWith(new BytesRef(indexPage.index), blockCopier.docIndices.getPositionCount());
+            return new BlockResultSuccess(
+                docBlock.blockFactory()
+                    .newConstantBytesRefBlockWith(new BytesRef(indexPage.index), blockCopier.docIndices.getPositionCount())
+            );
         }
-        int columnIndex = indexPage.columnIndex(columnName)
-            .orElseThrow(() -> new EsqlIllegalArgumentException("Cannot find column named [{}] in {}", columnName, indexPage.columnNames));
-        var originalData = indexPage.page.getBlock(columnIndex);
-        return blockCopier.copyBlock(originalData);
+        return indexPage.columnIndex(columnName)
+            .<BlockResult>map(columnIndex -> new BlockResultSuccess(blockCopier.copyBlock(indexPage.page.getBlock(columnIndex))))
+            .orElseGet(() -> new BlockResultMissing(columnName, indexPage.columnNames()));
     }
 
     private static void foreachIndexDoc(DocBlock docBlock, Consumer<DocBlock> indexDocConsumer) {

+ 78 - 0
x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/session/IndexResolverFieldNamesTests.java

@@ -1575,6 +1575,84 @@ public class IndexResolverFieldNamesTests extends ESTestCase {
         );
     }
 
+    public void testInsist_fieldIsMappedToNonKeywordSingleIndex() {
+        assumeTrue("UNMAPPED_FIELDS available as snapshot only", EsqlCapabilities.Cap.UNMAPPED_FIELDS.isEnabled());
+        assertFieldNames(
+            "FROM partial_mapping_sample_data | INSIST_🐔 client_ip | KEEP @timestamp, client_ip",
+            Set.of("@timestamp", "@timestamp.*", "client_ip", "client_ip.*"),
+            Set.of()
+        );
+    }
+
+    public void testInsist_fieldIsMappedToKeywordSingleIndex() {
+        assumeTrue("UNMAPPED_FIELDS available as snapshot only", EsqlCapabilities.Cap.UNMAPPED_FIELDS.isEnabled());
+        assertFieldNames(
+            "FROM partial_mapping_sample_data | INSIST_🐔 message | KEEP @timestamp, message",
+            Set.of("@timestamp", "@timestamp.*", "message", "message.*"),
+            Set.of()
+        );
+    }
+
+    public void testInsist_fieldDoesNotExistSingleIndex() {
+        assumeTrue("UNMAPPED_FIELDS available as snapshot only", EsqlCapabilities.Cap.UNMAPPED_FIELDS.isEnabled());
+        assertFieldNames(
+            "FROM partial_mapping_sample_data | INSIST_🐔 foo | KEEP @timestamp, foo",
+            Set.of("@timestamp", "@timestamp.*", "foo", "foo.*"),
+            Set.of()
+        );
+    }
+
+    public void testInsist_fieldIsUnmappedSingleIndex() {
+        assumeTrue("UNMAPPED_FIELDS available as snapshot only", EsqlCapabilities.Cap.UNMAPPED_FIELDS.isEnabled());
+        assertFieldNames(
+            "FROM partial_mapping_sample_data | INSIST_🐔 unmapped_message | KEEP @timestamp, unmapped_message",
+            Set.of("@timestamp", "@timestamp.*", "unmapped_message", "unmapped_message.*"),
+            Set.of()
+        );
+    }
+
+    public void testInsist_multiFieldTestSingleIndex() {
+        assumeTrue("UNMAPPED_FIELDS available as snapshot only", EsqlCapabilities.Cap.UNMAPPED_FIELDS.isEnabled());
+        assertFieldNames(
+            "FROM partial_mapping_sample_data | INSIST_🐔 message, unmapped_message, client_ip, foo | KEEP @timestamp, unmapped_message",
+            Set.of(
+                "@timestamp",
+                "@timestamp.*",
+                "message",
+                "message.*",
+                "unmapped_message",
+                "unmapped_message.*",
+                "client_ip",
+                "client_ip.*",
+                "foo",
+                "foo.*"
+            ),
+            Set.of()
+        );
+    }
+
+    public void testInsist_fieldIsMappedToDifferentTypesMultiIndex() {
+        assumeTrue("UNMAPPED_FIELDS available as snapshot only", EsqlCapabilities.Cap.UNMAPPED_FIELDS.isEnabled());
+        assertFieldNames(
+            "FROM sample_data_ts_long, sample_data METADATA _index | INSIST_🐔 @timestamp | KEEP _index, @timestamp",
+            Set.of("@timestamp", "@timestamp.*"),
+            Set.of()
+        );
+    }
+
+    public void testInsist_multiFieldMappedMultiIndex() {
+        assumeTrue("UNMAPPED_FIELDS available as snapshot only", EsqlCapabilities.Cap.UNMAPPED_FIELDS.isEnabled());
+        assertFieldNames(
+            """
+                FROM sample_data_ts_long, sample_data METADATA _index
+                | INSIST_🐔 @timestamp, unmapped_message
+                | INSIST_🐔 message, foo
+                | KEEP _index, @timestamp, message, foo""",
+            Set.of("@timestamp", "@timestamp.*", "message", "message.*", "unmapped_message", "unmapped_message.*", "foo", "foo.*"),
+            Set.of()
+        );
+    }
+
     private Set<String> fieldNames(String query, Set<String> enrichPolicyMatchFields) {
         var preAnalysisResult = new EsqlSession.PreAnalysisResult(null);
         return EsqlSession.fieldNames(parser.createStatement(query), enrichPolicyMatchFields, preAnalysisResult).fieldNames();

+ 1 - 1
x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/type/EsqlDataTypeRegistryTests.java

@@ -54,7 +54,7 @@ public class EsqlDataTypeRegistryTests extends ESTestCase {
 
         FieldCapabilitiesResponse caps = new FieldCapabilitiesResponse(idxResponses, List.of());
         // IndexResolver uses EsqlDataTypeRegistry directly
-        IndexResolution resolution = new IndexResolver(null).mergedMappings("idx-*", caps);
+        IndexResolution resolution = IndexResolver.mergedMappings("idx-*", caps);
         EsField f = resolution.get().mapping().get(field);
         assertThat(f.getDataType(), equalTo(expected));
     }

Unele fișiere nu au fost afișate deoarece prea multe fișiere au fost modificate în acest diff